Rewrite url to url without html ending (.html) - .htaccess

I would like to redirect (301) all urls without .html to .html.
Example:
example.com/site should be redirected to example.com/site.html
I tried the following:
RewriteRule (.+)$ /$1.html [L,R=301]

Your rule is likely to cause a redirect loop, because it would rewrite the URL even after it has already been redirected.
In your pattern you need to make sure that the URL does not end with .html already.
You could use a negated pattern to achieve this:
RewriteRule !\.html$ %{REQUEST_URI}.html [L,R=301]
Alternatively, if you do not want to apply this for empty paths (such as in your example) or need to reuse the matches of your pattern, you could use a RewriteCondition:
RewriteCond %{REQUEST_URI} !\.html$
RewriteRule (.+)$ $1.html [L,R=301]
Note that this is a very simple example which only works for the exact case you described. This would also rewrite URLs ending with .htm to .htm.html, which might or might not be what you want.

Related

Prevent redireting for a specific URL

I'm redirecting if the url contains a specific word.
RewriteRule ^forum(/.*)?$ /homepage.html?no=%{QUERY_STRING} [R=301,L,NE,NC]
Is it possible to avoid redirecting for a specific url that has the above specific word?
E.g.
The below gets redirect
http://www.exsample.com/forum/contactus.html?ypin9001234
to
http://www.exsample.com/homepage.html?no=ypin9001234
What I need is to continue the above redirect as it is but to avoid the redirect only for the below URL.
http://www.exsample.com/forum/members/gold/gold.html?ypin9001234
Note: The word gold is used only by this url.
You should use a RewriteCond with THE_REQUEST to match full URL with query string:
RewriteCond %{THE_REQUEST} !/forum/members/gold/gold\.html\?ypin9001234 [NC]
RewriteRule ^forum(/.*)?$ /homepage.html?no=%{QUERY_STRING} [R=301,L,NE,NC]
You can add a rewrite condition before your rewrite rule, e.g.:
RewriteCond %{REQUEST_URI} !^.*gold.*$
RewriteRule ^forum(/.*)?$ /homepage.html?no=%{QUERY_STRING} [R=301,L,NE,NC]
This will prevent any url containing the word gold from being rewritten. If you need to be more specific, just make the condition more precise:
RewriteCond %{REQUEST_URI} !^forum/members/gold.*$
RewriteRule ^forum(/.*)?$ /homepage.html?no=%{QUERY_STRING} [R=301,L,NE,NC]
etcetera...

Set up of conditional redirect in htaccess

I've been asked to make an existing web site multi-language.
In preparation for this I have had to move all existing pages from /path/page to /en/path/page
To maintain any existing incoming links I now need to set up an htaccess redirect to send any requests from their original urls to the new /en/path/page urls but I'm having trouble getting this to work.
This is what I currently have;
RewriteCond %{REQUEST_URI} !^/en$
RewriteRule ^(.*)$ /en/$1 [R=301,L]
Which I think is meant to check the requested URI and if it doesn't begin with /en then prepend /en onto the requested URI... but I'm obviously mistaken since it doesn't work.
Any help appreciated. Thank you.
UPDATE.
Since this is an ExpressionEngine site and there is an additional rule to remove the index.php portion of the URL here are both rules
# Rewrite for new language based urls
# This is to try and get all current pages going to /en/(old url) with a 301 redirect
RewriteCond %{REQUEST_URI} !^/en(/.*)?$
RewriteRule ^(.*)$ /en/$1 [R=301,L]
# Removes index.php
RewriteCond $1 !\.(gif|jpe?g|png|ico)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]
I have also tried this with the language rewrite after the index.php one. I'm still getting stuck in loops.
What it does is, checking whether the URI is not exactly /en, since the $ indicates the end of the string right after en.
Try this, it checks whether the URI is not exactly /en or /en/ or doesn't start with /en/, and if that's the case it will prepend /en/:
RewriteCond %{REQUEST_URI} !^/en(/.*)?$
RewriteRule ^(.*)$ /en/$1 [R=301,L]
update Considering the other rules you have in your .htaccess file, it is necessary to have the language rule not match again for the following internal redirect to /index.php..., otherwise you'll end up with an endless loop.
There may be better ways to prevent this, however the first thing that comes to my mind would be checking for index.php in the first condition:
RewriteCond %{REQUEST_URI} !^/(index\.php|en)(/.*)?$
So this will cause the rule not to apply after the internal redirect. But be careful, this solves the problem for this specific case only in which the internal redirect goes to index.php!

mod_rewrite RewriteRule takes priority over Redirect in .htaccess

I have two different kinds of rules in my .htaccess file. The first group matches on exact files, and then I have a generic catch-all for everything else. I have read you can use the [L] for rewrite rules, but is there an equivalent for Redirect 301? For example, my .htaccess file looks like this:
Redirect 301 /exact_page.html http: //www.newsite.com/new_page1.html
Redirect 301 /some_other_page.html http ://www.newsite.com/new_page2.html
RewriteEngine on
RewriteRule ^(.*)$ http://www.newsite.com/$1 [R=301,L]
What I would like is for pages exact_page.html and some_other_page.html to be redirected exactly as shown, and everything else gets maps from the domain to the new domain, with the rest of the url intact. Instead, it looks to me like the first two Redirect 301's are being ignored, or more precisely, are being superseded by the final rule. Is there a way to tell apache to stop after it finds the first match?
I think something like this should work:
RewriteEngine on
RewriteCond %{REQUEST_URI} !^/(exact_page\.html|some_other_page\.html)$
RewriteRule ^(.*)$ http://www.newsite.com/$1 [R=301,L]
RewriteRule ^exact_page\.html$ http://www.newsite.com/new_page1.html [R=301,L]
RewriteRule ^some_other_page\.html$ http://www.newsite.com/new_page2.html [R=301,L]

.htaccess redirect - two URLs with similar paths

So here's what I have.
www.website.com/foo (pretty URL to use on marketing pieces)
www.website.com/foobar (URL that actually exists on site)
I can get www.website.com/foo working perfectly with this:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /foo [NC]
RewriteRule ^ http://www.website.com/redirected/url-goes-here/ [L,R=301]
But that makes the www.website.com/foobar URL go there as well.
I'm sure this is a regex issue and I just don't know the correct symbol to get things working properly, but how can I make /foo redirect properly without effecting /foobar ?
Thanks.
Try this instead:
RewriteCond %{REQUEST_URI} ^/foo$ [NC]
RewriteRule ^ http://www.website.com/redirected/url-goes-here/ [L,R=301]
REQUEST_URI will get rid of the extra request headers that THE_REQUEST has. Then you can match the beginning and end of the requested URL with ^ and $.
You don't need the RewriteCond. Just be specific with the RewriteRule pattern
RewriteRule ^foo$ http://www.website.com/redirected/url-goes-here/ [L,R]
See more about regular expression.
Never test with 301 enabled, see this answer Tips for debugging .htaccess rewrite rules for details.

Redirect in htaccess is adding directory to new URL; not redirecting ExpressionEngine URLs correctly

I'm trying to setup a redirect rule for a new ExpressionEngine site.
I'm using the following code placed in my site's .htaccess file (the latter section is to remove index.php from ExpressionEngine's URLs - this works):
<IfModule mod_rewrite.c>
RewriteEngine On
RedirectMatch 301 ^/2010/example/*$ http://sub.domain.com/new-page/$1
# Removes index.php from ExpressionEngine URLs
RewriteCond $1 !\.(gif|jpe?g|png)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]
</IfModule>
A redirect of sort happens, but the URL I get is this:
http://sub.domain.com/new-page2010/example/
I've tried different combinations and it's driving me up the wall!! Any tips on where I'm going wrong?
The syntax for Apache's RedirectMatch Directive expects the use of parenthesis in the RegEx:
The supplied regular expression is matched against the URL-path, and
if it matches, the server will substitute any parenthesized matches
into the given string.
Using a RedirectMatch is equivalent to Redirect, but makes use of standard regular expressions, instead of simple prefix matching.
Therefore correcting your example, a valid RedirectMatch Directive would be:
RedirectMatch 301 ^/2010/example/(.*)$ http://sub.domain.com/new-page/$1
You can tap in the full power of Apache's rewrite engine by using a RewriteRule instead:
RewriteRule ^2011/example/(.*)$ http://sub.domain.com/new-page/$1 [R=301,L]
Depending on what you're wanting to redirect — a single page vs. entire sub-directory — you may need to modify the original URL path in each example.

Resources