1

I have a website www.example.com running on Apache.

Maybe someone got to me via example.com, or www.example.com, or http://example.com, or even http://www.example.com.

Can I use the rewrite rules in .htaccess so that however they get to example.com, the URL is fully fleshed out to http://www.example.com?

Daniel Kaplan
  • 171
  • 11

1 Answers1

0

Assuming Apache is already accepting requests to both the www subdomain and the domain apex (ie. example.com) then you can canonicalize the hostname to www using something like the following using mod_rewrite near the top of your .htaccess file in the document root.

RewriteEngine On

RewriteCond %{HTTP_HOST} ^example\.com [NC]
RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

The above redirects any request of the form example.com/<anything> to http://www.example.com/<anything>. The REQUEST_URI server variable contains the full URL-path, including the slash prefix. Any query string that might be on the original request is passed through unchanged.

Test first with a 302 (temporary) redirect to avoid potential caching issues.

Maybe someone got to me via example.com, or www.example.com, or http://example.com, or even http://www.example.com.

NB: example.com and http://example.com are the same - the browser simply hides the protocol (and defaults to HTTP for most users). The same for www.example.com and http://www.example.com.


UPDATE:

when I just tried this out, the browser URL remains example.com

If you haven't done so already, you need to enable .htaccess overrides in the server config, otherwise the .htaccess file will simply be ignored.

In the appropriate <Directory> container inside the <VirtualHost> (or main server config) you need to set AllowOverride (the default is `None). For example:

<Directory /path/to/document-root>
    Options +FollowSymLinks
    Require all granted

    # Enable .htaccess overrides
    AllowOverride All
</Directory>

AND, if you haven't already, you need to enable mod_rewrite:

Debugging .htaccess

You can increase the LogLevel (Apache 2.4+) in the server config to output debug information to the server's error log. For example, in the respective <VirtualHost> container (or main server config):

LogLevel debug

This sets the "log level" for all modules. The default is LogLevel warn. To target just a specific module, such as mod_rewrite (used above) then you can specify just that module. eg. LogLevel rewrite:debug.

Reference:

MrWhite
  • 183
  • 1
  • 12
  • There are subdirectories, obviously, on my website. Will this include them? Also, does .htaccess have a print feature? So I can debug? Because when I just tried this out, the browser URL remains example.com. – Daniel Kaplan May 05 '21 at 18:30
  • @DanielKaplan Yes, as mentioned, this redirects `example.com/`, copying the URL-path (ie. ``) onto the target URL. You need to enable `.htaccess` overrides in the server config if you haven't already. I've updated my answer. – MrWhite May 05 '21 at 18:37
  • I've added more info about "debugging". There is no "print feature" as such. – MrWhite May 05 '21 at 18:46
  • Rewrite is on, but to test I changed one of your lines to this: 'RewriteRule ^ http://ww4w.%{HTTP_HOST}%{REQUEST_URI} [R=302,L]' figuring it should fail. it does not. – Daniel Kaplan May 05 '21 at 21:18
  • (_Aside:_ To format inline code in comments use _backticks_.) @DanielKaplan – MrWhite May 05 '21 at 21:49
  • @DanielKaplan Try typing some _nonesense_ at the top of the `.htaccess` file. Do you get an error? If no error then `.htaccess` overrides are not enabled and you need to set `AllowOverride All` at the appropriate place in the server config (as mentioned above). Apache needs to be restarted after making changes to the server config. – MrWhite May 05 '21 at 21:51
  • no error reported with garbage at top. I have 'RewriteEngine on' at top of .htaccess (although I have more than one htacess file, this one is at the root (public_html). As well, in sudo nano /etc/apache2/sites-available/000-default.conf I have ServerAdmin webmaster@localhost DocumentRoot /var/www/html AllowOverride All ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined – Daniel Kaplan May 05 '21 at 23:15
  • As well when I enter the command 'sudo a2enmod rewrite' it tells me that Module rewrite already enabled – Daniel Kaplan May 05 '21 at 23:17
  • @DanielKaplan Do you have a symlink from `sites-enabled` to `sites-available`? You say "this one is at the root (public_html)", but you have `DocumentRoot /var/www/html`? Where does `public_html` fit into this? `AllowOverride All` needs to be defined inside a `` container (as shown above), not directly inside the vHost as you appear to be doing? – MrWhite May 06 '21 at 01:03
  • They way my server is set up, the html sits at /var/www/example.com/public_html. Checking on the 1st part of your comment – Daniel Kaplan May 06 '21 at 04:13
  • Right now I can't seem to get to trace the rewrites. I placed 'LogLevel alert rewrite:trace8' into the example.com.conf file. Is that the wrong place? – Daniel Kaplan May 06 '21 at 04:38
  • I have so many 'confs' files. For each domain, the 000-default one. Where do I place the Rewrite log level? Everywhere I have tried and I can't restart apache because of a syntax error. – Daniel Kaplan May 06 '21 at 21:34
  • 1
    @DanielKaplan "the html sits at /var/www/example.com/public_html" - in that case, it should be `DocumentRoot /var/www/example.com/public_html`, not `DocumentRoot /var/www/html` as in your earlier comment. "I placed 'LogLevel alert rewrite:trace8' into the example.com.conf file. Is that the wrong place?" - You need to place the directive in the vHost container that relates to the site you are accessing. Each "domain" (or "site", if you have multiple domains) would often have a single conf file, named according to the canonical domain. `000-default` is just the _default_. – MrWhite May 21 '21 at 11:39
  • @DanielKaplan "I can't restart apache because of a syntax error." - what is the error reported in the logs? – MrWhite May 21 '21 at 11:39