22

I applied the following mod_rewrite rule in Apache2 to redirect from non-www to www:

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

However, there's a double slash issue:

  • When I go to http://www.example.com it correctly rewrites the URL to http://www.example.com/
  • When I go to http://www.example.com/somepage, it correctly rewrites the URL to http://www.example.com/somepage
  • If I go to http://example.com, it rewrites the URL to http://www.example.com// (double final slash)
  • If I go to http://example.com/somepage, it correctly rewrites it to http://www.example.com/somepage

Is my configuration good for SEO?

Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
Mark
  • 67,098
  • 47
  • 117
  • 162

5 Answers5

40

Fixed with:

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

because $1 by default contains the index path /

Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
Mark
  • 67,098
  • 47
  • 117
  • 162
  • 2
    It's worth clarifying for other readers that this only applies when the directive is used in a _server_ or _virtualhost_ context. When used in a _directory_ (ie. `` container) or `.htaccess` context then the URL-path matched by the `RewriteRule` _pattern_ does NOT contain a slash prefix. – MrWhite Jul 28 '20 at 12:32
  • 1
    @MrWhite That is a huge distinction which answered my problem. I had moved all my `.htaccess` directives to the `.conf` and nothing worked. It was the leading `/` issue! Thank you. – IncredibleHat Jun 24 '23 at 14:48
21
RewriteRule ^\/?(.*)$ http://www.example.com/$1 [R=301,L]
Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
Rahly
  • 1,462
  • 13
  • 16
  • IMHO this solution should be preferred in relation to the accepted one, since leaving out the leading / from the match is cleaner than leaving out from the rewrite. – h7r Mar 21 '15 at 14:54
  • Minor point, but there is no need to backslash escape the forward slash in the `RewriteRule` _pattern_. – MrWhite Jul 28 '20 at 12:29
  • @MrWhite why there is no need to escape it? Isn't it a special character? Thanks! – StockBreak Mar 17 '21 at 13:41
  • 1
    @StockBreak The forward slash is not a "special character" in regex. The forward slash is sometimes used to "delimit" regex (in some environments), but in Apache config files (except when using Apache expressions), the _spaces_ are the regex (and argument) delimiters. – MrWhite Mar 17 '21 at 14:04
  • Thanks, I thought that Apache used `/` as a delimiter internally. – StockBreak Mar 18 '21 at 12:51
6

Actually, you will always have double slashes due to

RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,L]

combined with the fact that REQUEST_URI (that you are matching on) normally contains a starting slash. What you can try is RewriteRule ^(.*)$ http://example.com$1, and then send a broken HTTP request GET foo HTTP/1.0 and see if Apache deals with it properly.

Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
user502515
  • 4,346
  • 24
  • 20
2

Putting a slash into your pattern should resolve this issue:

RewriteRule ^/(.*)$ http://www.example.com/$1 [R=301,L]
Dennis Winter
  • 2,027
  • 4
  • 32
  • 45
1

That is because the root path is /, and you are appending whatever you get in RewriteRule (the first case works fine because it doesn't match the condition so no rewrite is performed).

You can try something like this:

RewriteEngine On
RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
# for the home page
RewriteRule ^/$ http://www.example.com/ [R=301,L]
# for the rest of pages
RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,L]
Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
Alberto Martinez
  • 2,620
  • 4
  • 25
  • 28