How to redirect a bare domain to www in Apache

Redirecting example.com to www.example.com// keeps one canonical hostname for browsers, search engines, cookies, caches, and application-generated links. A single host identity avoids split sessions and duplicate URL variants when the same site answers on both the bare and www names. In Apache, the requested host arrives in the Host header and is matched against ServerName and ServerAlias inside the best VirtualHost for that IP address and port. A redirect to www works cleanly when the bare host is redirected in its own VirtualHost or when both names reach the same document root and a host-aware .htaccess rule handles the redirect there. Examples below use the Debian and Ubuntu layout with /etc/apache2/, apache2ctl, and the apache2 systemd unit. Both hostnames must already resolve to the server, and HTTPS adds another prerequisite: the certificate must cover both names or the TLS handshake fails before Apache can send the redirect. The .htaccess method also needs mod_rewrite plus override permission for FileInfo and Options. Test with a temporary 302 first, because browsers and intermediaries can cache a 301 aggressively.

===== Steps to redirect a bare domain to www in Apache: ===== ===== Redirect naked domain to www in Apache using htaccess ===== The .htaccess method is useful when the redirect logic needs to stay inside the site tree instead of the main Apache configuration. It works only when the site already routes both hostnames to the same document root and the directory is allowed to use rewrite directives. This approach is more flexible than a dedicated redirect-only VirtualHost, but it also adds per-request filesystem lookups. When full server configuration access is available, the VirtualHost method below is usually simpler and faster. - Enable mod_rewrite if it is not already loaded. <code> $ sudo a2enmod rewrite Enabling module rewrite. To activate the new configuration, you need to run: systemctl restart apache2 </code>

On Debian and Ubuntu, a2enmod enables the module. On RHEL-family systems, confirm that mod_rewrite is already loaded with sudo httpd -M | grep rewrite.

- Open the site VirtualHost file that serves the canonical www hostname. <code>$ sudo vi /etc/apache2/sites-available/example.com.conf</code>

- Confirm that the VirtualHost answers both hostnames and allows the rewrite directives that the .htaccess rule needs. <code apache> <VirtualHost *:80> ServerName www.example.com ServerAlias example.com DocumentRoot /var/www/html <Directory /var/www/html> AllowOverride FileInfo Options Options FollowSymLinks </Directory> </VirtualHost> </code>

Without ServerAlias example.com, requests for the bare host do not reach this document root, so the .htaccess redirect never runs.

Keep any existing access directives such as Require all granted, PHP handlers, or logging directives that the site already uses.

- Test the Apache configuration before restarting the service. <code> $ sudo apache2ctl -t Syntax OK </code>

Use sudo apachectl -t or sudo httpd -t on platforms that expose those control names instead.

- Restart Apache if the module state or VirtualHost configuration changed. <code>$ sudo systemctl restart apache2</code>

Use sudo systemctl restart httpd on RHEL-family systems.

- Open or create the site .htaccess file inside the DocumentRoot directory. <code>$ sudo vi /var/www/html/.htaccess</code> - Add a temporary bare-host redirect rule. <code apache> RewriteEngine On RewriteCond %{HTTP_HOST} ^example\.com$ [NC] RewriteRule ^ http://www.example.com%{REQUEST_URI} [R=302,L] </code>

Change the target to https://www.example.com when the canonical www site already serves HTTPS.

If the site already has other host or scheme redirects, combine the rules carefully to avoid redirect loops.

- Verify that the bare hostname now redirects to the canonical www hostname. <code> $ curl -I http://example.com/docs/page.html?ref=1 HTTP/1.1 302 Found Date: Thu, 09 Apr 2026 04:49:37 GMT Server: Apache/2.4.66 (Unix) Location: http://www.example.com/docs/page.html?ref=1 Content-Type: text/html; charset=iso-8859-1 </code>

A request to http://www.example.com/docs/page.html?ref=1 should return the page itself instead of another redirect.

- After the redirect behaves correctly, change the rule to a permanent redirect. <code apache> RewriteEngine On RewriteCond %{HTTP_HOST} ^example\.com$ [NC] RewriteRule ^ http://www.example.com%{REQUEST_URI} [R=301,L] </code>

Apache reads the updated .htaccess file on the next request, so a service restart is not required for this final change.

===== Redirect naked domain to www in Apache using Virtualhost ===== A dedicated redirect-only VirtualHost keeps canonical-host logic in the server configuration instead of the content tree. This avoids .htaccess lookups on every request and is the cleaner option when Apache VirtualHost files are available. The important detail is host matching. The bare host and the canonical www host should be defined as separate VirtualHost blocks on the same address and port. If a redirect is placed inside a www vhost that also aliases the bare host, both names are caught by the same redirect block. - Open or create the site VirtualHost file. <code>$ sudo vi /etc/apache2/sites-available/example.com.conf</code>

- Add a redirect-only VirtualHost for the bare hostname and keep the application site in a separate www VirtualHost. <code apache> <VirtualHost *:80> ServerName example.com Redirect temp “/” “http://www.example.com/” </VirtualHost> <VirtualHost *:80> ServerName www.example.com DocumentRoot /var/www/html </VirtualHost> </code>

Keep existing directory rules, logging, proxy directives, PHP handlers, and aliases in the canonical www vhost instead of duplicating them in the redirect-only block.

If the bare host must also redirect on HTTPS, create a separate *:443 bare-host VirtualHost after the certificate already covers both names.

- Test the Apache configuration before reloading the service. <code> $ sudo apache2ctl -t Syntax OK </code>

- Reload Apache to apply the new VirtualHost definitions. <code>$ sudo systemctl reload apache2</code>

Use sudo systemctl reload httpd on RHEL-family systems.

- Verify that the bare hostname redirects to the canonical www hostname while the www vhost stays local. <code> $ curl -I http://example.com/docs/page.html?ref=1 HTTP/1.1 302 Found Date: Thu, 09 Apr 2026 04:48:22 GMT Server: Apache/2.4.66 (Unix) Location: http://www.example.com/docs/page.html?ref=1 Content-Type: text/html; charset=iso-8859-1 </code>

The same request sent to http://www.example.com/docs/page.html?ref=1 should return a normal page response instead of another redirect.

- After the redirect is confirmed, change the rule to a permanent redirect and reload Apache again. <code apache> <VirtualHost *:80> ServerName example.com Redirect permanent “/” “http://www.example.com/” </VirtualHost> </code>

Use temporary or temp only for testing. Permanent redirects are commonly cached by browsers and reverse proxies.