2

I just changed the urls structure of my site and want old urls to be forward to the new without the use of redirection plugin.

Old structure:

/%category%/%year%/%day%/%postname%/

New:

/%postname%/

Can anyone you tell me the regex code for the redirect that I can insert in the .htaccess file?

P.S. I tried yoast code regenerator and it redirected the old URLs to the new URLs without the end trailing slash and then redirected again with the trailing slash. So, it generated 2 redirects instead of one.

I am not able to figure out the .htaccess code needed and the following Yoast permalink generator code seems to cause a redirect chain issue:

RedirectMatch 301 ^/([^/]+)/([0-9]{4})/([0-9]{2})/([^/]+)/$ https://www.example.com/$4

I would like to know how to correct this code so I can insert it in my .htaccess file. Thanks.

4
  • 1
    Are you sure you are not missing %month% in old URL? Was it really /year/day/ without month part?
    – Marek
    Jul 1 at 14:56
  • "it redirected the old URLs to the new URLs without the end trailing slash" - Did you try simply appending a trailing slash to the target URL in the directive you've posted?
    – MrWhite
    Jul 1 at 15:32
  • No, it was a custom url we used date instead of month.
    – user208459
    Jul 3 at 10:03
  • The directive for some reason removes the trailing slash before redirecting and redirects again to the url with trailing slash. The original url requested is with trailing slash.
    – user208459
    Jul 3 at 10:06
1

...it redirected the old URLs to the new URLs without the end trailing slash and then redirected again with the trailing slash. So, it generated 2 redirects instead of one.

RedirectMatch 301 ^/([^/]+)/([0-9]{4})/([0-9]{2})/([^/]+)/$ https://www.example.com/$4

In that case you should simply be able to append a trailing slash to the target URL in the above directive (generated by yoast). ie. /$4/ instead of /$4. The second redirect you are seeing, that appends the trailing slash, is being performed by something else.

For example, the complete directive would be:

RedirectMatch 301 ^/([^/]+)/([0-9]{4})/([0-9]{2})/([^/]+)/$ https://www.example.com/$4/

You will need to clear your browser cache before testing. Preferably test with 302 (temporary) redirects to avoid potential caching issues (ie. change the 301 to 302 in the first argument of the above directive.)


Optimisation

However, the above directive can be simplified. Since you only need to capture the last path segment, you can avoid the parenthesised subpatterns in the regex (2nd argument). For example:

RedirectMatch 301 ^/[^/]+/\d{4}/\d{2}/([^/]+)/$ https://www.example.com/$1/

The \d shorthand character class is the same as [0-9]. Since we are only capturing the postname (4th path segment), we use $1, not $4 in the target URL.


Use mod_rewrite instead

However, the RedirectMatch directive (part of mod_alias) is processed after mod_rewrite (as used by the WordPress code block), so ideally you should be using mod_rewrite here instead in order to avoid unexpected conflicts (and it will be marginally more efficient).

For example, instead of the above RedirectMatch, use the following mod_rewrite RewriteRule directive at the top of your .htaccess file before the # BEGIN WordPress section:

RewriteRule ^[^/]+/\d{4}/\d{2}/([^/]+)/$ https://www.example.com/$1/ [R=301,L]

Just to emphasise, the above RewriteRule directive must go near the top of the .htaccess file, before the WordPress front-controller, otherwise it's simply never going to get processed. Whereas for the earlier RedirectMatch directive, the ordering does not matter so much (it can appear after the WordPress front-controller) - unless you have other mod_alias Redirect and/or RedirectMatch directives.


UPDATE:

when the original url is accessed without a trailing slash it is not forwarded to the new URL

You can make the trailing slash optional in the above regular expression (regex) by following the slash with ? (0 or 1 occurrences of the preceding element). For example:

RewriteRule ^[^/]+/\d{4}/\d{2}/([^/]+)/?$ https://www.example.com/$1/ [R=301,L]

So now it matches URLs both with and without a trailing slash and redirects to always include a trailing slash.

4
  • Thanks for the super detailed explanation! RewriteRule ^[^/]+/\d{4}/\d{2}/([^/]+)/$ example.com/$1 [R=301,L] worked! There is another issue, when the original url is accessed without a trailing slash it is not forwarded to the new url, it give a 404 error. Can you please help me with this issue?
    – user208459
    Jul 5 at 18:26
  • 1
    You're welcome. You can make the trailing slash optional by following it with ?. I've updated my answer.
    – MrWhite
    Jul 6 at 9:41
  • 1
    Thank you so much! The trailing slash issue has been solved as well :)
    – user208459
    Jul 8 at 8:40
  • I had one more question. Is there a way to change the internal links on the site with the new url structure?
    – user208459
    Jul 20 at 14:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.