1

I have the following URL

https://example.com/expert-profile?id=john-doe&locale=en

I want it to be redirected to

https://example.com/expert/john-doe

I tried the following

RewriteCond %{QUERY_STRING} ^(([^&]*&)*)id=([^&]+)&?(.*)?$
RewriteRule ^expert-profile$ https://example.com/expert/%3?%1%4 [L,R=301]

And a couple of other solutions, nothing is working here. Can someone help me to go in the right direction?

Update:

This is my current .htaccess file

<IfModule mod_rewrite.c>

  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_FILENAME} !-l
  RewriteRule . /index.html [L]

</IfModule>

Redirect 301 "/en/download-app" "/download-app"
MrWhite
  • 43,179
  • 8
  • 60
  • 84
Ibrahim Azhar Armar
  • 25,288
  • 35
  • 131
  • 207
  • 1
    What exactly was happening with the attempt that you've posted? It should result in a "valid" redirect (albeit with an additional query string). If nothing at all is happening then you're probably putting the directive in the wrong place. – MrWhite Apr 04 '21 at 10:12

3 Answers3

3

Please keep your htaccess file in your root and have it in following way. Please clear your browser cache before testing your URLs.

RewriteEngine ON
RewriteCond %{QUERY_STRING} ^id=([^&]*)&locale=(.*)$ [NC]
RewriteRule ^([^-]*)-.*/?$ $1/%1-%2 [R=301,L]


OR in case you don't have Rules to handle non-existing files/directories then use following Rules set. Please make sure either use above OR following Rules set one at a time only.

RewriteEngine ON
RewriteBase /
RewriteRule ^index\.html$ - [L]

RewriteCond %{QUERY_STRING} ^id=([^&]*)&locale=(.*)$ [NC]
RewriteRule ^([^-]*)-.*/?$ $1/%1-%2 [R=301,L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(?:expert)/([^-]*)-(.*)$ $1-profile?id=$1&locale=$2 [NC,L]


RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^ /index.html [L]
RavinderSingh13
  • 130,504
  • 14
  • 57
  • 93
2

If you want it rewritten, capture the name (.+) and insert it into the target $1

RewriteRule ^expert/(.+)$ /expert-profile?id=$1&locale=en [L]

And don't use flag R|redirect here, unless you really want a redirect.---


To redirect from expert-profile?id=john-doe to expert/john-doe, capture the id (.+?) from the query string and insert it in the substitution URL %1

RewriteCond &%{QUERY_STRING}& &id=(.+?)&
RewriteRule ^expert-profile$ /expert/%1 [R,L]

When everything works as it should, you may replace R with R=301 (permanent redirect).

Don't use both rules together. If you do, it will result in an endless redirect loop and finally give a "500 Internal Server Error".


Unrelated, but never test with R=301!

Olaf Dietsche
  • 72,253
  • 8
  • 102
  • 198
2

I have following URL

https://example.com/expert-profile?id=john-doe&locale=en

I want it to be redirected to

https://example.com/expert/john-doe

You would need to do something like the following at the top of your .htaccess file, before your existing directives (order is important):

RewriteCond %{QUERY_STRING} (?:^|&)id=([^&]+)
RewriteRule ^expert-profile$ /expert/%1 [QSD,R=301,L]

This captures the value of the id URL parameter (in the %1 backreference) regardless of where it appears in the query string and discards all other URL parameters. I'm assuming you don't specifically need to match locale=en?

Note that the regex subpattern ([^&]+) (the id value) only matches something, not nothing. If the URL parameter is empty (ie. id=&locale=en) then no redirect occurs.

The QSD flag is necessary to discard the original query string.

Test first with a 302 (temporary) redirect to avoid potential caching issues. And clear your browser cache before testing. Only use a 301 (permanent) redirect if this really is intended to be permanent.

To redirect the specific URL /expert-profile?id=<name>&locale=en to /expert/<name>, ie. the id parameter is at the start of the query string and is followed by locale=en only then you can (and should) be more specific in the condition. For example:

RewriteCond %{QUERY_STRING} ^id=([^&]+)&locale=en$
RewriteRule ^expert-profile$ /expert/%1 [QSD,R=301,L]
RewriteCond %{QUERY_STRING} ^(([^&]*&)*)id=([^&]+)&?(.*)?$
RewriteRule ^expert-profile$ https://example.com/expert/%3?%1%4 [L,R=301]

This is close (providing you placed the rule at the top of the file), however, this tries to preserve the other URL parameters, ie. locale=en and whatever else, to create another query string - which you've not stated in your requirements.


Aside: The existing answers are assuming you are wanting to internally rewrite (URL rewrite) the request in the other direction, ie. from /expert/john-doe to /expert-profile?id=john-doe&locale=en. This is probably due to how questions of this nature are notoriously miswritten and this is often the real underlying intention. However, you've made no mention of this here and a URL of the form /expert-profile is not a valid endpoint - so it wouldn't really make sense to "rewrite" the URL in that direction. (?)

MrWhite
  • 43,179
  • 8
  • 60
  • 84