I have working code in .htaccess that accomplishes the following.
redirect non-www to www (and https:)
redirect http to https (and www)
allow accessing URLs ending with /file1.htm etc at /file
However, as I discovered, the third rule was more of a hack that needed to be used in combination with removing all existing links to the .htm versions (which is outside your control). As a result, Google started crawling both versions and deciding which ones are canonical.
I want to modify the third rule to not just allowing access at /file, but rewriting the URL with a 301 message. There are several answers on Stackoverflow that have worked for others that are not working for me due to existing rules in the file, so I'm posting it as a new question.
How do I add a 301 redirect to all /file.htm links to /file without breaking the 3 existing rules?
RewriteEngine On
RewriteCond %{http_host} ^example.com [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [L,R=301]
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.htm [NC,L]
Redirect 301 /output.php /
I want to modify the third rule to not just allowing access at /file, but rewriting the URL with a 301 message.
Using a 301 there makes little sense – you want to keep this one an internal redirect.
You should add a new rule, that rewrites requests for /file.htm to /file externally, and have that one use a 301 status code:
#1) externally redirect "/file.htm" to "/file"
RewriteCond %{THE_REQUEST} /([^.]+)\.htm [NC]
RewriteRule ^ /%1 [NC,L,R=301]
#2) Internally map "/file" back to "/file.htm"
RewriteCond %{REQUEST_FILENAME}.htm -f
RewriteRule ^(.*?)/?$ /$1.htm [NC,L]
Related
I have...
| .htaccess : (v1)
RewriteEngine on
RewriteRule ^in?$ login.php
So, /in --is-really--> /login.php
This much works great. We all can learn how to do this from: .htaccess redirect with alias url
But, I want it to also work in reverse...
If someone should enter /login.php into the address bar, I want it to change to /in.
So also, /login.php --rewrites-to--> /in
From this Answer to a different Question, I want to be ready for anything, using REQUEST_URI. So, my .htaccess file starts with this...
| .htaccess : (v2)
RewriteEngine on
# Remove index.php, if a user adds it to the address
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_URI} ^/(.+/)?index\.php
RewriteRule (^|/)index\.php(/|$) /%1 [R=301,L]
# "in" --> login.php
RewriteRule ^in?$ login.php
That also works great.
But now, I want to add this rule (my Question here) for /in <--> /login.php both ways, just how / <--> /index.php already works with .htaccess (v2). So, I adopted the settings and added a second rule...
| .htaccess : (v3) —not working!
RewriteEngine on
# Remove index.php, if a user adds it to the address
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_URI} ^/(.+/)?index\.php
RewriteRule (^|/)index\.php(/|$) /%1 [R=301,L]
# "in" --> login.php, and also redirect back to it
RewriteCond %{REQUEST_URI} ^/(.+/)?login\.php
RewriteRule (^|/)login\.php(/|$) /%1in [R=302,L]
RewriteRule ^in?$ login.php
...but then /in and /login.php both cause an infinite redirect loop.
What's the right way to do this, still using REQUEST_URI, and still having both rewrite rules (for index.php and for login.php)?
These Questions did not help:
Rewrite rule to hide folder, doesn't work right without trailing slash
This is not about a trailing slash
Allow multiple IPs to access Wordpress Site Admin via .htaccess
This is not about IP-based access
Htaccess URLs redirects are working for http not all https
This is not about https vs http
Rewrite-rules issues : .htaccess
This is not about cleaning up the GET array in the URL
apache htaccess rewrite with alias
This is not about rewriting the host/domain, thereby preserving the path
rewrite htaccess causes infinite loop?
This is not about www subdomain rewrites
.htaccess rewrite page with alias
This is not about rewriting "pretty" URLs nor about how to use slug settings in WordPress
Htaccess alias or rewrite confusion
This is not about simply having multiple rules with the same destination
htaccess rewrite to include #!
I'm not trying to rewrite #!
Reason of redirect loop is a missing RewriteCond %{ENV:REDIRECT_STATUS} ^$ before first redirect rule that removes index.php. Remember that RewriteCond is applicable to immediate next RewriteRule only.
Suggested .htaccess:
RewriteEngine on
# Remove index.php, if a user adds it to the address
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_URI} ^/(.+/)?index\.php$ [NC]
RewriteRule ^ /%1 [R=301,L]
# "in" --> login.php, and also redirect back to it
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_URI} ^/(.+/)?login\.php$ [NC]
RewriteRule ^ /%1in [R=302,L]
RewriteRule ^in?$ login.php [L,NC]
It won't cause redirect loop because after first rewrite to /login.php, variable REDIRECT_STATUS will become 200 and then the RewriteCond %{ENV:REDIRECT_STATUS} ^$ will stop redirect looping.
Thanks to the help from the user with the correct answer, I found that...
RewriteCond %{ENV:REDIRECT_STATUS} ^$
...doesn't go in .htaccess only once, but every time on the line before...
RewriteCond %{REQUEST_URI} ...
Need to redirect example.com/page to www.example.com/page_2. Can also be from www.example.com/page to www.example.com/page_2. I have tried
RewriteCond %{HTTP_HOST} ^(www\.)?example\.com/page [NC]
RewriteRule (.*) https://www.example.com/page_2 [R=301,L]
But that does not appear to work.
The HTTP_HOST server variable contains just the Host header, as its name suggests (eg. www.example.com), it does not include the URL-path as well (ie. /page).
You match the URL-path with the RewriteRule pattern. So, try the following instead:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www\.)?example\.com [NC]
RewriteRule ^page$ https://www.example.com/page_2 [R=302,L]
Change the 302 (temporary) redirect to 301 (permanent) only when you are sure it's working OK (if this is indeed intended to be permanent). 301s are cached hard by the browser so can make testing problematic.
Unless you have multiple domains on this account, you can remove the RewriteCond directive altogether.
I gave an old website a new CMS. Now i need a .htaccess with 3 parts, but it only works with 2 of them:
Redirect permanent
www redirect (this don't work)
url rewriting
Now i 'll explain something more.
Part 0 (only for the totality)
RewriteEngine On
Part 1 (Redirect permanent) i use to redirect the URLs of the old CMS to the content of the new one.
RewriteCond %{THE_REQUEST} !/de-old-content.html
Redirect permanent /de-old-content.html /old/content.html
Part 2 (www redirect) i use to avoid duplicate content.
RewriteCond %{HTTP_HOST} ^website.de [NC]
RewriteRule ^(.*)$ http://www.website.de/$1 [L,R=301]
Part 3 (url rewriting) to convert "old/content.html" into "index.php?adresse=old/content"
RewriteRule ^(.*)\.html$ index.php?adresse=$1 [l,qsa]
the [l,qsa] only allows to use $_GET.
Is it possible to combine this parts?
If i use Part 2 it shows the right content with
http://www.website.de/abc/def/ghi.html
but without www it redirect to
http://www.website.deabc/
I think there must be a misstake in this Part.
Thanks in advance.
Redirect is part of mod_alias, while RewriteCond and RewriteRule are part of mod_rewrite. As a consequence the RewriteCond of part 1 accually applies to the RewriteRule of part 2, which would make it not work properly.
Best to avoid using both rewriterule and redirect together.
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^website.de [NC]
RewriteRule ^(.*)$ http://www.website.de/$1 [L,R=301]
RewriteRule ^de-old-content\.html$ /old/content.html [L,R=301]
RewriteRule ^(.*)\.html$ index.php?adresse=$1 [L,QSA]
PS. to keep your sanity, use 302's while testing. Once everything is working, change them to 301's. Since you already used 301's, also clear your browser cache, so all the old 301's are removed from the browser's cache.
I have been trying to redirect old pages for my old site to the corresponding new ones with permanent redirect.
as well as redirecting www.example.com to example.com
I dont seem to able to do both on the same time
at the moment redirects works for correct links from ex www.example.com/correctlink to example.com/correctlink
but only example.com/Info.aspx is redirected to example.com/about-magento-demo-store and NOT www.example.com/Info.aspx
*Update
I want to remove www. AND redirect 40-50 specific adress to new specific adresses. My problem is that the redirect only works if google has saved the old link without Www. IF google has stored a link including www. then my redirect Redirect permanent example.com/tabid/61/CategoryID/13/ProductID/64/Default.aspx /index.php/solpaneler/re does not function –
*Update
my htaccess looks a bit like this
(with a few lines in the end that where present before I started editing)
(i also tried to ad a line Redirect permanent http://www.example.com/Info.aspx http://example.com/about-magento-demo-store but it does not function)
RewriteEngine On
RewriteCond %{HTTP_HOST} ^example\.com
RewriteRule ^(.*)$ http://example.se/$1 [R=301,QSA,L]
Options +FollowSymLinks
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteCond %{HTTPS}s ^on(s)|
RewriteRule ^ http%2://%1%{REQUEST_URI} [L,R=301]
Redirect permanent /Info.aspx /about-magento-demo-store
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteRule .* index.php [L]
Just use rewrite rules for everything. Rewrite rules and Redirect don't always mix well.
RewriteRule ^Info\.aspx$ /about-magento-demo-store [L,R=301]
I've had the same problem a looooooooong time ago. Here's a sample of my rewriterules:
# If domain name doesn't end with .com redirect to .com:
RewriteCond %{HTTP_HOST} (.*)\.(fr|net|org|eu) [NC]
RewriteRule (.*) http://%1.com$1 [R=301,L]
# If domain name without "www", add them:
RewriteCond %{HTTP_HOST} ^mydomainname\.(fr|com|net|org|eu) [NC]
# Ca signifie forcément que c'est sans www => forcer redirection :
RewriteRule (.*) http://www.mydomainname.%1$1 [QSA,R=301,L]
NB: Put this on the top of your rewrite rules, because it should be processed before anything else so that you are sure your domain name always begin with "www"
Note that it redirects mydomainname only if it's "empty" i.e. nothing behind. It won't touch URLs like http://abc.mydomainname.com and it won't touch URLs like http://abc.def.mydomainname.com
Tell me if it works.
I use URL rewriting on my redesigned website to give my pages tidier URLs.
RewriteEngine On
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^$ index.php [L]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^.+/$ %{REQUEST_URI}index.php [L]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^(.+\.php|(.+/)?index)$ - [R=404,L]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{SCRIPT_FILENAME}.php -f
RewriteRule ^(.+)$ $1.php [L]
This .htaccess file allows /filename to actually point to /filename.php. It all works fine.
However, I have now realised that I should set up 301 permanent redirects, so that the pages of the old website (before the redesign) can redirect to pages on the new site (for SEO and linking reasons). The pages have been reorganised, so multiple old pages will redirect to new pages, for example.
The old website did not use URL rewriting. Therefore, I want to create permanent redirects such as /about-page.php to /about, doing them manually with one rule per old page.
I have tried several things, such as...
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^about-page.php$ about [R=301,L]
...or...
Redirect 301 /about-page.php /about
...but it always ends up either not working at all (giving me a 404 error when I attempt to access /old-filename.php, or breaks everything with internal server errors. It seems to work fine if I use Redirect 301 /about-page.html /about instead, but unfortunately the old URLs used .php extensions, not .html extensions.
I believe the problem is related to one of the other rules, which redirect requests for /xyz to /xyz.php, possibly creating some endless loop. But I can't figure out how to fix it.
Any advice? Thank you very much.
Edit: Final, working .htaccess file:
DirectoryIndex index.php #
RewriteEngine On
# -- Use a permanent redirect to point the old page to the new page.
# -- The RewriteCond is needed, or a redirect loop happens in certain cases.
# -- The full URL seems to be needed, or it redirects incorrectly.
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^about-page.php$ http://www.mywebsite.com/about [R=301,L]
# -- Redirect most other .php files to a 404 error, to avoid duplicate content.
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^(.+\.php|(.+/)?index)$ - [R=404,L]
# -- Redirect requests without an extension, but for a valid file, to that file.
# -- I'm not sure what the RewriteCond lines are for, but they both seem necessary.
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{SCRIPT_FILENAME}.php -f
RewriteRule ^(.+)$ $1.php [L]
DirectoryIndex index.php # -- this sets index.php to be default file for a folder
RewriteEngine On
# -- RewriteRule ^(.+\.php|(.+/)?index)$ - [R=404,L]
# -- dude this above line redirects all php files to 404 error
# -- so delete this, its a problem not solution
RewriteCond %{SCRIPT_FILENAME}.php -f
RewriteRule ^(.+)$ $1.php [L]
RewriteRule ^about-page.php$ /about [R=301,L]
This should work, comment if problem occurs