Welcome to WebmasterWorld Guest from

Forum Moderators: Ocean10000 & incrediBILL & phranque

Message Too Old, No Replies

htaccess rewrite - the trailing slash

4:17 am on Feb 5, 2010 (gmt 0)

New User

5+ Year Member

joined:Jan 29, 2010
posts: 4
votes: 0

Hello I’m using htaccess to rewrite my domain’s URL. However i’m completely stuck!

Htaccess calls the php page with the following URL:

The following input urls will resolve:

However the following URL gives a 404:

I plan to have php detect and add missing trailing slashes when the page data exists in the database, redirecting with a 301. If no page data exists in the database, php will give a 404 header.

I can append the URL with the missing trailing slash within htaccess , however the page then goes through a two-step process where there’s a 301 redirect to the error page and then a 404 header is given:

http://www.example.com/yyy [301 -> ]

http://www.example.com/yyy/ [404 -> ]


If I have php detect and add missing trailing slashes then I can cut out the 301 redirect.

Any ideas on how I fix the issue with the url ‘http://www.example.com/yyy'? I assume i'm overlooking something simple in my htaccess file but just can't see it!

Any better way to do this?

I would be grateful if anyone can help!

The htaccess file is follows:
RewriteRule ^(sitemap\.xml|robots\.txt|favicon\.ico) - [L]

#block list
IndexIgnore *

#rewrite url
RewriteEngine on
Options +FollowSymlinks
RewriteBase /
RewriteRule ^([^/]*)/$ /?levelone=$1&leveltwo=$2 [L]
RewriteRule ^([^/]*)/([^/]*)/$ /?levelone=$1&leveltwo=$2 [L]
RewriteRule ^([^/]*)/([^/]*)$ /?levelone=$1&leveltwo=$2 [L]

RewriteEngine on
RewriteCond %{HTTP_HOST} ^example.com
RewriteRule (.*) http://www.example.com/$1/ [R=301,L]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.php\ HTTP/
RewriteRule ^index\.php$ http://www.example.com/ [R=301,L]

RewriteEngine on
RewriteCond %{HTTP_REFERER} .
RewriteCond %{HTTP_REFERER} !^http://([^.]+\.)?example\. [NC]
RewriteCond %{HTTP_REFERER} !google\. [NC]
RewriteCond %{HTTP_REFERER} !search\?q=cache [NC]
RewriteCond %{HTTP_REFERER} !msn\. [NC]
RewriteCond %{HTTP_REFERER} !yahoo\. [NC]
RewriteCond %{REQUEST_URI} !^/images/warning\.gif$
RewriteRule \.(gif|jpg|png)$ /images/warning.gif [NC,L]
5:42 am on Feb 5, 2010 (gmt 0)

Senior Member

WebmasterWorld Senior Member jdmorgan is a WebmasterWorld Top Contributor of All Time 10+ Year Member

joined:Mar 31, 2002
votes: 0

Your rules are in the wrong order.

Put all external redirects first, ordered from most-specific to least-specific. Most-specific rules affect one or only a few URLs, as exemplified by your "index.php" canonicalization rule. Least-specific is the catch-all non-canonical domain redirect.

BTW, that rule could do with some improvement. If you don't use any subdomains other than www, then the following is a much more robust solution:

RewriteCond %{HTTP_HOST} !^(www\.example\.com)?$
RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,L]

It also avoids adding a trailing slash to all requests -- a possible contributor to your declared problem.

Follow your external redirects with all of your internal rewrites, again from most-specific to least-specific.

The variable $2 in your first internal rewrite rule above is undefined; Omit the "&leveltwo=$2" query part, or give "leveltwo=" a hard-coded value.

You can replace internal rewrites two and three with a single rule by making the trailing slash optional:
RewriteRule ^([^/]*)/([^/]*)/?$ /?levelone=$1&leveltwo=$2 [L]

Only one "RewriteEngine on" is needed. It must precede any other mod_rewrite directives.

One comment on your narrative. mod_rewrite will be far easier to understand if you keep in mind that it either performs a URL-to-URL translation (external redirect), or it does a URL-to-filepath translation (internal rewrite.) Therefore, the statement, "Htaccess calls the php page with the following URL: ..." is incorrect, as .htaccess merely translates a request for the URL www.example.com/yyy/zzz/ into a request for the file at "/index.php" with a query string of "levelone=yyy&leveltwo=zzz".
It's much easier to understand what's going on in mod_rewrite if you keep URLs and filepaths as two completely separate and distinct concepts.

One final comment: Adding slashes to 'page' URLs is generally a mistake, although doing so may be required by some CMS packages. URLs with trailing slashes are generally assumed to refer to directory indexes or to index pages in directories (my statement above about URLs versus filepaths notwithstanding). If it is an option and your site is not already well-linked, well-indexed, and well-trafficked, drop the trailing slashes from 'page' URLs instead of adding them.

6:24 pm on Feb 5, 2010 (gmt 0)

New User

5+ Year Member

joined:Jan 29, 2010
votes: 0

Brilliant! Thank you so much.