skip to Main Content

I’ve been looking around the web and especially here on stackoverflow for THE answer to this question.

I only use directories with an index.php file in it. Includables and private stuff are outside the public_html (cpanel) directory.

By using directories, anchor links and queries will look like:

http://domain.com/sub/#anchor or http://domain.com/sub/?query

And I just don’t like it. People keep telling me that this is irrelevant for SEO but I don’t think that this is the case. Firstly because I want consistency, secondly, trailing slashes creates duplicates thus I need 301 redirects! Consistency and duplicates are indeed a SEO problem!

This is just an example of how my website is structured:

/
·--index.php
|
·--/about-us/
|  |
|  ·--index.php
·--/contact-us/
   |
   ·--index.php

Users will never know that about-us is a directory, and they won’t type the last trailing slash anyway. This creates duplicates and HTTP errors.

On the web I’ve found only non-working examples, and as for what I’ve understood, I have to internally add the trailing slash and index.php. This helps to avoid security problems and makes all the thing work!

Here, and here I asked something similar. But in that case I had to create the /public directory. Now I am managing to change host, and I will be able to use the non public directory to store php files.

Since I don’t need the /public directory anymore, I copied part of that code and pasted it on a new .htaccess.

Here is the .htaccess

# Options
Options +FollowSymLinks -MultiViews -Indexes
DirectoryIndex index.php index.html
DirectorySlash off

# Enable Rewrite Engine
RewriteEngine on
RewriteBase /

# www to non-www
RewriteCond %{HTTP_HOST} ^www.(.+)$ [NC]
RewriteCond %1##%{HTTPS}s ^(.+)##(?:on(s)|)
RewriteRule ^ http%2://%1%{REQUEST_URI} [L,R=301,NE]

# remove trailing slash from all URLs
RewriteCond %{THE_REQUEST} s(.+?)/+[?s]
RewriteRule ^(.+)/$ /$1 [R=301,L,NE]

# To externally redirect /dir/file.php to /dir/file
RewriteCond %{THE_REQUEST} s/+(.+?).php[s?] [NC]
RewriteRule ^ /%1 [R=301,NE,L]

# internally add trailing / to directories
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule !/$ %{REQUEST_URI}/ [L]

# To internally forward /dir/file to /dir/file.php
RewriteCond %{DOCUMENT_ROOT}/$1.php -f [NC]
RewriteRule ^(.+?)/?$ $1.php [L]

<FilesMatch ^.>
  order allow,deny
  deny from all
</FilesMatch>

<Files *.inc>
  order allow,deny
  deny from all
</Files>

The code seems to work well in subdirectories but not in root. I guess that this is because the code above was tailored to work on the /public subdirectory.

How can I make it work on root too?

To sum-up, I need 301 redirects, otherwise there will be duplicates of content!!

http://www.domain.com/ R–> http://domain.com/

http://domain.com/ R–> http://domain.com

http://domain.com/sub/ R–> http://domain.com/sub

http://domain.com/sub/index.php R–> http://domain.com/sub

http://domain.com/sub/index.php#anchor R–> http://domain.com/sub#anchor

http://domain.com/sub/#anchor R–> http://domain.com/sub#anchor

2

Answers


  1. You can use these rules to meet all the requirements including removal of index.php. Do remember that anchors cannot be preserved on server side as server won’t even get #anchor in the HTTP request i.e. only http://domain.com/sub/ will be received in Apache logs.

    # Options
    Options +FollowSymLinks -MultiViews -Indexes
    DirectoryIndex index.php index.html
    DirectorySlash off
    
    # Enable Rewrite Engine
    RewriteEngine on
    RewriteBase /
    
    # www to non-www
    RewriteCond %{HTTP_HOST} ^www.(.+)$ [NC]
    RewriteCond %1##%{HTTPS}s ^(.+)##(?:on(s)|)
    RewriteRule ^ http%2://%1%{REQUEST_URI} [L,R=301,NE]
    
    # remove index.php
    RewriteCond %{THE_REQUEST} s/*(/.*)?/index.php[?s] [NC]
    RewriteRule ^ %1 [L,R=301,NE]
    
    # remove trailing slash from all URLs
    RewriteCond %{THE_REQUEST} s(.+?)/+[?s]
    RewriteRule ^(.+)/$ /$1 [R=301,L,NE]
    
    # To externally redirect /dir/file.php to /dir/file
    RewriteCond %{THE_REQUEST} s/+(.+?).php[s?] [NC]
    RewriteRule ^ /%1 [R=301,NE,L]
    
    # internally add trailing / to directories
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteRule [^/]$ %{REQUEST_URI}/ [L]
    
    # To internally forward /dir/file to /dir/file.php
    RewriteCond %{DOCUMENT_ROOT}/$1.php -f [NC]
    RewriteRule ^(.+?)/?$ $1.php [L]
    
    <FilesMatch ^.>
      order allow,deny
      deny from all
    </FilesMatch>
    
    <Files *.inc>
      order allow,deny
      deny from all
    </Files>
    
    Login or Signup to reply.
  2. Don’t trim trailing slashes, you’re fighting the normal directory structure of URLs. There is no such URL as http://domain.com even if your browser hides it, the slash is still being sent in the request and will be added back to a URL copied from an address bar.

    Doing a redirect for a single domain is good. Automatic 301 redirects (the kind that Apache does) from http://domain.com/foo to http://domain.com/foo/ are good for SEO. How are index.php strings in your URLs in the first place? There’s no need for them to be there; make sure all your own links are free of them. The easiest way to ensure only unique pages are indexed is with <link rel=canonical href="…">.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search