How to combine htaccess 301 rules properly - .htaccess

To my knowledge, htaccess files are parsed from "top down".
So I tried this:
Define some explicit URL redirects.
Redirect 301 /de/category/product.html http://shop.de/category/productnewurl
...
...
And additionally remove all /de/ from all other URLs not explicitly caught above with the below "catch all" statement.
RewriteRule ^de((?:(?:\s*|/.*)$)) $1 [L,R=301,QSA]
For some reason this is not working. I tried to move the above catch all directive before and after the explicit URL redirects. Both without success.
Additionally, while the "catch all" directive is active, none of the explicit url redirect work any longer. What am I overseeing?

Redirect is from mod_alias module and RewriteRule is from mod_rewrite module. It is not a good idea to mix both directives together as these modules are invoked at different times by Apache engine.
Better stick to mod_rewrite rules:
RewriteEngine On
RewriteRule ^de/category/product\.html$ http://shop.de/category/productnewurl [L,NC,R=301]
RewriteRule ^de((?:(?:\s*|/.*)$)) $1 [L,NC,R=301]

Related

Keeping existing 301 redirects along with wildcard redirection

I have manually redirected some URLs from domainA to domainB like this
Redirect /abc123 https://domainB.com/abc/?page_url=12
If any user enters domainA/abc123, they ll land on domainB.com/abc/?page_url=12
Now, I want to implement a wildcard redirect like this
RewriteCond %{HTTP_HOST} !domainB.in$ [NC]
RewriteRule ^(.*)$ https://domainB.in/something/?page_url=1&eid=$1 [L,R=301]
where user can add any string after domainA.com/STRING and that will be passed to domainB.com/something/?eid=STRING
How can I keep the existing manual redirects along with the wildcard redirect without conflict? If writing if-else condition in htaccess is possible, how can I achieve that?
Redirect is a mod_alias directive and RewriteRule is a mod_rewrite directive. Different Apache modules run independently and at different times during the request. mod_rewrite will run first, despite the apparent order of directives in the config file. You should avoid mixing redirects from both modules in the same config file to avoid such conflicts.
Convert your existing Redirect directives to use mod_rewrite instead and make sure the most specific redirects are first.
For example:
RewriteEngine On
# Specific redirects
RewriteRule ^abc123$ https://domainB.com/abc/?page_url=12 [R=302,L]
# General redirect
RewriteCond %{HTTP_HOST} !domainB\.in [NC]
RewriteRule (.*) https://domainB.in/something/?page_url=1&eid=$1 [R=301,L]
Note that the Redirect directive you posted, that did not explicitly state the status code, would have defaulted to a 302 (temporary) redirect.
However, it is always preferable to test with 302 (temporary) redirects to avoid caching issues.

htaccess redirect all pages ending with .html to without html Except some pages

I'm having an issue with my .htaccess rules for redirection.
I need to redirect pages ending with .html to the pages ending with slash.
/about-us.html to /about-us/
But there are also pages where I need to redirect to specific page without .html like
/gallery/first-gallery/this-is-the-gallery.html to /gallery/new/
The problem is that my rules are not working together nicely, it seems that the rule to redirect .html pages ignores all other rules.
This is how my .htaccess looks like
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^/?(.*).(html)$ /$1 [R=301,L]
Redirect 301 /about-us/photo-gallery/17577-album-mca-corona-clay-tile-roof-princeton-texas/131173-58e29f485064eprinceton-texas-roofing-services-1.html /about-us/photo-gallery/17577-album-mca-corona-clay-tile-roof-princeton-texas/
Redirect 301 /about-us/photo-gallery/17577-album-mca-corona-clay-tile-roof-princeton-texas/131174-58e2a063b8b06princeton-texas-roofing-services-2.html /about-us/photo-gallery/17577-album-mca-corona-clay-tile-roof-princeton-texas/
#Many other 301 rules below
</IfModule>
So when I type in domain.com/about-us/photo-gallery/17577-album-mca-corona-clay-tile-roof-princeton-texas/131173-58e29f485064eprinceton-texas-roofing-services-1.html in the browser it redirects to domain.com/about-us/photo-gallery/17577-album-mca-corona-clay-tile-roof-princeton-texas/131173-58e29f485064eprinceton-texas-roofing-services-1 where I need this specific redirect to redirect to /about-us/photo-gallery/17577-album-mca-corona-clay-tile-roof-princeton-texas/
I tried moving the RewriteRule ^/?(.*).(html)$ /$1 [R=301,L] to the bottom hoping that the rules above will process first, but that did not work.
What can I do to make this work as I need it?
First of all if there are mod_alias like redirect and mod_rewrite like RewriteRule mod_rewrite rules get executed before mod_alias rules.
There are many senarios to sove this issue like excluding all other redirect rules from the main rewriterule but it think if the other rules redirect have same target to only ommit last part of URI you could make rules like the folwoing :
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^([^\/]+)/([^\/]+)/([^\/]+)/([^\/]+)\.(html)$ /$1/$2/$3 [R=301,L]
RewriteRule ^(.*)\.(html)$ /$1 [R=301,L]
</IfModule>
Rules above will check if URI is coming in this form /something/something/something/something.html like /about-us/photo-gallery/17577-album-mca-corona-clay-tile-roof-princeton-texas/131173-58e29f485064eprinceton-texas-roofing-services-1.html then redirect it into /something/something/something and if not coming in this way , the second rule will be applied.
Note: clear browser cache then test

Try to Fix 301 Redirect of a Dynamic URL | Not Working

I'm trying to 301 redirect the URL /topics/blog/dot-net/?page_id=386 to http://www.example.com/dot-net.
I have tried like below:
Redirect 301 /topics/blog/dot-net/?page_id=386 http://www.example.com/dot-net
Above will not work i was sure but just tried.
And this one:
RewriteCond %{THE_REQUEST} ^(GET|POST)\ /topics/blog/dot-net/?page_id=386(.*)\ HTTP
RewriteRule ^ /dot-net? [R=301,L]
If you know something about this issue. How i could fix this in .htaccess please give me a suggestion.
A mod_alias Redirect cannot be used to match against the query string. Your mod_rewrite attempt potentially should work. There might be a caching issue (from previous failed attempts). However, if you just want to redirect the stated URL then it can be written something like:
RewriteEngine On
RewriteCond %{QUERY_STRING} ^page_id=396$
RewriteRule ^topics/blog/dot-net/$ /dot-net? [R=302,L]
It is more efficient to check the URL-path in the RewriteRule pattern, rather than use a generic catch-all.
You would only need to check against THE_REQUEST if you needed to prevent a rewrite loop - but this is not stated in your question.
Change the 302 (temporary) to 301 (permanent) when you are sure it's working OK.

redirect 301 not working properly in .htaccess

htaccess 301 redirect. I have this old site which is for example http://test.org/conference I want to redirect it to conference.test.org
What happened is the 301 redirect in my .htaccess file is quite buggy.
Here is my 301 redirect htaccess code below:
RewriteCond %{REQUEST_URI} ^/http://test.org/conference(/)?
RewriteRule ^(.*)$ http://conference.test.org/? [R=301,L]
When I test this one it runs and redirects correctly. But when I test it over and over again. It seems not to redirect anymore.
Can someone help me have a htaccess 301 redirect code?
Any help is much appreciated.TIA
I assume this is what you are looking for:
RewriteEngine on
RewriteRule ^conference/?$ http://conference.test.org/ [R=301,L,QSA]
Please note that %{REQUEST_URI} only contains the path of the URI, so not the protocol and the hostname. Reason is that the evaluation is performed inside a http host. This is explicitly pointed out in the documentation: http://httpd.apache.org/docs/current/mod/mod_rewrite.html
Depending on your http hosts setup you might also have to add a condition to prevent an endless redirection loop:
RewriteEngine on
RewriteCond %{HTTP_HOST} !^conference\.test\.org$ [NC]
RewriteRule ^conference/?$ http://conference.test.org/ [R=301,L,QSA]
But usually that is not required, since the rule should be defined inside the test.org http host...

.htaccess rewrite conflicting rules

I'm having an issue with some htaccess rules which I thought would be simple. I have some nice SEO friendly URL rewriting in place as below
RewriteEngine On
RewriteCond %{REQUEST_URI} !^(index\.php|/images|/templates|/views|/ajax|/uploads|/robots\.txt|/sitemap\.xml|/favicon\.ico|/scripts|/cron|/combine.php|/js|/css)
RewriteRule ^(.*)$ index.php?ref=$1&%{QUERY_STRING} [L]
This all works well and I want to keep this. I also wish to rewrite some old pages which Google WMT is reporting as 404's to the new equivalent and for that I'd like to use:
Redirect 301 /about_us http://example.com/about-us
The problem I have is that the URL that the browser is directed to is:
http://example.com/about-us?ref=about_us
The about_us is the old link and about-us is the correct link. If the htaccess redirected to example.com/about-us then the other SEO friendly rewrite rule will pick it up and show the page but eh extra ?ref= parameter is confusing it. I am guessing the two rules are conflicting to a degree but is there a way to get the two rules to work together e.g. redirect without the extra ?ref= parameter? My knowledge of htaccess is basic to say the least so I am a little stuck on this one.
Thanks in advance
Redirect and RedirectMatch are part of mod_alias, while the rewrite rules are part of mod_rewrite. The problem you're running into is when you mix the two, both modules affect the same request, thus two things happen when you only want one. In this case, you need to stick with just mod_rewrite and use this instead:
RewriteEngine On
RewriteRule ^about_us /about-us [L,R=301]
RewriteCond %{REQUEST_URI} !^(index\.php|/images|/templates|/views|/ajax|/uploads|/robots\.txt|/sitemap\.xml|/favicon\.ico|/scripts|/cron|/combine.php|/js|/css)
RewriteRule ^(.*)$ index.php?ref=$1&%{QUERY_STRING} [L]
Note that the rule that redirects comes before the rule that routes to index.php.

Resources