RewriteRule to redirect non-www to www

Hi Everyone,

Im in struggle with my rewrite settings right now and hope someone can help me to find the right htaccess rules.

What I want to achieve:
I want to redirect every non-www-link to www (using HTTP response code 301)
http://domain.com should be redirect to http://www.domain.com
and http://domain.com/example should be redirect to http://www.domain.com/example
So I want to keep the current directory structure.

Currently I only get this:
http://domain.com redirects to http://www.domain.com
but http://domain.com/example redirects to http://www.domain.com/index.php

My setup right now:
Apache 2.2.22

htaccess

<IfModule mod_rewrite.c>

# enable awesome urls. i.e.:
# http://yourdomain.com/about-us/team
RewriteEngine on

# make sure to set the RewriteBase correctly
# if you are running the site in a subfolder.
# Otherwise links or the entire site will break.
#
# If your homepage is http://yourdomain.com/mysite
# Set the RewriteBase to:
#
#RewriteBase /

# make cachebuster asset links work
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)\.(\d+)\.(js|css)$ $1.$3 [L]

# block text files in the content folder from being accessed directly
RewriteRule ^content/(.*)\.(txt|md|mdown)$ index.php [L]

# block all files in the site folder from being accessed directly
RewriteRule ^site/(.*) index.php [L]

# block all files in the kirby folder from being accessed directly
RewriteRule ^kirby/(.*) index.php [L]

# make panel links work
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^panel/(.*) panel/index.php [L]

# make site links work
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*) index.php [L]
</IfModule>

<IfModule mod_rewrite.c>
     RewriteEngine On
     RewriteCond %{HTTPS} !=on
     RewriteCond %{HTTP_HOST} !^www\. [NC]
     RewriteCond %{SERVER_ADDR} !=127.0.0.1
     RewriteCond %{SERVER_ADDR} !=::1
     RewriteRule ^ %{ENV:PROTO}://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</IfModule>

Thank you!

Have you tried to add these lines to your mod_rewrite section right after your RewriteBase setting:

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

I don’t quite understand why you set the URL in your config file? And to the non-www domain on top of that?

ups, the non-www domain was just a typo in this post.
Didn’t know that kirby is creating absolute links by default. Always thaught that I have to add the domain in my Kirby Config…

It’s usually not necessary to set the URL in your config. Kirby should autodetect it.

The solution @jbeyerstedt posted is the recommended setting to redirect non-www to www domains.

1 Like

Okay, thank you for this.

I cleaned everything and now I only have the Kirby htaccess + @jbeyerstedt solution. But nothing has changed.

Did you add the code right at the beginning after the RewriteBase definition?

1 Like

@lukasbestle That’s the solution, it’s working now :slight_smile: Thank you so much.

My final htaccess file looks like this:

<IfModule mod_rewrite.c>

# enable awesome urls. i.e.:
# http://yourdomain.com/about-us/team
RewriteEngine on

# make sure to set the RewriteBase correctly
# if you are running the site in a subfolder.
# Otherwise links or the entire site will break.
#
# If your homepage is http://yourdomain.com/mysite
# Set the RewriteBase to:
#
#RewriteBase /

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

# make cachebuster asset links work
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)\.(\d+)\.(js|css)$ $1.$3 [L]

# block text files in the content folder from being accessed directly
RewriteRule ^content/(.*)\.(txt|md|mdown)$ index.php [L]

# block all files in the site folder from being accessed directly
RewriteRule ^site/(.*) index.php [L]

# block all files in the kirby folder from being accessed directly
RewriteRule ^kirby/(.*) index.php [L]

# make panel links work
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^panel/(.*) panel/index.php [L]

# make site links work
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*) index.php [L]
</IfModule> 

@Ti_Gr:

add the code right at the beginning after the RewriteBase definition

and not in front of it!

In your case “RewriteBase” is commented out (a “#” is in front of its line), but for others your file is not correct, put it after the line:

#RewriteBase /

2 Likes

You’re right. Thank you for hint.

On many Kirby installations, we don’t need to uncomment (and may be to complement) the line

The line

#RewriteBase /

is then ok.

1 Like

okay… I figured out that both works fine for me and it doesn’t really effect my redirects.

Thank you for your time and help :slight_smile:

Another solution: Since you are on Apache and I guess you are using virtual hosts, you could check out the “ServerAlias” configuration directive in Apache Docs, maybe this allows you to avoid the hassle of the rewrite engine.

Hm, but then both URLs will work and it won’t redirect. Actually the solution above requires that Apache routes both domains to the same directory, and it will only do the redirection on top of that.

Thats true - it always depends on the requirements. Yet another solution could be the “RedirectPermanent” directive, recommended by Apache for pure domain -> domain redirects.