Search code examples
apache.htaccesshttp-redirectmod-rewritetrailing-slash

.htaccess: Redirect Trailing Slashes


I have a rewrite rule below in my .htaccess file in the root directory:

RewriteEngine On

# Exclude .css / .js / ...
RewriteCond ${REQUEST_URI} ^.+$
RewriteCond %{REQUEST_FILENAME} \.(gif|jpe?g|png|js|css|swf|php|ico|txt|pdf|xml)$ [OR]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -l
RewriteRule ^ - [L]

# Rewrite Rule
RewriteRule ^([^/]*)/([^/]*)$ /index.php?category=$1&product=$2

So the URL http://example.com/data1/data2 give me category=data1 and product=data2.

The problem is that the below URLs are not working:

http://example.com/data1          # Not Working (Page Not Found)
http://example.com/data1/data2/   # Not Working (Page Not Found)

But these URLs are working:

http://example.com/data1/         # Works -> category=data1
http://example.com/data1/data2    # Works -> category=data1 & product=data2

How can I redirect the first two URLs to the second one?

OR/AND

Do something that all URLs are redirect to the non-trailing slash one. So the URLs below:

http://example.com/data1/
http://example.com/data1/data2/

are redirect to these:

http://example.com/data1
http://example.com/data1/data2

Solution

  • To avoid trailing slashes alltogether, do a redirect

    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.+)/$ /$1 [R,L]
    

    To match a URL with just one element, you might use a second rule

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.+)$ /index.php?category=$1&product= [L]
    

    or

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.+)$ /index.php?category=$1 [L]
    

    Putting all together gives

    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.+)/$ /$1 [R,L]
    
    RewriteRule ^(.+?)/(.+)$ /index.php?category=$1&product=$2 [L]
    
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.+)$ /index.php?category=$1 [L]