Forum Moderators: phranque
My issue is concerning redirecting with .htaccess. Let me first setup my situation.
My site used to be in the /view.php?linkid=1 form. Recently, during a complete site redesign, I've discovered the wonders of mod_rewrite. The URL for this page on my site will soon be /view/1/post-title/. It looks better, and I believe it may even help regarding SEO.
Anyway, to do this, I have the following rule in my .htaccess:
RewriteRule ^view/([0-9]*)/[a-zA-Z0-9-]*/?$ view.php?linkid=$1 [NC]
This works great. However, I have a slight problem - my old style URLs still work, and google has indexed my old /view.php?linkid=x format URLs. So when the new site is rolled out, google will see new URLs with the same content, which i've read isn't ideal.
So I need to do a 301 redirect. To achieve this, I have added the following to .htaccess:
RewriteCond %{QUERY_STRING} linkid=([0-9]*)$ [NC]
RewriteRule ^view.php$ [localhost...] [R]
Note - [R] is used instead of [R=301] to avoid permanent caching issues while in development, and obviously localhost will be replaced with the domain in deployment.
Anyway, this rule also works - unfortunately though what I've done is created an endless loop. When a view.php?linkid=x URL is accessed, it obviously redirects to /view/x/, which in turn is just a rewrite of view.php?linkid=x, and hence the endless loop.
I know there must be something I'm missing, so any help is greatly appreciated. Perhaps I'm going about this the wrong way? Basically, I just want to rewrite my old dynamic URL to a static one while also redirecting said old dynamic URL to the static one.
Thanks for any help.
You need for the redirect to fire only for direct client requests. To that end you need to examine THE_REQUEST when deciding whether to redirect or not.
The redirect must include the domain name in the target URL.
The redirect must be listed before the rewrite.
Note that [R] gives a 302 redirect, and you'll need [R=301]. You can get a LOT of search engine problems with a 302 redirect.
Every rule must end with [L].
RewriteCond %{THE_REQUEST},%{QUERY_STRING} bla bla,linkid=([0-9]*)$ [NC]
Correct? obviously where bla bla is checking the HTTP request header. I know that much, but I'm not sure exactly what I'm looking for?
Oh and I know about 302's and search engines, I'm just using [R] in development as to avoid browser caching.
RewriteCond %{the_request} ^[A-Z]{3,9}\ /view\.php\?linkid=(.*)\ HTTP/
RewriteRule ^view.php$ [localhost...] [R,L]
This seems to work without even needing the %{query_string} condition.
Thanks for the help - and feel free to let me know if this is not the best solution (it works, but I'm not opposed to making things work better :)).
You absolutely cannot guess the syntax without risking bringing your whole site down, inaccessible to everyone.
THE_REQUEST will contain the full request made by the browser or bot, including query string.
There's no need to be looking explicitly at QUERY_STRING.