Rewriting a specific URL: adding a subdirectory - .htaccess

I am working on a WordPress-site and I have an URL like
https://example.com/technische-uebersetzungen
What I need is:
https://example.com/subdirectory/technische-uebersetzungen
My code has a bug, it does not rewrite the URL. I placed it at the end of the existing .htaccess file.
RewriteEngine On
RewriteRule ^technische-uebersetzungen/(.*)$ /blog/technische-uebersetzungen/$1 [R=301,NC,L]
Does anybody know, what is that bug?

My code has a bug, it does not rewrite the URL. I placed it at the end of the existing .htaccess file.
One "bug" is placing that rule at the end of the .htaccess file. By placing the rule after the WordPress code block, the request is first rewritten to index.php and your rule is never processed.
This "redirect" needs to go at the top of the .htaccess file, before the WordPress code block (ie. before the # BEGIN WordPress comment marker).
RewriteRule ^technische-uebersetzungen/(.*)$ /blog/technische-uebersetzungen/$1 [R=301,NC,L]
This rule matches /technische-uebersetzungen/<anything> (note the mandatory trailing slash after the first path segment) and the <anything> part is copied onto the end of the target URL. This is not mentioned in your example.
Your example URL is for /technische-uebersetzungen exactly (no trailing slash). And nothing is appended to the end of the target URL.
Try the following instead at the top of the .htaccess file:
RewriteRule ^technische-uebersetzungen(/.*)?$ /blog/$0 [R=301,NC,L]
This will match /technische-uebersetzungen or /technische-uebersetzungen/<anything> and redirect to the same URL with a /blog/ prefix.
NB: You must test this first with a 302 (temporary) redirect to avoid any potential caching issues and only change this to a 301 (permanent) redirect - if that is the intention - once you have confirmed this works as intended.

Related

getting a internal server error on redirect 301

My old page url looks like this
https://blabla.com/us/sample-data/us/
my new url looks like this
https://blabla.com/us/data/sample/us/
I added this into my htaccess
<IfModule mod_rewrite.c>
Redirect 301 ^sample-data/us/ /data/sample/us/ [NC,L]
</IfModule>
but i'm getting a internal server error
the 1st us in the url is dynamic depending on country user is from. and the 2nd us is the countries sample data. which is a list of 10 countries at the moment. could be more.
i tried
RewriteRule ^sample-data/us/ /data/sample/us/ [L,R=301,NC]
but no luck either. it redirects too
https://blabla.com/data/sample/us/ missing the 1st /us/
how do get this redirect working? Thanks
<IfModule mod_rewrite.c>
Redirect 301 ^sample-data/us/ /data/sample/us/ [NC,L]
</IfModule>
but i'm getting a internal server error
Because that directive is syntactically invalid. The [NC,L] argument is a parameter belonging to the mod_rewrite RewriteRule directive. Redirect is a mod_alias directive - there is no such "flags" parameter with the Redirect directive.
RewriteRule ^sample-data/us/ /data/sample/us/ [L,R=301,NC]
but no luck either. it redirects too
https://blabla.com/data/sample/us/ missing the 1st /us/
You appear to be missing the 1st /us/ (virtual path segment) from your directives, so I don't see how this is redirecting at all (unless you are seeing a cached response, or something else is performing the redirect)? This .htaccess file is presumably in the document root and you are presumably requesting the URL /us/sample-data/us/ and the first /us/ is virtual - so the directive above cannot possibly do anything?
If the first path segment is variable and you need to redirect to the same path segment and assuming this consists of two lowercase a-z letters then try the following instead:
RewriteRule ^([a-z]{2})/sample-data/us/ /$1/data/sample/us/ [R=302,L]
But what about the 2nd /us/ - is that not also variable? Should the 1st and 2nd instance of /XX/ (two letters) be the same?
Test first with 302 (temporary) redirect to avoid potential caching issues. You will need to clear your browser cache before testing.
I've removed the NC flag - should this really be a case-insensitive match?
Note that if you have existing directives in your .htaccess file then the order is important. Generally, external redirects need to go near the top, certainly before your front-controller.

301 Redirection from old archive link to new

I changed my blog archive links from https://example.com/2019/09/ to https://example.com/blog/2019/09/. I would like to redirect from old url to new one. Is there any way to redirect all archive url along with /blog/ slug. Currently old urls goes to 404.
Try the following at the top of your .htaccess file:
RewriteEngine On
# Redirect "/NNNN/NN/" to "/blog/NNNN/NN/"
RewriteRule ^\d{4}/\d\d/$ /blog/$0 [R=302,L]
The $0 backreference contains the entire URL-path that is matched by the RewriteRule pattern (1st argument).
Change the 302 (temporary) redirect to 301 (permanent) only once you have confirmed that it works as intended.
Assuming this is WordPress then you don't need to repeat the RewriteEngine On directive, since it probably already occurs later in the file.

How to exclude trailing slash on source URL when redirecting?

I have to make a 301 redirect from a domain to another (example-a.com to example-b.com).
This is the code I put in .htaccess of example-a.com:
RewriteEngine on
RewriteRule ^(.*)$ https://www.example-b.com/$1 [R=301,L]
All URLs are the same, except pages of example-a.com all have a / (slash) at the end of the URL, but example-b.com does not. So how to redirect without the ending / if the URL contains one?
RewriteRule ^(.*)$ https://www.example-b.com/$1 [R=301,L]
To exclude the slash from the redirected URL, then exclude the slash from the captured group in the RewriteRule pattern. eg. ^(.*)/$.
However, assuming you also want the document root to redirect, where there is no slash in the URL-path, then you need to make the trailing slash optional (or create an entirely separate rule). But in that case you need to also make the capturing group non-greedy, otherwise the trailing slash will always be included in the captured group (since regex is greedy by default).
So, try the following instead:
RewriteRule ^(.*?)/?$ https://www.example-b.com/$1 [R=302,L]
You will need to clear your browser cache before testing. Since the earlier 301s will have likely been cached.
Note that this is a 302 (temporary) redirect. Only change this to a 301 (permanent) redirect - if that is the intention - once you have confirmed that it works OK. This is to avoid the browser caching erroneous redirects whilst testing.

mod_alias redirects adding two trailing slashes

I have a number of URLs which may be entered with or without a trailing slash. They're used as vanity URLs.
.htaccess looks like this:
Redirect 301 /folder/vanity1 http://example.com/differentfolder/
Redirect 301 /folder/vanity2 http://example.com/a/third/folder/
Redirect 301 /vanity3 http://example.com/fourth/folder/
Users type in:
http://example.com/folder/vanity1
http://example.com/folder/vanity2
http://example.com/vanity3
http://example.com/folder/vanity1/
http://example.com/folder/vanity2/
http://example.com/vanity3/
When users type these in with no trailing slash, the redirects are working correctly, ending up at http://example.com/differentfolder/ with one trailing slash as desired.
The problem:
When users type these in with a trailing slash, such as http:/example.com/folder/vanity1/ they redirect to a URL with two trailing slashes, such as http://example.com/differentfolder// which throws a 404 error.
I have tried:
Removing all other lines from .htaccess, except these three vanity URLs and the standard WordPress block required to keep the site functioning. The WordPress block appears at the very end of the file:
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
I checked not only with my browser but with WebConfs HTTP Header Check to make sure I wasn't seeing a cached rule. Still the same, if you type a vanity URL with no trailing slash it works; if you type it with one trailing slash, it redirects to two trailing slashes which causes a 404.
Adding a trailing slash in my rules:
Redirect 301 /folder/vanity1/ http://example.com/differentfolder/
This works fine if the user types the trailing slash, but if they leave off the slash it does not redirect and 404s because the URL http://example.com/folder/vanity1/ does not actually exist.
Question:
Is there a different way to 301 redirect the vanity URLs to a final destination with only one trailing slash, no matter which way the visitor types in the vanity URL - with or without a trailing slash?
This works as documented in Redirect,
Additional path information beyond the matched URL-path will be appended to the target URL.
This means /folder/vanity1 works only as a prefix, and an additional slash or anything else in the requested URL will be appended to the target, e.g. http://example.com/folder/vanity1/hi/there would result in http://example.com/differentfolder//hi/there
If you want to match exactly these two URLs, /folder/vanity1 and /folder/vanity1/, you must use either RedirectMatch or mod_rewrite
With a RewriteRule this would look like
RewriteRule ^folder/vanity1/?$ /differentfolder/ [R,L]
This pattern matches both with or without a trailing slash because of /?, which denotes an optional slash. The other rules would look similar.
When everything works as it should, you may replace R with R=301 (permanent redirect). Never test with R=301.
And with RedirectMatch, it would look almost the same
RedirectMatch ^/folder/vanity1/?$ /differentfolder/
Same disclaimer applies here, when it works as expected, you may set the status code to 301.

.htaccess : redirect permanent and stop new rules

I have that rule that works well
RedirectMatch 301 ^/(.*?)-/(.*)$ /$1/$2
It redirects for instance
http://example.com/category-/list/town/id/id2/country ->
http://example.com/category/list/town/id/id2/country
Problem is, later .htaccess adds some extra query parameters.
My goal is: when this rule is matches, then do not apply other .htaccess rules
I tried with:
RewriteRule ^/(.*?)-/(.*)$ /$1/$2 [R=301,L]
and rule is not applied at all !
As #hjpotter92 mentioned in the comments, the pattern is without the leading slash in .htaccess files. See Apache mod_rewrite Technical Details
In per-directory context (i.e., within .htaccess files and Directory blocks), these rules are being applied after a URL has already been translated to a filename. Because of this, the URL-path that mod_rewrite initially compares RewriteRule directives against is the full filesystem path to the translated filename with the current directories path (including a trailing slash) removed from the front.
To illustrate: If rules are in /var/www/foo/.htaccess and a request for /foo/bar/baz is being processed, an expression like ^bar/baz$ would match.
RewriteRule has a similar note in the section "Per-directory Rewrites".
So your rule should look like
RewriteRule ^(.*?)-/(.*)$ /$1/$2 [R,L]
If you have this RewriteRule, you don't need the RedirectMatch anymore.

Resources