Strip parent categories from url - apache

I'm struggling to fix an issue with 301 redirects and .htaccess. I have moved a site from an old domain to a new domain. And I have successfully managed to do this with a 301 redirect. Like so:
Redirect 301 / https://newdomain.com
On the old site child category URLs are like this:
olddomain.com/product-category/parent-cat1/parent-cat2/child-cat
or
olddomain.com/product-category/parent-cat1/child-cat
or
olddomain.com/product-category/child-cat
Whereas on the new site they are:
newdomain.com/product-category/child-cat
Unfortunately, this is resulting in 404s from the redirects. Is there any way to remove the parent categories (which can vary by name and amount of them) from the URL?

Try including the following RedirectMatch directive before your existing Redirect directive:
RedirectMatch 302 ^/([\w-]+)/(?:[\w-]+/)+([\w-]+)$ https://newdomain.com/$1/$2
The RedirectMatch directive is complementary to the Redirect directive, both part of mod_alias. Except the RedirectMatch directive uses regex to match the URL-path, whereas Redirect uses simple prefix-matching.
This assumes that the path segments (ie. "product-category", "parent-cat" and "child-cat") consist of just the characters a-z, A-Z, 0-9, _ and - (hyphen). This needs to be as specific as possible so as not to match "too much". One or more "parent-cat" are required.
$1 is a backreference to the first captured group in the pattern. ie. ([\w-]+), the product-category. And $2 is a backreference to the second captured group, ie. ([\w-]+) at the end of the pattern, the child-cat. The (?:....) "group" in the middle is a non-capturing group, so there is no backreference that applies to this.
This is a 302 (temporary) redirect. Change it to a 301 only when it is working OK. It is easier to test with 302s since they are not cached by the browser. Consequently, you'll need to make sure your browser cache is clear before testing.

Related

RedirectMatch without last part of URL

I have this RedirecMatch
RedirectMatch 301 ^/en/products/(.*)/(.*)/(.*)$ https://www.example.com/en/collections/$2/
If I visit
https://www.example.com/en/products/sofas/greyson/greyson-sofa
I'm redirected to
https://www.example.com/en/collections/greyson/greyson-sofa
What I want is
https://www.example.com/en/collections/greyson/
How do I accomplish this?
There's nothing obvious in what you have posted that would produce the specific output you are seeing, however, there are other errors in the directives and you may be seeing a cached response. 301s are cached persistently by the browser, so any errors are also cached.
The Redirect directive is prefix-matching and everything after the match is copied onto the end of the target URL. So, the redirect you are seeing would be produced by a directive something like this:
Redirect 301 /en/products/sofas/greyson https://www.example.com/en/collections/sofas/greyson
When you request /en/products/sofas/greyson/greyson-sofa, the part after the match, ie. /greyson-sofa, is copied onto the end of the target URL to produce /en/collections/sofas/greyson/greyson-sofa
You can resolve most of these issues by reordering your rules (but also watch the trailing slashes). You need to have the most specific redirects first. RedirectMatch before Redirect. For example, take the following two redirects:
Redirect 301 /en/products/accessories https://www.example.com/en/products/complements/
Redirect 301 /en/products/accessories/bush/ https://www.example.com/en/collections/bush-on/
Since the Redirect directive is prefix-matching, a request for /en/products/accessories/bush/ will actually be caught by the first rule, not the second and end up redirecting to /en/products/complements//bush-on/ - note the erroneous double-slash (since you have a mismatch of trailing slashes on the source and target URLs.)
You need to reverse these two rules. (But also watch the trailing slash.)
The same applies to the Redirect directives that follow. You also have some duplication, ie. You have two rules for /en/products/chairs-and-bar-stools/piper/?

how do I redirect a url and remove part of the string

I have an url like this:
domain.com/thispart/blah-something-blah-remove
I need to redirect this url like this:
domain.com/newpart/blah-something-blah
change the directory and remove the last part(the last part is always constant, this time it's remove).
How do I do this? I managed to redirect the directory, but the last par I don't know how to remove.
Providing you don't have any existing mod_rewrite directives then you can do something like the following using a mod_alias RedirectMatch directive near the top of your .htaccess file:
RedirectMatch ^/thispart/([\w-]+)-remove$ /newpart/$1
Note that this removes "-remove", as in your example, not simply the string "remove".
The path segment before the "-remove" part is assumed to consist of the characters 0-9, a-z, A-Z, _ or -.
This is a temporary (302) redirect.
You will need to clear your browser cache before testing.
However, if you have existing mod_rewrite directives then you should use mod_rewrite instead to avoid potential conflicts (and improve efficiency). For example:
RewriteRule ^thispart/([\w-]+)-remove$ /newpart/$1 [R=302,L]
(Note the absence of the slash prefix on the RewriteRule pattern.)

Redirect and append GET-Parameter

I'm having trouble with redirecting from one URL to another, while appending one GET-parameter to the NEW URL.
The first time (from root of old domain to root of new domain) works perfectly fine. After (further down in the .htaccess this one case) the GET-parameter appears randomly in the middle of the new url.
Obviously that leads to some nasty 404 situations...
RewiriteEngine on
Redirect 301 / https://foo.bar?redirect=1
Redirect 301 /foo/bar/ https://foo.bar/foo/bar?redirect=1
To give further information:
The idea is to redirect inklusive this parameter, to trigger a popup, giving information about the recent redirect so the user doesn't lose his confidence about the visit of foo.bar.
The first redirect will result in just the right way, it works perfectly.
The second thou, turns out like:
https://foo.bar/foo/?redirect=1bar/
Please and Thank you :)
Your rules work fine as you configure them , why ?
With mod_alias redirect and this part
Redirect 301 / https://foo.bar?redirect=1
Will match / & /foo/ & /foo/bar/ and so on , so the second rule will not work at all because of every request being captured by firrt rule ,and the result of redirecting /foo/bar/ with first rule is foo/bar?redirect=1foo/bar/ because with redirect every things after match will be appending to new target.
To avoid that use RedirectMatch
RewriteEngine On
RedirectMatch 301 /?$ https://foo.bar/foo/bar?redirect=1
RedirectMatch 301 /foo/bar/ https://foo.bar/foo/bar?redirect=1
By this way with regex , you will be able to match against root only by first rule then against /foo/bar/ by second rule.
Note: clear browser cache then test

301 redirect for old urls with language parameter

I need a hand with some 301 redirects for my apache htaccess file. The old urls contain variables at the end and have structures like the following:
/furniture-248/category/570-shelves.html?lang=en
/all-products/furniture-248/shelves.html?page=2&lang=en
/store/product/asearch.html?path=7_632&lang=en&Itemid=284
The new urls don't contain parameters of this nature and would be simply of the form:
main-cat/subcat/sale.html
I tried a regular 301 redirect in the htaccess file which works for urls without parameters but those urls containing the ?lang=en simply don't work.
This is what I was trying:
Redirect 301 /furniture-248/category/570-shelves.html?lang=en http://www.domain.com/shelves.html
I'd be very grateful for any help and advice.
Many thanks in advance
You can't use the query string as part of a redirect like that. You have two options.
Option 1
Take the "?lang=en" part off and just redirect all instances of that URL, whatever the query string is.
Redirect 301 /furniture-248/category/570-shelves.html http://www.domain.com/shelves.html
This will leave the query string intact, so the new URL will include "?lang=en" if it is present, or any other query string.
But of course, you might need to only redirect it when it has the "?lang=en" part, or leaving the query string intact when redirecting might not be acceptable. In that case, it will need to be...
Option 2
Use mod_rewrite:
RewriteEngine On
RewriteCond %{QUERY_STRING} ^lang=en$
RewriteRule ^furniture-248/category/570-shelves\.html$ http://www.domain.com/shelves.html? [R=301,L]
This does exactly what you asked for, redirecting /furniture-248/category/570-shelves.html?lang=en to http://www.domain.com/shelves.html and only that.
Note that..
The query string is matched separately.
The opening forward slash on the matching part is not used (because the fact you're in a website root level .htaccess file implies that opening slash).
The closing question mark on the redirect URL is important, as it tells the engine to drop the existing query string, which is what you want.
[R=301,L] means do a 301 redirect and don't process any more URL rewriting on this URL.
For the matching part in RewriteRule, the dot before "html" is escaped with "\" because dot has a special meaning in a regex.
Also for the matching parts, in both RewriteCond and RewriteRule, the ^ means the start of the string and the $ means the end of it, so that we are matching exactly that rather than it being possible for it to be part of a longer string.
And finally, if you're adding a number of these, you only need the "RewriteEngine On" part once, at the top. The other two parts are needed for each one.
Please be sure to test all redirects you add with this method as there is more to mod_rewrite than I have mentioned in this simple explanation.

multiple folder redirect

I have been trying variations of the following without success:
Redirect permanent /([0-9]+)/([0-9]+)/(.?).html http://example.com/($3)
It seems to have no effect. I have also tried rewrite with similar lack of results.
I want all links similar to: http://example.com/2002/10/some-long-title.html
to redirect the browser and spiders to: http://example.com/some-long-title
When I save this to my server, and visit a link with the nested folders, it just returns a 404 with the original URL unchanged in the address bar. What I want is the new location in the address bar (and the content of course).
I guess this is more or less what you are looking for:
RewriteEngine On
ReriteRule ^/([0-9]+)/([0-9]+)/(.?)\.html$ http://example.com/$3 [L,R=301]
This can be used inside the central apache configuration. If you have to use .htaccess files because you don't have access to the apache configuration then the syntax is slightly different.
Using mod_alias, you want the RedirectMatch, not the regular Redirect directive:
RedirectMatch permanent ^/([0-9]+)/([0-9]+)/(.+)\.html$ http://example.com/$3
Your last grouping needs to be (.+) which means anything that's 1 character or more, what you had before, (.?) matches anything that is either 0 or 1 character. Also, the last backreference doesn't need the parentheses.
Using mod_rewrite, it looks similar:
RewriteEngine On
RewriteRule ^/([0-9]+)/([0-9]+)/(.+)\.html$ http://example.com/$3 [L,R=301]