1

I have a single-site Wordpress installed on example.com. The DNS is configured so that www.example.com is an ALIAS of example.com. The client wants the user to see www. on their nav bar if they entered it, so this is important.

I hosted their website on an apache server running cpanel. The cpanel has the domain set as example.com. Before I installed wordpress, typing www.example.com brought up the directory and kept the www. on the nav bar, so great.

After I installed wordpress though, the www. is getting removed. When I did a redirect trace I found this odd 302 redirect:

http://www.example.com
Status: 302 Found
Code:   302
Date:   Thu, 24 Aug 2017 00:23:08 GMT
Server: Apache/2.4.16 (Unix) OpenSSL/1.0.1e-fips mod_bwlimited/1.4
Location:   https://example.com
Content-Length: 346
Connection: close
Content-Type:   text/html; charset=iso-8859-1

I modified wordpress's htaccess file to force ssl, but I thought this is a 301:

SSLOptions +StrictRequire
SSLRequireSSL
SSLRequire %{HTTP_HOST} eq "example.com"
ErrorDocument 403 https://example.com

Okay, whatever. So I removed this section of code, the URL bar is still not preserving the www. This time I get a 301 redirect:

http://www.example.com
Status: 301 Moved Permanently
Code:   301
Date:   Thu, 24 Aug 2017 00:35:22 GMT
Server: Apache/2.4.16 (Unix) OpenSSL/1.0.1e-fips mod_bwlimited/1.4
X-Powered-By:   PHP/5.6.16
Location:   http://example.com/
Content-Length: 0
Connection: close
Content-Type:   text/html; charset=UTF-8

I don't know where else to look. What do I need to do in cpanel, htaccess, or wordpress to have the URL bar preserve the www.

1

You need to set the canonical hostname (ie. with www) in the WordPress dashboard... Under Settings > General and set the appropriate "WordPress Address (URL)" and "Site Address (URL)" properties.

Alternatively, these values can be hardcoded in wp_config.php by defining the WP_HOME and WP_SITEURL constants respectively.

Reference:
https://codex.wordpress.org/Changing_The_Site_URL

SSLOptions +StrictRequire
SSLRequireSSL
SSLRequire %{HTTP_HOST} eq "example.com"
ErrorDocument 403 https://example.com

Bit of an aside, but this is a very roundabout (not recommended) way of redirecting to HTTPS. Yes, this will trigger a 302 (temporary), not a 301 (permanent) redirect. This only redirects at all because of a side effect of ErrorDocument. And it only redirects to the document root, the requested URL is lost.

This code actually blocks access to the HTTP-only site and triggers a 403 Forbidden. Because you have set an absolute URL as the 2nd argument to the custom 403, Apache triggers an external (302) redirect to the URL, the root of your site.

If you don't have access to the server config, then this redirect is normally achieved using mod_rewrite in .htaccess. For example:

RewriteCond %{HTTPS} !on
RewriteRule ^ https://www.example.com%{REQUEST_URI} [R=301,L]

This would need to go before the existing WordPress directives in .htaccess.


Once you have set the appropriate hostname within WordPress, you can handle both HTTPS and www redirection in .htaccess if you wish (it would be slightly more efficient). For example:

RewriteCond %{HTTPS} !on [OR]
RewriteCond %{HTTP_HOST} !www\.
RewriteRule ^ https://www.example.com%{REQUEST_URI} [R=301,L]

Make sure you clear your browser cache before testing.


I need the www. preserved only if the user entered it to begin with.

Unless you have a specific reason to do this, then this is generally a bad idea. It potentially creates duplicate content, although you can set a rel="canonical" tag in the head section to alleviate this, and you can specify a preference in Google Search Console (to avoid both hosts being indexed). But the stats will be split between them. How are you setting cookies? If you want cookies shared between both www and non-www (login, sessions, etc.), you'll need to ensure that cookies are set on the apex domain, regardless of which host is accessed - I don't believe this is the default behaviour.

Anyway, if you want to redirect HTTP to HTTPS but preserve whatever host has been accessed (www, non-www or xyz alias) then this is a much simpler redirect as you can reference the HTTP_HOST server variable. For example:

RewriteCond %{HTTPS} !on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
| improve this answer | |
  • Thanks for the help regarding the SSL. As for the canonical hostname, that will force all traffic to www., while I need the www. preserved only if the user entered it to begin with. I think I came up with a solution building off your answer; can you please look at the answer I posted and let me know if it is proper or if it can be made more efficient? – Kumar Aug 24 '17 at 21:43
  • Not having a canonical hostname (www or non-www) is generally a bad idea. Do you have a specific reason for this? I've updated my answer and included a simpler HTTPS redirect that preserves the hostname. – MrWhite Aug 25 '17 at 0:17
0

Changing the canonical hostname in wordpress means that now all traffic becomes www. In this particular use case, only if the user comes in as www. traffic should they continue to see www urls. Otherwise, they should just see example.com, just as they entered it. After doing some more research, I found that a way to do this is to add the following lines to wp_config.php.

define('WP_SITEURL', 'http://' . $_SERVER['HTTP_HOST']);
define('WP_HOME', 'http://' . $_SERVER['HTTP_HOST']);

My understanding of this code is that any url declared as an alias to example.com in both the DNS and Cpanel will be shown the wordpress site with the urls preserved.

To piggyback on MrWhite's SSL advice, I modified his code slightly to accommodate the fact that two URLs (with and without www) need to be allowed:

# Force SSL While Preserving www.#
RewriteCond %{HTTPS} !on
RewriteCond %{HTTP_HOST} www\.
RewriteRule ^ https://www.example.com%{REQUEST_URI} [R=301,L]

# Force SSL for non-www. Traffic #
RewriteCond %{HTTPS} !on
RewriteCond %{HTTP_HOST} !www\.
RewriteRule ^ https://example.com%{REQUEST_URI} [R=301,L]

If a third or fourth etc alias needs to be added the RewriteCond will need to be made more specific and additional Rewrite blocks will be needed.

| improve this answer | |
  • Setting the constants dynamically in wp_config.php does allow the hostname that the user has accessed to be preserved. However, your redirects can be greatly simplified - see my updated answer. – MrWhite Aug 25 '17 at 0:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.