homepage Welcome to WebmasterWorld Guest from
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Become a Pro Member

Home / Forums Index / Code, Content, and Presentation / Apache Web Server
Forum Library, Charter, Moderators: Ocean10000 & incrediBILL & phranque

Apache Web Server Forum

permanent redirect from dynamic to static 301

 12:36 pm on Apr 12, 2013 (gmt 0)

I have spent almost a day now, trying to figure out how to rewrite my old dynamic url's to my new static ones. Without luck. This is what I need:




Best options should be something like:
RewriteCond %{QUERY_STRING} ^newsid=79$
RewriteRule ^news\.php$ http://www.example.com/het-heilig-licht/? [R=301,L]

RewriteRule ^/news.php?newsid=79$ http://www.example.com/gestalten-en-stemmingen/? [R=301,L]

However, I cannot get it to work. Alex Juel advised me to try your forum. Awaiting the solution anxiously. ;-)

[edited by: Ocean10000 at 1:53 pm (utc) on Apr 12, 2013]
[edit reason] Examplified [/edit]



 1:08 pm on Apr 12, 2013 (gmt 0)

I should add that the number of the old page does not match the new page. They are different pages, and that is what causes my difficulty.


 8:50 pm on Apr 12, 2013 (gmt 0)

There's another difficulty. The subject line says "permanent redirect" while the body of the first post says "rewrite".

Since your new URLs look nicer than your old URLs I will guess that you want a redirect, but I'm not going any further until I'm sure what you want to do. And if it is a redirect, you also need to deal with fetching content from wherever it "really" lives. That place is definitely not the target; it might even be your old URL. In which case you need a supplementary rewrite.

RewriteRule ^/news.php?newsid=79$

This format will never work. RewriteRules do not see the query string; they only see the body of the URL.

If this is happening in htaccess, leave off the leading slash or the rule will always fail, even if you omit the query. Forms with leading slash are used in config files but not in anything directory-specific.

Oh, wait. Haven't pasted-in this boilerplate in ages, so I might as well toss it in here. It will give you something to read, at least.

The Redirect-to-Rewrite Two-Step

Problem: Your dynamically generated pages have long, ugly, hard-to-memorize URLs, probably containing query strings. You want them to have short pretty URLs.

The Solution comes in two parts.

Part 1. Redirect
When a user asks for the long ugly URL, redirect to the short pretty URL. Basic pattern:

RewriteCond %{THE_REQUEST} \?
RewriteCond %{QUERY_STRING} queryname=([a-z]+)
RewriteRule longcomplicatedURL http://www.example.com/blahblah/%1? [R=301,L]

The %1 is captured from the original query string, and the final ? means that you now get rid of the query string. In real life it will usually be a little more complicated, but that's the basic process.

user asks for

They get bounced over to

Part 2. Rewrite
You get an incoming request for a short pretty URL-- either from a new arrival or from someone who was redirected in Part 1. The server can't tell the difference.

RewriteRule blahblah/([a-z]+)$ longcomplicatedURL?queryname=$1 [L]

This time around, you're capturing part of the request and changing it into a query string.

user asks for

They may think that's what they're getting-- it's what the browser's address bar says-- but behind the scenes the page content is really coming from

Now you see why Part 1 had to look at THE_REQUEST. It's for insurance. If something happens later on, your long complicated URL might pass through mod_rewrite again. If it does, you need to be sure it doesn't get re-redirected. Otherwise there will be an infinite loop.

Now wait a minute! Does this mean that if someone starts out asking for "longcomplicatedURL", they go through this whole rigamarole and then they end up right back where they started?

Yup. But they don't know it. They only know what the browser's address bar tells them. Even robots-- yes, even google-- can't tell that they're being rewritten.

The Redirect part of the package-- Part 1-- is not technically necessary. The Rewrite-- Part 2-- will function without it. But redirecting everyone to the same URL means that everyone is now on the same page ... and it avoids nasty things like Duplicate Content.

But you're not done yet.

Part 0.
Before you do anything with Part 1 and Part 2, go over your current site carefully. Make sure that your own links point only to the short pretty URL. Requests for the long complicated URL should come only from outside-- from people with outdated bookmarks, or old links from other sites. Your own site will use only the pretty URLs.


 7:23 am on Apr 13, 2013 (gmt 0)

Lucy24, thank you for your reply. Sorry for the confusing info. Since this probably a one time only for me, although I am a bit handy I am just not that well introduced to the vocabulary of Apache/htaccess. So I mixed up redirect and rewrite.

Indeed I am (was?) looking for a redirect solution. Glad that you had something lying around. I am guessing the part one will do the trick for me. Will try this today and let you know how I ended up.


 8:26 am on Apr 13, 2013 (gmt 0)

It's best to also soft-anchor the query string parameter RegEx pattern:


 8:49 am on Apr 13, 2013 (gmt 0)

Thank you for adding that, G1smd.
Well, I tried this:

RewriteCond %{THE_REQUEST} \?
RewriteCond %{QUERY_STRING} (^|&)queryname=([a-z]+)(&|$)
RewriteRule http://www.example.com/news.php?newsid=79 http://www.example.com/het-heilig-licht/%1 [R=301,L]

(as well as without %1)

Helas this does not work for me. The site redirects to the 404-page and says news.php?newsid=79 cannot be found. Which is not that strange because this page does not exist anymore: I want to forward the url to a new place/new page (I have to do that for over 150 url's).

This is what I did: my old site used another database with the ugly url. I rebuilt and filled a new database. Because I want to keep my pagerank as good as I can, and because I don't want to disappoint people who enter from an old external link/website to the not-existing page, I need the redirect.

For the static pages, the redirect was easy (successfull):
redirect 301 /the-race.php http://www.example.com/the-race/ (<-- which is actually a permalink to something like this: www.example.com/?p=123, a different page anyway)

For the dynamic pages, I of course tried (unsuccessfully):
redirect 301 /news.php?newsid=79 http://www.example.com/het-heilig-licht/ and so on.
But this is actually what I need.

Crossing my fingers for the solution.

[edited by: bill at 12:40 am (utc) on Apr 18, 2013]
[edit reason] disable smilies [/edit]


 9:24 am on Apr 13, 2013 (gmt 0)

With the additional soft anchors, the %1 should be changed to %2 in the rule target.

Don't use Redirect or Redirectmatch here. Use only RewriteRule syntax for redirects and rewrites. There can be problems if you mix mod_rewrite and mod_alias directives in the same site.

Replace queryname=([a-z]+) with newsid=([0-9]+) too.


 9:38 am on Apr 13, 2013 (gmt 0)

So, like this:

RewriteCond %{THE_REQUEST} \?
RewriteCond %{QUERY_STRING} (^|&) newsid=([0-9]+)
RewriteRule http://www.example.com/news.php?newsid=79 http://www.example.com/het-heilig-licht/%2 [R=301,L]

However, this results in a 500 internal server error.
I was not sure how to go about your comment about redirect or redirectmatch. I tried the same three lines without (R=301,L], but this also results in an internal server error.

Thanks for helping me out here

[edited by: incrediBILL at 3:35 am (utc) on Apr 18, 2013]
[edit reason] disable smilies [/edit]


 9:45 am on Apr 13, 2013 (gmt 0)

Many changes...

RewriteCond %{THE_REQUEST} \?
RewriteCond %{QUERY_STRING} (^|&)newsid=79(&|$)
RewriteRule ^news\.php$ http://www.example.com/het-heilig-licht/? [R=301,L]

The unwanted space between
(^|&) and newsid would have caused the 500 error.

[edited by: g1smd at 9:59 am (utc) on Apr 13, 2013]


 9:58 am on Apr 13, 2013 (gmt 0)

Hi there. I was going to jump for joy with the last one (I tried to find the cause of the error, but overlooked the space). However, I get the same problem as before: page not found.
Actually your solution is quite similar to the one in my first post:

RewriteCond %{QUERY_STRING} ^newsid=79$
RewriteRule ^news\.php$ http://www.example.com/het-heilig-licht/? [R=301,L]

Do I miss something? Would I need to turn something on (modrewrite, engine?).

I put the code in the .htaccess-file after the redirects from static to static (one free line).
Thanks again.


 10:00 am on Apr 13, 2013 (gmt 0)

Make sure you convert all your redirects to use RewriteRule syntax.

You do need RewriteEngine On at the start. I assumed you added that.


 10:01 am on Apr 13, 2013 (gmt 0)

Just to be sure: can you use this code for a page that does not exist? Because if the code tries to find newsid=79, it will never succeed since it is not present in my new site. The url-structure has been changed completely.


 10:01 am on Apr 13, 2013 (gmt 0)

"Make sure you convert all your redirects to use RewriteRule syntax.

You do need RewriteEngine On at the start. I assumed you added that. "

Checking that, just to be sure.


 10:13 am on Apr 13, 2013 (gmt 0)

Hmm. Well, I created a new empty .htaccess, added:

RewriteEngine On
RewriteCond %{THE_REQUEST} \?
RewriteCond %{QUERY_STRING} (^|&)newsid=79(&|$)
RewriteRule ^news\.php$ http://www.example.com/het-heilig-licht/ [R=301,L]

saved, and uploaded.
Same problem: page not found.
Any ideas left?

[edited by: incrediBILL at 3:36 am (utc) on Apr 18, 2013]
[edit reason] disabled smilies [/edit]


 10:47 am on Apr 13, 2013 (gmt 0)

What URL do you request? Use example.com for the hostname here.

What does the browser address bar say after you pressed enter?


 10:56 am on Apr 13, 2013 (gmt 0)

It goes to the 'page does not exist' (404) page that is active.
In the url the /news.php?newsid=79 is still visible.

That is why I wonder if the code tries to find that page, because that is not possible, and I would be in need for another code, as Lucy suggested.

I use Wordpress for this specific site.

I would even be happy with a code that detects search for news.php redirecting to my home, so no 404-page comes up. Anything better than a broken link or 404.

Even tried this:
RewriteCond %{REQUEST_URI} /news.php
RewriteCond %{QUERY_STRING} newsid=79
RewriteRule (.*) /het-heilig-licht/

But I guess this is not redirecting, but rewriting.
Do I need something with a rewritemap maybe?


 5:48 pm on Apr 13, 2013 (gmt 0)

As long as the redirect acts before any Wordpress rewriting code, the redirect should work.

A redirect is an instruction back to a browser to make a new request for a new URL. The browser address bar changes as this new requrst is made.

Once the browser requests the correct URL, your internal rewrite should fetch the correct page and send it out to the browser.


 8:49 pm on Apr 13, 2013 (gmt 0)

Coming in late here (different time zone):

can you use this code for a page that does not exist?

YES, absolutely, in fact that's what rewrites are all about. The server does not even look for the file until all the apache mods have done their stuff and it's time to serve up the page. (Bizarrely, this is true even when a rule is inside a <Files> or <FilesMatch> envelope. The file itself doesn't have to exist-- only its putative directory.)

Well, I created a new empty .htaccess

Uh-oh. Is this new htaccess instead of or in addition to other htaccess files in other directories either above or below the one you're working on (side-by-side doesn't matter)? mod_rewrite behaves differently from all other Apache mods in a number of ways. One of those ways is that a RewriteRule in a later htaccess-- or inside <Files> in the same htaccess-- will make the effects of any earlier RewriteRules disappear, exactly as if they never existed.

The new htaccess can't possibly be the only one you've got. Somewhere along the line you mentioned WordPress. Like any CMS you can name, it won't do its stuff without a whole set of RewriteRules of its own. So either there is a separate htaccess you've overlooked-- or you've overwritten the WordPress htaccess.

Redirects are easier to test than rewrites. You don't even need LiveHeaders or similar; you will see your browser's address bar changing. Or not changing.


 8:33 am on Apr 14, 2013 (gmt 0)

Indeed different time zone ..
Firstly; I assume the htaccess-file in the root is the first one WP uses, if any others are around. So, yes I replaced the WP-htaccess-file and put the old one back after I tested the new.
G1smd suggests that the given code should work as long as the redirect acts before any Wordpress rewriting code. However, with the htaccess-file replaced, having only this redirect-code it still does not work.

Anyway, I have several websites so - maybe daft that I have not done this earlier along the road - I tried the same code at a non-WP-site.
And yes (HURRAY!) it does work.
So I am overlooking something. It has probably got something to do with the installed security for WP. I am going to dig deeper into it and hope to find the solution why WP does not eat it.

And thank you both for the effort to this solution. I appreciate it. To pay back a little, I will write an article about this issue in Dutch as there is not much about this specific issue in my language. Maybe it helps others out.


 12:29 am on Apr 18, 2013 (gmt 0)

welcome to WebmasterWorld, WdMnl!


 4:01 pm on Apr 26, 2013 (gmt 0)

Just to keep you posted: it all worked out fine and my article will be published next week at [snip]. Thank you Lucy and G1msd.

[edited by: phranque at 12:33 pm (utc) on Apr 27, 2013]
[edit reason] no personal urls please [/edit]

Global Options:
 top home search open messages active posts  

Home / Forums Index / Code, Content, and Presentation / Apache Web Server
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved