Apache Rewrite - Redirect Wildcard Subdomain and Handling Internal URL shortener

apache, mod-rewrite, redirect, seo

Solution

Is you SEO consultant right?

As all things SEO, the answer involves some guessing and assumptions, but he's probably right.

When you redirect a page, you tell the crawler to forget the initial page and come back later to index the target page instead, which introduces a delay between the first introduction of your page to the world and the actual appearance of your page in the search results. Two redirections means you double that delay. Depending on the "mood" of the search engine, that can add up to a significant regression in you SEO (or some confusion in your indexed urls while the search engine sorts the redirections).

Why you get a 400 response

If you check the documentation for RewriteRule, entry Inside per-server configuration

Given Rule --> Resulting Substitution `^/somepath(.*) --> otherpath$1` : invalid, not supported `^/somepath(.*) --> /otherpath$1` : `/otherpath/pathinfo`

which means that, in a vhost conf, you have to provide an absolute path for your substition (the final one that will be handed back to Apache, previous ones can be anything you like). To solve the 400 error:

`RewriteRule . /index.php [L]`

How to fix the redirection

It will depend on how your index.php builds its redirections, but setting

ServerName www.example.com
UseCanonicalName On

will set `$_SERVER["SERVER_NAME"]`to `www.example.com` and should result in a URL pointing to the canonical domain.

Potential conf

<VirtualHost *:80>
    ServerName www.example.com
    ServerAlias *.example.com example.com

    UseCanonicalName On
    RewriteEngine on

    #set the document root
    DocumentRoot /path/to/the/app 

    # if something goes wrong, setup logs to track what happens
    # comment these lines when you're done
    ErrorLog /a/path/to/a/log/file

    RewriteLogLevel 5
    RewriteLog /a/path/to/another/log/file

    # I simplified the conditions, those are equivalent to your rules
    # a RewriteRule tries to match against %{REQUEST_URI}
    RewriteCond %{HTTP_HOST} ^example\.com [NC]
    RewriteRule ^/b/ /index.php [L] 

    RewriteCond %{HTTP_HOST} !^www\.example\.com [NC]
    RewriteRule ^/(.*)$ http://www.example.com/$1 [R=301]
</VirtualHost>

Problem

I have problem in redirecting wild-card sub-domain and handing internal URL shortener. Let's say I have an internal URL shortener in my app ``` example.com/b/ABCDE ``` that will translate ``` example.com/book/12345678-the-book-name ``` the script referred by `/b/` (I use PHP framework that could handle URL rule) will translate short ID `ABCDE` to the book real ID `12345678` (and the title "The Book Name") then redirect it the book's permanent URL `example.com/book/12345678-the-book-name` so then every time I spread a link about a book in websites like bulletin boards, micro-blogging sites, or physical media like posters or business cards, I use the short link (the `example.com/b/ABCDE`) instead of the permanent link (`example.com/book/12345678-the-book-name`). next, I need to redirect all wild-card sub-domain to the main domain (`www.example.com`) while maintaining the request URI, e.g. ``` http://random.example.com/book/11111111-some-book -> http://www.example.com/book/11111111-some-book http://123456.example.com/book/22222222-another-book -> http://www.example.com/book/22222222-another-book http://abcdefg.example.com/book/33333333-another-book-again -> http://www.example.com/book/33333333-another-book-again ``` by adding the rule below after all the rules I used ``` <VirtualHost *:80> ServerName example.com ServerAlias *.example.com RewriteEngine on RewriteCond %{HTTP_HOST} !^www.example.com [NC] RewriteRule ^/(.*)$ http://www.example.com/$1 [R=301] </VirtualHost> ``` Consequently the url with example.com domain and without prefix like below ``` http://example.com/book/11111111-some-book ``` will translate to ``` http://www.example.com/book/11111111-some-book ``` And, another consequence is that if the internal URL shortener use plain domain without the prefix, it will take two redirection to resolve. For example, ``` http://example.com/b/ABCDE ``` will first be redirected to ``` http://www.example.com/b/ABCDE ``` which then be redirected to ``` http://www.example.com/book/12345678-the-book-name ``` Actually, I don't mind with the two-times redirection. But my SEO consultant said that the two-times redirection is bad for my site's SEO. (which I still don't know why) So I tried change the last rule to below ``` <VirtualHost *:80> ServerName example.com ServerAlias *.example.com RewriteEngine on RewriteCond %{HTTP_HOST} ^example.com [NC] RewriteCond %{REQUEST_URI} ^/b/(.*)$ RewriteRule . index.php [L] RewriteCond %{HTTP_HOST} !^www.example.com [NC] RewriteRule ^/(.*)$ http://www.example.com/$1 [R=301] </VirtualHost> ``` I'm not very good at configuring Apache, but when I simulate above rule in http://htaccess.madewithlove.be/, it works. But when I applied it to my server, it gave me 400 Bad Request for the `example.com/p/ABCDE`. So, my questions are - Is my SEO consultant right about his argument? Is there any explanation that can back him up or is there a counter-argument? - Why the server gave 400 Bad Request? - How to fix the redirection? I want to maintain the short URL (`example.com/b/ABCDE` without `www` prefix) but still in one redirection.

Original source