Search code examples
wordpress.htaccesshttp-redirecthttp-status-code-301

Subdomain/subfolder redirect conflict


We have a bunch of sites that are subdomains. We are changing the structure of these sites so they are a single site instead of multiple WordPress installs. No problem. Many of the subdomains have authority so we want to add 301 redirects from these subdomains to the new corresponding page. However, the new page parent page URLs conflict with the old subdomain structure.

existing subdomain

sub1.example.com

redirect which is now a landing page.

example.com/sub1

There is a conflict because the subdomain folders need to stay in place to perform the redirects.

I am looking for a way to create a redirect in the .htaccess from the subdomains that does not conflict with the new page URL of the same name?


Solution

  • it is preferred to leave the folders in tact so we can add 301 redirects to the .htaccess files in these folders

    This is part of the problem. Any .htaccess file in these subdirectories will override the .htaccess file in the parent directory (the main WP directives I assume). (Strictly speaking it's just the mod_rewrite directives that are overridden. Other modules are inherited.)

    Instead, try the following:

    (NB: This assumes the subdomain points to a corresponding subdirectory off the main domain's document root. It would simpler if you changed the subdomain, so that it also pointed to the document root of the main site. You would then only need a single (simpler) redirect.)

    1. Delete the .htaccess (and index.php) file(s) in the subdirectory and instead add the appropriate directives in the parent .htaccess file.

    2. Near the top of the root .htaccess file (before any existing WP directives):

      RewriteCond %{HTTP_HOST} ^(?:www\.)?(sub1|sub2|sub3)\.example\.com
      RewriteRule ^[^/]+/(.*) http://example.com/%1/$1 [R=302,L]
      

      This would redirect sub1.example.com/<anything> to http://example.com/sub1/<anything>. The www sub-subdomain on the initial request is optional.

      Exactly how you would do this could depend on how many (and what format) subdomains you have. If you have just a handful (you say you have 3) then it would preferable to name these explicitly, as in the above RewriteCond directive.

      It is easier to use a 302 (temporary) redirect whilst testing since they aren't cached by the browser. (Ensure the browser cache is cleared before testing.)

    3. You will need to update the main WordPress directives to include an additional rule/condition for when these bare subdirectories are accessed (eg. http://example.com/sub1/). Since /sub1 is a physical directory, WP will not route the request, because the WordPress front-controller specifically ignores existing files and directories.

      In the main WP .htaccess file, you have the following directives:

      # BEGIN WordPress
      <IfModule mod_rewrite.c>
      RewriteEngine On
      RewriteBase /
      RewriteRule ^index\.php$ - [L]
      RewriteCond %{REQUEST_FILENAME} !-f
      RewriteCond %{REQUEST_FILENAME} !-d
      RewriteRule . /index.php [L]
      </IfModule>
      # END WordPress
      

      Add the following rule immediately after the above:

      RewriteCond %{REQUEST_FILENAME} -d
      RewriteRule ^(sub1|sub2|sub3)/?$ /index.php [L]
      

      This allows requests for the bare subdirectory (eg. http://example.com/sub1/) to be routed by WordPress.