1

htaccess | 301 redirect | URI Issue

I recently applied this code to my htaccess to enforce the trailing slash on my URL:

#Trailing backslash
RewriteBase /
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ $1/ [L,R=301]

The code works great at adding a / at the end of MOST URLs except for those with ? in the middle of the URL. Like below:

https://www.example.com/list-of-all-objects/search?keywords=test

This URL with the currently code that is stated above will change on load to this: https://www.example.com/list-of-all-objects/search/?keywords=test

When it should look like this: https://www.example.com/list-of-all-objects/search?keywords=test/

I have quickly learnt all of the code that I have applied does not work for two reasons.

  1. They don't enforce the / - they just make it possible if its blocked
  2. The term REQUEST_URI or $1 or $2 all don't include ?keyword= (in fact there is nothing that I can find that refers to this part of the URL so I can't include it correctly)

No matter what I do - I can't get a ? or anything after it to be placed before the /. HOW do I get the trailing slash to not be applied before the ? on keyword search but at the end of the URL and continue to be applied at the end of all the other URL's?

Other previously tried methods:

 # Force Trailing Slash
enter code hereRewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)([^/])$ http://%{HTTP_HOST}/$1$2/ [L,R=301]

Found here: .htaccess Rewrite to Force Trailing Slash at the end

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*[^/])$ /$1/ [L,R=301]

Found here: Htaccess: add/remove trailing slash from URL

<IfModule mod_rewrite.c>
 RewriteCond %{REQUEST_URI} /+[^\.]+$
 RewriteRule ^(.+[^/])$ %{REQUEST_URI}/ [R=301,L]
</IfModule>

Found here: http://www.paulund.co.uk/using-htaccess-to-force-trailing-slash

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ http://%{HTTP_HOST}/$1/ [L,R=301]

Found here: http://ralphvanderpauw.com/seo/how-to-301-redirect-a-trailing-slash-in-htaccess/

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !example.php
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ http://domain.com/$1/ [L,R=301]

Found here: http://enarion.net/web/htaccess/trailing-slash/

# Trailing slash check

# Don't fix direct file links
RewriteCond %{REQUEST_FILENAME} !-f

RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ $1/ [L,R=301]

Found here: https://moz.com/community/q/trailing-slash-at-end-of-url

# Always append a trailing slash
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !/$
RewriteRule . %{REQUEST_URI}/ [R=301,L]

Found here: https://craftcms.stackexchange.com/questions/9501/force-trailing-slash-on-urls

Below is my complete htaccess file contents:

RewriteEngine On

#Trailing backslash
RewriteBase /
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ $1/ [L,R=301]


#HTTPS Redirects
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

RewriteCond $1 !\.(gif|jpe?g|png)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d 
RewriteRule ^(.*)$ /index.php?/$1 [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* [QSA,L]

<IfModule mod_expires.c>
# Enable expirations
ExpiresActive On 
# Default directive
ExpiresDefault "access plus 1 month"
# My favicon
ExpiresByType image/x-icon "access plus 1 year"
# Images
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/jpg "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
# CSS
ExpiresByType text/css "access plus 1 month"
# Javascript
ExpiresByType application/javascript "access plus 1 year"
</IfModule>
Community
  • 1
  • 1
Trent
  • 429
  • 1
  • 5
  • 19

1 Answers1

1

Query_string is not part of match in RewriteRule.

To add a trailing slash to query strings, you can use :

RewriteCond %{QUERY_STRING} ([^/]+)$ [NC]
RewriteRule ^ %{REQUEST_URI}?%1/ [R,L]

EDIT :

As I already said, query strings can not be handled directly by a RewriteRule directive, so you need a separate rule to add trailing slash to query strings.

The example bellow adds a trailing slash to both parts of the url.

  RewriteEngine on

  #Add a trailing slash to uri
  RewriteCond %{REQUEST_URI} !/$
  RewriteRule ^ %{REQUEST_URI}/ [NC,L,R]
  #Add a trailing slash to query strings
  RewriteCond %{QUERY_STRING} ([^/]+)$ [NC]
 RewriteRule ^ %{REQUEST_URI}?%1/ [R,L]

This will change the following urls :

to

Or

to

(Hope, this helps!)

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Amit Verma
  • 40,709
  • 21
  • 93
  • 115
  • Amazing answer however this only enforces the trailing slash on the problem URL's for me and doesn't work for all of the others. Is there any way for it to do both. This is how my htaccess trailing slash section looks now with the changes you've suggested `#Trailing backslash RewriteBase / RewriteCond %{HTTP_HOST} !^www\. [NC] RewriteRule ^(.*)$ https://www.reeffree.com.au/$1 [R=301,L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_URI} !(.*)/$ RewriteCond %{QUERY_STRING} ([^/]+)$ [NC] RewriteRule ^ %{REQUEST_URI}?%1/ [R,L]` – Trent Jan 28 '16 at 00:07
  • 1
    @Trent You will need to use 2 separate rules for this. See the edit. – Amit Verma Jan 28 '16 at 13:30
  • Thank you for your feedback. I understand and agree that two statements are needed but having both causes the rule for URLs without ? applies to URLs with ? as well so it ends up doing this: https://www.example.com/list-of-all-objects/search/?keywords=test/ Is there a way to use an IF statement – Trent Jan 29 '16 at 00:18
  • Is an if statement possible? – Trent Feb 02 '16 at 00:23