htaccess rewrite url by matching only the first part of the url - .htaccess

I've been struggling to find a solution to this very simple problem. You would think that this is the classic "please help me I need to redirect this url to newurl" type of thing but, believe me, it isn't that easy.
I have a domain example.com, this example.com has some language variants:
example.com/mx
example.com/us
example.com/ca
example.com/cl
example.com/xx
and so on, example
.com is the index to choose between countries and it exists too but has no content.
We recently moved our example.com/mx to a whole new domain (with a different system) example.com.mx so we proceeded to permanently redirect every url there to the its new url in the example.com.mx
While we were at it, we discovered that our multilingual wordpress installation on example.com was duplicating all website's content in the root file, something which shouldn't have happened.
So, we have like
example.com/us/folder
example.com/cl/folder
example.com/ca/folder
etc
AND
example.com/folder which shouldn't exist
There are tons of directories that are duplicated there, we already know where to redirect each of these directories but we just can't find the right line of code to do it.
For example, we have set up this htaccess rule to deal with all the /mx/ folder, which works well:
RewriteRule ^mx/shop/ https://www.example.com.mx/? [L,R=301]
RewriteRule ^mx/home/ https://www.example.com.mx/? [L,R=301]
RewriteRule ^mx/page/ https://www.example.com.mx/? [L,R=301]
RewriteRule ^mx/tag/ https://www.example.com.mx/? [L,R=301]
But when trying to extend this same logic to the "/shop/" directory, it matches the same directory in EVERY country folder, something we obviously don't want.
This is what we tried, described previously:
RewriteRule ^/tag/ https://www.example.com.mx/newtagurl? [L,R=301]
This obviously also redirects example.com/ca/tag/, because the ^.
So my question is, how to properly redirect to these cases ONLY matching the beginning https://example.com/tag/ string instead of matching every /tag/ case in every country folder?
Thanks!

Related

Subdomain in .htaccess file only works with index

I have a subdomain setup in my .htaccess, which only seems to work with the default index.html page. I'd LIKE it to work for ANY page in the folder corresponding to the subdomain. Edited for privacy, assume my domain is example.org. The pertinent parts of the file look like this...
#subdomain
RewriteCond %{HTTP_HOST} ^subname\.example\.org$ [OR]
RewriteCond %{HTTP_HOST} ^www\.subname\.example\.org$
# (a few lines added by my hosting company deleted -- see below)
RewriteRule ^/?$ "http\:\/\/example\.org\/subname\/" [R=301,L]
So the result of the above is that if I have an index.html page in my 'public-html' (root?), http://example.org and a different index.html stored in a sub-folder (having the same name as the subdomain), I will get this expected result, which works...
browse to: http://example.org results in viewing http:// example.org/index.html
browse to: http://subname.example.org results in viewing http:// example.org/subname/index.html
Great so far. This is what I expected when I created the domain name. However, given a specific file myfile.html stored in the subname folder, I would expect this to work also, and it doesn't...
browse to: http://subname.example.org/myfile.html results in a 404 error.
This despite the fact that browsing to http://example.org/subname/myfile.html works fine. In that case myfile.html is displayed. So is there anything I can do to modify the subdomain code to get the result I'm looking for? Namely, browsing to http://subname.example.org/ANYFILE should work as well as browsing to http://example.org/subname/ANYFILE, regardless of what 'ANYFILE' is. This, after all, is one of the main reasons I set up the subdomain to begin with!
Note: I confess that I relied on my hosting company's cPanel utility to create the subdomain code, so I asked for their tech support for help first. Long story short they didn't. Maybe what I hoped for is not actually possible?
Also, the lines I deleted' from the code had to do with something called "well-known/acme-challenge", added by my hosting company at some point. Since removing them had no effect on the behavior I've described, I left it out to avoid clouding the issue.
RewriteRule ^/?$ "http\:\/\/example\.org\/subname\/" [R=301,L]
This only "redirects" the document root. To redirect all URLs you need to change the above to read something like:
RewriteRule (.*) http://example.org/subname/$1 [R=301,L]
The $1 backreference refers to the URL-path captured in the RewriteRule pattern, ie. (.*).
No need to backslash-escape the colons, slashes and dots in the substitution string (that's typical of cPanel).
Also, the lines I deleted' from the code had to do with something called "well-known/acme-challenge", added by my hosting company at some point.
Those lines will likely be required when the (Let's Encrypt?) SSL cert auto-renews. (Although the above redirects to "http" - are you not using HTTPS?)
UPDATE:
RewriteCond %{HTTP_HOST} ^subname\.example\.org$ [OR]
RewriteCond %{HTTP_HOST} ^www\.subname\.example\.org$
Just as an aside, these two conditions could be reduced to a single condition if you wanted. For example, the above is equivalent to:
RewriteCond %{HTTP_HOST} ^(www\.)?subname\.example\.org$

Eliminate duplicate directory name in url using .htaccess file

For some reason, I'm getting duplicate directory names in some urls within a subfolder on our website. This seems to affect only crawlers as the files within this directory work fine when navigated.
I'd like to simply remove the duplicate directory name and make mydomain.com/sub/sub redirect to mydomain.com/sub.
I've tried many versions but my .htaccess skills are lacking apparently. I currently have (not working of course):
RewriteRule ^mydomain.com/sub/sub/(.*) mydomain.com/sub/$1 [L,R=301]
RewriteRule ^mydomain.com/sub/sub/(.*) mydomain.com/sub/$1 [L,R=301]
The RewriteRule pattern matches against the URL-path only - you appear to have included (part of) the domain name. Also, mydomain.com in the substitution string is going to be seen as a relative subdirectory.
Assuming you have a limited number of subdirectories where this occurs then to reduce /sub/sub/<something> to just /sub/<something> you would do something like this:
RewriteEngine On
RewriteRule ^sub/sub/(.*) /sub/$1 [R=301,L]
If you have other directives in you .htaccess file, then this needs to go near the top.
First test with 302 (temporary) redirects to avoid potential caching issues. Clear your browser cache before testing.
But to echo #arkascha's comment... the reason why crawlers are finding these URLs in the first place would seem to be a fault in your URL structure/internal links - so this is what ultimately needs to be fixed.

Rewrite Subdomain To non-existing Subdirectory

post edited with better current example.
I am looking for the best way to redirect my subdomains to subdirectories which do not really exist as subfolders.....
in a nutshell, the script I am using for a website allows for setting up geographic regions as subdomains..... but each region MUST have a unique subdomain and I really do not want to have 3-level subdomains (state, city, neighborhood) for my regions and the "big boys" in my niche all opt to use a single subdirectory (like /neighborhood-city,state/) so I am looking for the best way to point my subdomains to subdirectories, although they do not actually exist....
I currently have this in the htaccess as a rewrite:
RewriteRule ^/?([0-9]+)/([^./\\"'?#]+)\.html$ index.php?a=5&b=$1 [QSA,L] ##category
which rewrites to the url to: mydomain/cat#/catname.html
I want the URL/links to have this non-existing "region" subdomain-as-subdirectory added after the /catname/ but not sure how to modify this rewrite so that instead of having:
subdomain.mydomain/cat#/catname.html
I would have:
mydomain/cat#/catname/subdomain(value).html
The not found error is normal because you redirect your subdomains to nonexistents directories, which are not rewrited. Besides your redirection, you have to rewrite these directories so that the server knows where it can find the real files. So, try this code :
RewriteEngine On
RewriteRule ^([^/]+)/(.*)$ http://$1.domain.com/$2 [L]
Of course, you have to change this path to the good.

How do I do a htaccess rewrite to another folder for a single file?

We moved a part of our site from one sub folder to another. I want to put permanent redirects (301) into htaccess for the files in this folder (some have changed their filename as well, so I can't just setup one rule for the whole folder). Here's what I'm trying
RewriteRule ^search/tutorial-search.html$ db/tutorial.php [R=301]
This doesn't work though, I get a 404 response when now entering the old URL. I find this curious as I had a rule in place for ages that does work, which looks like this:
RewriteRule ^search/tutorial-search.html$ search/tutorial-search.php
I really don't see the big difference. I also tried the following (among others) but it doesn't work either
RewriteRule ^search/tutorial-search.html$ db/tutorial.php
What exactly is causing this to fail? Just to make sure I put all of these at the exact same line of the htaccess file. Is it because I'm rewriting to another folder? Thanks :)
Try adding a leading slash to your rewrite targets, because when redirecting, apache could be mistaking a URL-path with a file-path.
RewriteRule ^search/tutorial-search.html$ /db/tutorial.php [R=301]

.htaccess Rewrite Based on Existence of Path in URL

Here's the scenario, I have a website that used to be a static HTML site and WordPress blog using a subdomain (http://blog.domain.com).
I recently combined everything into a single WordPress installation. To maintain old links I had to rewrite requests like "http://blog.domain.com/index.php/2010/10/16/post-name" to "http://domain.com/index.php/2010/10/16/post-name". My problem is that when trying to visit just "http://blog.domain.com", I get redirected to "http://domain.com" when I want it to go to "http://domain.com/index.php/blog".
So, if a user requests "http://blog.domain.com" (by itself, with or without slash), I want it to go to "http://domain.com/index.php/blog". If they request an old URL of "http://blog.domain.com/some-link-to-a-post", I want it to redirect to "http://domain.com/some-link-to-a-post". In other words, if it's a URL to an actual post, I just want to strip the "blog" subdomain. If it's the old link to the main blog page, I want to remove the "blog" subdomain and append "/index.php/blog"
http://blog.domain.com/ -> http://domain.com/index.php/blog
http://blog.domain.com/index.php/2010/10/16/post-title -> http://domain.com/index.php/2010/10/16/post-title
Hopefully that's clear. I'm not an htaccess expert, so hopefully someone can help me out here. Thanks in advance!
Using the [L] command at the end of a rewrite will tell htaccess that this is the last rule it should match. If you put a rule to match your first condition at the top and the other rewrite rule you said you had already created after it, you should get your expected result.
Try this:
RewriteRule ^blog.domain.com(/?)$ domain.com/index.php/blog [L]
# Your other rewrite here #
I couldn't get that solution to work. However, I used the following:
RewriteCond %{HTTP_HOST} ^blog\.domain\.com$ [NC]
RewriteRule ^(.*)$ http://domain.com/index.php/blog/$1 [R=301,L]
That ends up in a URL like http://domain.com/index.php/blog/index.php/2010/06/04/post-title, but Wordpress is smart enough to fix it.

Resources