The WordPress directives are at the bottom of the .htaccess
file, while I've put mine at the top.
That is correct.
RewriteCond %{HTTP_REFERER} domain.tracker.com [NC]
There is nothing actually wrong with the RewriteCond
directive you posted that would prevent this from working. The condition is successful if the HTTP Referer
header contains the string "domain.tracker.com" (case-insensitive). That's it, there is nothing more to it. Bear in mind that the CondPattern is a regex, so the dots (.
) need to be backslash-escaped in order to match literal dots, otherwise they match any character (which is the case in your example). So, your directive is potentially matching too much, but it's not going to stop it from working. eg. It would also match an HTTP Referer of the form: http://example.com/domain-tracker-com/foo
.
The most common cause of such a condition not working is when the HTTP_REFERER
does not contain what you expect. As you are no doubt aware, the Referer
header is notoriously unreliable: it can be blocked by the client and/or website and is easily faked. Although your test appears to show the Referer
being passed as expected, so that is a mystery.
RewriteRule article-1 www.another-site.com/article-1 [R=301,L,NC]
HOWEVER, the RewriteRule
substitution (ie. www.another-site.com/article-1
) is invalid in this context and will not result in the redirect as stated, ie. to the external host www.another-site.com
. You are missing the required scheme (eg. http
) and should be of the form: http://www.another-site.com/article-1
. In other words, an absolute URL.
(I wondered if this was simply a typo in your question, since you had used an absolute URL in a related question on SO, but you appear to have confirmed in comments that it is correct as written.)
When the RewriteRule
substitution does not start with a scheme (http
or https
) or slash (/
) then it is seen as a relative URL-path. In per-directory .htaccess
files, that means that it is seen as relative to the filesystem directory that contains the .htaccess
file, which is called the "directory-prefix" (unless a RewriteBase
directive states otherwise or the directives are being "inherited"). This directory-prefix is added back to the substitution at the end of the rewriting process. In the case of the above RewriteRule
this would most probably result in a wholly invalid redirect of the form:
http://example.com/home/user/public_html/www.another-site.com/article-1
Where /home/user/public_html/
is the directory-prefix, ie. the absolute filesystem path of the location of the .htaccess
file. example.com
is the current host (probably the Host that has been requested). www.another-site.com/article-1
is the relative URL-path as stated in the RewriteRule
substitution.
As stated above, you need to include the scheme/protocol to form an absolute URL:
RewriteCond %{HTTP_REFERER} domain\.tracker\.com [NC]
RewriteRule article-1 http://www.another-site.com/article-1 [R=301,L,NC]
Also note that the regex article-1
matches the string "article-1" anywhere inside the requested URL. eg. /foo-article-1-bar/
would also match. If you are matching a specific URL then you should match that specific URL, eg. ^article-1$
. If the URL-path on the destination site is the same, then you can avoid repetition by capturing the URL-path and using a backreference in the RewriteRule
substitution. For example:
RewriteRule ^(article-1)$ http://www.another-site.com/$1 [R=301,L,NC]
Why are the conditions not working?
From the information given, there is no reasonable explanation.
Could it be a conflict with WordPress instruction?
By placing these directives before the WordPress front-controller you have pretty much eliminated that possibility.
Could it depend by the hosting provider?
That is very unlikely.
Try this with a simple query string instead:
RewriteCond %{QUERY_STRING} ^bar=1$
RewriteRule ^(foo)$ http://example.com/$1 [R,QSD,L]
Request:
/foo?bar=1
And you should be temporarily (302) redirected to:
http://example.com/foo
ie. the same URL-path, but with the query string removed.