2

I am trying to both rewrite and redirect this URL:

https://www.domain.com/video-lessons-page.php?item=stocks

to go to this URL:

https://www.domain.com/stocks-video-lessons

Here is the code I'm currently working with:

RewriteCond %{QUERY_STRING} ^item=([^&]+)
RewriteRule ^/?video-lessons-page\.php$ https://www.domain.com/%1-video-lessons? [R=301,L]
RewriteRule ^(stocks|finance|accounting)-video-lessons$ video-lessons-page.php?item=$1 [NC,L]

Unfortunately with the above code I'm having issues. The first two lines work great by themselves in that it redirects /video-lessons-page.php?item=stocks to /stocks-video-lessons.

And the third line also works great by itself to where the /stocks-video-lessons URL functions correctly with the GET variable and the page's code.

But putting them together is problematic. Right now I'm getting errors like "www.domain.com redirected you too many times." etc. Any ideas?

2 Answers 2

1

Just to clarify, presumably you have already changed all your internal URLs to the form /stocks-video-lessons and the reason for the external redirect is because the "ugly" URLs have already been indexed and linked externally?


As you have found, you are getting a redirect loop because these two rules conflict and it's constantly redirecting/rewriting from one to the other.

You need to redirect when only the initial request contains the URL /video-lessons-page.php, not the rewritten URL (which is what's happening here). You can check the initial request by checking against THE_REQUEST server variable (which contains the full HTTP request as sent by the browser).

Something like the following:

RewriteCond %{THE_REQUEST} /video-lessons-page\.php?item=(\w+)
RewriteRule ^video-lessons-page\.php$ https://www.example.com/%1-video-lessons? [R=301,L]

RewriteRule ^(stocks|finance|accounting)-video-lessons$ video-lessons-page.php?item=$1 [L]

Note you must clear your browser cache before testing, since 301 (permanent) redirects will be cached by the browser. (Often easier to test with 302 redirects.) Only use the NC flag if you specifically need a case-insensitive match.

UPDATE: I've changed the regex on the query string parameter value, from ([^&]+) to the slightly more restrictive (\w+). \w being the shorthand character class for a word character (which naturally excludes & and crucially spaces). Since THE_REQUEST contains a string of the form:

GET /video-lessons-page.php?item=stocks HTTP/1.1

...we need to stop capturing before the space. The previous pattern ([^&]+) would have captured everything to the end of the string ie. "stocks HTTP/1.1". So, I would have expected a 404, since an invalid redirect would have occurred but the internal rewrite would have failed. (?)

Sign up to request clarification or add additional context in comments.

2 Comments

Yes the ugly URLs have already been indexed. That all actually makes a ton of sense, thank you for your help. For some reason though with the code you have, the actual redirect isn't happening from /video-lessons-page.php?item=stocks to /stocks-video-lessons. It just stays on the ugly URL. I do refresh my cache each time.
Ah ok, yes, indeed... the regex on the query string parameter value needs to be updated when used to match against THE_REQUEST - I've updated my answer. However, I would have expected a 404, rather than a failure to redirect?
0

Thanks to w3dk's guidance, I figured it out, just needed a QUERY_STRING to stay in place in addition to the THE_REQUEST.

Final code:

RewriteCond %{THE_REQUEST} video-lessons-page\.php
RewriteCond %{QUERY_STRING} ^item=([^&]+)
RewriteRule ^video-lessons-page\.php$ https://www.example.com/%1-video-lessons? [R=301,L]
RewriteRule ^(stocks|finance|accounting)-video-lessons$ video-lessons-page.php?item=$1 [L]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.