I'm trying to rewrite the URLs on my site (to improve SEO, its an AJAX site) so that they go from
http://www.domain.co.uk/?section=home
http://www.domain.co.uk/?section=contact
to
http://www.domain.co.uk/home
http://www.domain.co.uk/contact
respectively.
This is my first time using .htaccess for rewriting, and I'm finding that I end up just guessing with my expressions/copying answers from other questions and trying to make them work.
The closest I've gotten is from adapting this answer here
RewriteEngine on
RewriteCond %{THE_REQUEST} ^GET\ /\?(([^&\s]*&)*)section=([^&\s]+)&?([^\s]*)
RewriteRule ^(.*)$ /section/%3?%1%4 [L,R=301]
RewriteRule ^section/(.*) index.php?section=$1 [L]
which gives me the result
http://www.domain.co.uk/section/contact
however this also breaks all my other links, and leaves the site without CSS or javascript etc.
Furthermore, one of the sections of my site has URLs that look like this
http://www.domain.co.uk/?section=blog&post=post-name-one
http://www.domain.co.uk/?section=blog&post=post-name-two
which I wanted to rewrite to
http://www.domain.co.uk/blog/post-name-one
http://www.domain.co.uk/blog/post-name-two
However, I'm am very unsure about how to approach this in RegEx.
Could anyone help in getting this right? If there are good references for writing these rules, I'd be happy to hear about them as well. So far the things I have read have been helpful in explaining what is happening, but I haven't been able to write my own yet.
You can use these rules in your root .htaccess:
RewriteEngine on
RewriteCond %{THE_REQUEST} \s/+\?section=([^\s&]+)&post=([^\s&]+) [NC]
RewriteRule ^ /%1/%2? [R=302,L]
RewriteCond %{THE_REQUEST} \s/+\?section=([^\s&]+) [NC]
RewriteRule ^ /%1? [R=302,L]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^([^/]+)/([^/]+)/?$ /?section=$1&post=$2 [L,QSA]
RewriteRule ^([^/]+)/?$ /?section=$1 [L,QSA]
Related
So I have been struggling on finding the rule to match this rewrite. I am working on a client website and it is a nightmare with the number of duplicate title tags. I have managed to resolve most of them by enforcing forward slash, redirect non www. to the www. version and disallow crawling of https version of the website.
The issue I am having at the moment. I have over 1000 URLs that are duplicate content, each product has two different URLs with the exact same content. An example is:
http://www.example.co.uk/product/widget1/
http://www.example.co.uk/widget1/
http://www.example.co.uk/product/widget2/
http://www.example.co.uk/widget2/
Now the following URLs have the same content:
http://www.example.co.uk/product/widget1/
http://www.example.co.uk/widget1/
I want to redirect any URL that contains "/product/" to the URL version without "/product/" in the URL if that makes sense. I honestly don't know where to start and would really appreciate the help.
Thanks in advance
EDIT: The recommended rule:
RewriteEngine On
RewriteRule ^/product/(.*)$ /$1 [R=301]
does not work. It may be conflicting. These are the other rules:
RewriteEngine On
RewriteCond %{QUERY_STRING} .+
RewriteRule ^(.*)$ /$1? [R=301,L]
RewriteRule ^/product/(.*)$ /$1 [R=301]
RewriteCond %{HTTP_HOST} ^example\.co [NC]
RewriteRule (.*) http://www.example.co.uk/$1 [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)([^/])$ /$1$2/ [L,R=301]
I dont know if there are any conflicts here. Please help
Have your full .htaccess like this:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^example\.co [NC]
RewriteRule (.*) http://www.example.co.uk/$1? [L,R=301]
RewriteCond %{QUERY_STRING} .+
RewriteRule ^(.*)$ /$1? [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+?[^/])$ /$1/ [L,R=301]
RewriteRule ^product/([^/]+)/?$ /$1/ [R=301,L]
Assuming the URLs always start with product, this should work:
RewriteEngine On
RewriteRule ^/product/(.*)$ /$1 [R=301]
It'll need to go in your main site conf or .htaccess
I have a tricky one here for the .htaccess guru!
I have a site i.e. mysite.co.uk but i dont want people to be able to go straight to the homepage of mysite.co.uk instead i redirect them to enter.mysite.co.uk a subdomain of mysite.co.uk.
Currently I have this:
RewriteEngine on
RewriteBase /
RewriteCond %{HTTP_REFERER} !^http://mysite.co.uk [NC]
RewriteCond %{HTTP_REFERER} !^http://enter.mysite.co.uk [NC]
RewriteRule ^ http://enter.mysite.co.uk [L,R]
RewriteRule ^(.*)$ proxy.php?url=$1 [L,QSA]
This does what I want it to but the problem is the redirect is turning away Google bot and all other search engines, so my question is this is there any code I can add to allow a number of the larger search engine bots/spiders to enter without having to have come from the refering url i.e. enter.mysite.co.uk
Help greatly appreciated with this im pulling my hair out and nearly bald now :)
Add a negative condition for search bots like this:
RewriteCond %{HTTP_USER_AGENT} !(googlebot|adsbot-google|bingbot|msnbot|psbot|gigabot|twitterbot|linkedinbot|yahoo-mmcrawler|pingdom\.com_bot) [NC]
RewriteCond %{HTTP_REFERER} !^http://mysite.co.uk [NC]
RewriteCond %{HTTP_REFERER} !^http://enter.mysite.co.uk [NC]
RewriteRule ^ http://enter.mysite.co.uk [L,R]
RewriteRule ^(.*)$ proxy.php?url=$1 [L,QSA]
This way your first rule won't be applicable for listed search bots.
I'm trying to come up with a rewrite rule that will work in conf files for all the environments I support (qa, stage, dev, etc), so a common rewrite condition and rule to "rule" them all.
Example:
subdomain.environment.site.com should redirect to environment.site.com
except subdomain.site.com should redirect to www.site.com.
It also shouldn't forward when some of the request URIs have stuff in them.
This is as far as I've come:
RewriteCond %{HTTP_HOST} subdomain.$ENV.site.com [NC]
RewriteCond %{REQUEST_URI} !/images
RewriteCond %{REQUEST_URI} !/blah
RewriteCond %{REQUEST_URI} !/blah-foo
RewriteCond %{REQUEST_URI} !/foo-bar
RewriteRule ^/(.*) http://$ENV.site.com/$1 [L,R=302]
Obvious the $ENV isn't going to work, but I am having a having a helluva time trying to find a proper regex to make this work in all environments.
A little more research, hand banging and beer got me the solution.
It might not be pretty but it works. Answering so if anyone ever tries to do this, they have some sort of start here.
RewriteCond %{HTTP_HOST} ^(sub)(\.)((?:[a-z][a-z]+))(\.)(site)(\.)(com) [NC]
RewriteCond %{REQUEST_URI} !/image
RewriteCond %{REQUEST_URI} !/blah
RewriteCond %{REQUEST_URI} !/foobar
RewriteCond %{REQUEST_URI} !/barfoo
RewriteRule ^/(.*) http://%3.%5.%7/$1 [L,R=302]
I'm having a lot of trouble getting my .htaccess ReWrite to work on my apache web server. I've read several tutorials and tested my regex matching with Grep.
Here is the code:
RewriteRule \?action=viewArticle&articleId=([0-9]*)&categoryId=([0-9])$ essays/$1 [R=301,L]
here is a url I'm trying to match:
http://mysite.com/?action=viewArticle&articleId=15&categoryId=1
and change to
http://mysite.com/essays/15
UPDATE: Solution! with a very excellent tutorial from Jon. It was very important that I put <base href="/"> in my header file to get the css to work correctly.
Final rewrite looked like this:
RewriteCond %{THE_REQUEST} /?action=viewArticle&articleId=([0-9]*)&categoryId=([0-9])
RewriteRule ^$ /essays/%1? [R=301,L,NE]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^essays/([0-9]+) /?action=viewArticle&articleId=$1&categoryId=([0-9]) [L]
You can't match hosts or query strings inside a RewriteRule, you need to match against the %{HTTP_HOST} and %{QUERY_STRING} variables in a RewriteCond directive:
RewriteCond %{HTTP_HOST} mysite\.com$ [NC]
RewriteCond %{QUERY_STRING} ^action=viewArticle&articleId=([0-9]*)&categoryId=([0-9])$
RewriteRule ^$ /essays/%1? [L,R=301]
This redirects the browser (changing the URL in the address bar) when someone goes to http://mysite.com/?action=viewArticle&articleId=15&categoryId=1 to http://mysite.com/essays/15
You don't need the %{HTTP_HOST} condition if your htaccess file only serves a single host.
I have a Drupal 6 multisite, with 2 domains (www.example.com and www.domain.com), sharing some common content.
The domain example.com is in three languages (EN, FR, NL). Languages are set by path prefix (/en, /fr, /nl). The other domain domain.com is just in one language (NL).
The problem: on many occasions domain.com is shown in the wrong language, even if no path prefix is filled in. Somehow it seems to default to EN, though it doesn't always do that - behaviour doesn't seem to be very consistent.
The solution (at least I hope): since I'm not a Drupal developer (I inhereted the site from a former colleague) I have no idea how to fix this in Drupal, so I thought the best way to fix it would be to add some rewrite rules to .htaccess.
I'm no htaccess/regex expert either, and can't get it working. You can find my current rewrite rules below, any help or suggestions are most welcome.
Some examples:
www.domain.com/fr/some-title needs to be rewritten to www.domain.com/nl/some-title
www.domain.com/node/1975 needs to be rewritten to www.domain.com/nl/node/1975
These are the rewrite rules that were already there:
# Rewrite URLs of the form 'x' to the form 'index.php?q=x'.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
I tried adding this:
RewriteCond %{HTTP_HOST} ^(www.)?domain.com$ [NC]
RewriteRule ^/(.*)$ /nl/$1
and would expect this just to prepend /nl/ to all paths (thus not being a full solution since /fr/some-title would become /nl/fr/some-title) - however, a quick test shows me that:
/fr/some-title is rewritten to /nl/some-title (which is what I need, but not what I expected)
/some-title is not rewritten
The question: any ideas what might be wrong? Or could this be caused by other (Drupal) settings? Or is there a better way to solve my problem?
Just for the sake of completeness: the live website is www.cinemazuid.be
If this rule
RewriteRule ^/(.*)$ /nl/$1
is in your .htaccess file, I am surprised that it works as the leading / is always stripped out, so it should theoretically never match any request.
If your desire is to force a default language of NL for those requests that do not specify a language, then add the following rules to the top of your .htaccess file, before any existing rules
#if request is for existing file or directory
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
#then stop processing
RewriteRule .* - [L]
#replace fr with nl. This rule
RewriteRule ^fr/(.*)$ /nl/$1 [L,R=301]
#if the request does not have a language of en or nl
RewriteCond %{REQUEST_URI} !^/(en|nl)/ [NC]
#redirect with nl as default language
RewriteRule .+ /nl%{REQUEST_URI} [L,R=301]
If you do not want to redirect, just drop the R=301
I edited code above to replace /fr/some-title with /nl/some-title/.
The L flag tells mod_rewrite to stop processing further rules, which is usually what you want, unless you have another rule that needs to further process the current request.
#redirect /fr/* and /en/* to /*
RewriteCond %{HTTP_HOST} ^(www\.)?domain\.com$ [NC]
RewriteRule ^(en|fr)/(.*)$ /$2 [R,L]
#internally rewrite /* to /nl/*
RewriteCond %{HTTP_HOST} ^(www\.)?domain\.com$ [NC]
RewriteCond $1 !^nl/$ [NC]
RewriteRule ^(.*)$ /nl/$1
#drupal code
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]