1

I've read everything I could and can't figure this out. I need a simple page redirect that keeps the original subdomain. We have several stores on their own subdomains with identical product page names, so if someone visits URLs like these:

https://XYZ.example.com/old-product.html
https://ABC.example.com/old-product.html

We need to redirect them to the new product page like so:

https://XYZ.example.com/new-product-page.html
https://ABC.example.com/new-product-page.html

I tried something simple like this, but it redirects to our main www site instead of keeping the subdomain.

RewriteRule ^old-product.html$ new-product-page.html [NC]

I don't know how to catch the subdomain and use it for the rewrite. Can anyone help me? Thanks so much.

EDIT: Here's my .htaccess file, it's a Magento 1.9 site:

# Force www
RewriteCond %{HTTP_HOST} ^example.com
RewriteCond %{REQUEST_URI} !^/[0-9]+\..+\.cpaneldcv$
RewriteCond %{REQUEST_URI} !^/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteCond %{REQUEST_URI} !^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteRule (.*) https://www.example.com/$1 [R=301,L]
SetEnvIf SERVER_PORT 443 HTTPS=on

# Force https
RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} !^/[0-9]+\..+\.cpaneldcv$
RewriteCond %{REQUEST_URI} !^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE]

# XYZ Env Variables
SetEnvIf Host www\.XYZ\.example\.com MAGE_RUN_CODE=XYZ_website
SetEnvIf Host www\.XYZ\.example\.com MAGE_RUN_TYPE=website
SetEnvIf Host ^XYZ\.example\.com MAGE_RUN_CODE=XYZ_website
SetEnvIf Host ^XYZ\.example\.com MAGE_RUN_TYPE=website

# ABC Env Variables
SetEnvIf Host www\.ABC\.example\.com MAGE_RUN_CODE=abc_website
SetEnvIf Host www\.ABC\.example\.com MAGE_RUN_TYPE=website
SetEnvIf Host ^ABC\.example\.com MAGE_RUN_CODE=abc_website
SetEnvIf Host ^ABC\.example\.com MAGE_RUN_TYPE=website

<IfModule mod_ssl.c>
############################################
## make HTTPS env vars available for CGI mode

    SSLOptions StdEnvVars
</IfModule>

<IfModule mod_rewrite.c>
############################################
## enable rewrites

    Options +FollowSymLinks
    RewriteEngine on
</IfModule>

EDIT 2: Well I figured out part of the answer:

RewriteCond %{HTTP_HOST} ^(.*)\.example\.com [NC]
RewriteRule ^(.*)old-product.html$ new-product-page.html [R=301,L]

That's returning a URL like this:

https://www.example.com/live/public_html/new-product-page.html

How can I remove the /live/public_html part?

0
RewriteCond %{HTTP_HOST} ^(.*)\.ourdomain\.com [NC]
RewriteRule ^(.*)old-product.html$ new-product-page.html [R=301,L]

For an external redirect, the substitution string (2nd argument to the RewriteRule directive) needs to be either root-relative (starting with a slash) or absolute (scheme + hostname). Unless you have specified a RewriteBase directive elsewhere in your config. So, it should be /new-product-page.html (with a slash prefix).

A relative substitution string is seen as relative to the directory that contains the .htaccess file. And this results in the directory-prefix being added back, hence the live/public_html/ part in your resulting redirect (this is OK for an internal rewrite).

For example, try the following rule. It doesn't really matter where this goes, although it would be logical to have it after the "Force https" rule.

RewriteCond %{HTTP_HOST} ^(xyz|abc)\.example\.com [NC]
RewriteRule ^old-product\.html$ /new-product-page.html [R=302,L]

If you want to redirect only specific subdomains/hostnames then yes, you'll need to check the Host header (ie. HTTP_HOST server variable). Although in your directive, you made this very general - to redirect any subdomain? If the redirect is not dependent on the hostname then remove the condition altogether.

If you want to redirect /old-product.html only then you don't need the (.*) prefix, as you had in your directive.

When the server constructs the redirect response, it will (by default) preserve the scheme and hostname from the request. There is nothing else you need to do, unless your server is configured otherwise. (The server could be configured to always use the defined ServerName, however, this is not the default.)

Note that this is a 302 (temporary) redirect. Only change to a 301 (permanent) once you have confirmed that it all works OK. 301s are cached persistently by the browser so can make testing problematic.


However, the above does result in two redirects when requesting http://xyz.example.com/old-product.html (note the HTTP) - regardless of where you place the directive. Since the redirect to HTTPS is separate.

To "fix" this, so you only get at most one redirect, specify an absolute URL (include the HTTPS scheme) and place this at the top of the .htaccess file:

RewriteCond %{HTTP_HOST} ^(xyz|abc)\.example\.com [NC]
RewriteRule ^old-product\.html$ https://%{HTTP_HOST}/new-product-page.html [R=302,L]

I tried something simple like this, but it redirects to our main www site instead of keeping the subdomain.

RewriteRule ^old-product.html$ new-product-page.html [NC]

This is an "internal rewrite" (absence of the R flag), not an external "redirect". And given the .htaccess file as posted, this could not have triggered an external redirect.

If you were seeing a "redirect" then something else in Magento's code base may have been triggering this. How does your site handle 404s?

| improve this answer | |
  • 1
    Great! It works perfectly. Thanks so much for the explanation too. Just an FYI for others, I used (.*) in place of (xyz|abc) to handle any subdomain. – JohnWLIV Feb 20 at 17:21

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.