How to replace ? and = with / in the URL? I think it may be in .htaccess.


example.com/public/Micheal-Smith would look like example.com?public=Micheal-Smith if I didn't replace the ? and = with /.

  • Are you wanting to "redirect" from one URL to the other? Or are you changing the URL in your application?
    – MrWhite
    May 2, 2021 at 11:56
  • Do your URLs have exactly one parameter? Or if you have two or more URL parameters, what would you expect your URLs to look like? May 2, 2021 at 13:04
  • @MrWhite I'm just trying to change URL in my application. May 2, 2021 at 15:16
  • @StephenOstermiller I've got only one parameter. May 2, 2021 at 15:18
  • @WawiSobota Ok, which part you are having trouble with? Have you changed the URL you are linking to in your application?
    – MrWhite
    May 2, 2021 at 16:53

1 Answer 1


I'm just trying to change URL in my application.

In that case, you are really asking the wrong question, since in order to change the URL that your application uses you don't "replace ? and = with /" in .htaccess. (You might do this later in order to preserve SEO, but that is really secondary to getting this working.)

In order to change the URL in your application, you must first actually change the URL you are using in your application. For example, if you were previously linking to a URL of the form example.com?public=Micheal-Smith in your HTML then you must physically change that link point to example.com/public/Micheal-Smith (the "new" user-friendly URL) instead. There really is no shortcut here. You must change the actual link in your HTML source.

You then use mod_rewrite (Apache's URL-rewriting module) in .htaccess to internally rewrite a request for the "new" user-friendly URL back into the "old" URL that your application understands. ie. /public/Micheal-Smith to ?public=Micheal-Smith. In other words, you are converting the slashes back into ? and = (effectively the opposite of what you were asking in the question).

Another side issue with how you've asked the question is that example.com?public=Micheal-Smith is not strictly a valid end-point. It requires further rewriting (perhaps by mod_dir) to actually get the request to a script that handles the response. If you are using PHP and the request should be handled by index.php in the document root, then this should really be example.com/index.php?public=Micheal-Smith (note there is always a slash at the start of the URL-path, even though you might not see this in the browser).

From your example, I'm assuming public (the URL parameter name) and Micheal-Smith (the URL parameter value) are entirely variable, so in a more generalised sense, you are changing the URL from /index.php?<param-name>=<param-value> to /<param-name>/<param-value>. I'll also assume <param-name> and <param-value> are restricted to the characters 0-9, a-z, A-Z, _ (underscore) and - (hyphen).

So, in summary, the steps to implement this are:

  1. Actually change the URL in your HTML source to /<param-name>/<param-value>.

  2. Implement an internal rewrite in .htaccess to rewrite a request for /<param-name>/<param-value> back to /index.php?<param-name>=<param-value>. For example:

    RewriteEngine On
    # Rewrite "/<param-name>/<param-value>" to "/index.php?<param-name>=<param-value>"
    RewriteRule ^([\w-]+)/([\w-]+)$ index.php?$1=$2 [QSA,L]

    The first argument ^([\w-]+)/([\w-]+)$ is a regular expression that matches against the requested URL /<param-name>/<param-value>. The parenthesised subpatterns (ie. ([\w-]+)) are "capturing groups" that capture the parts of the URL before and after the slash (the <param-name> and <param-value>). These are saved in the $1 and $2 backreferences and used in the RewriteRule substitution string (2nd argument) to form the original query string parameter. The QSA flag appends any query string that might be present on the requested URL to the end of the susbstituion string. If you are not using any additional URL parameters then you can remove this flag.

That is sufficient to implement the "new" user-friendly URL.

Optional 3rd step... However, if you are changing an existing URL structure that has already been indexed by search engines and linked to by third parties then you can choose to implement an external redirect from /?<param-name>=<param-value> to the "new" user-friendly URL, ie. /<param-name>/<param-value> (effectively the opposite of the above rewrite). This is a necessary step in order to preserve SEO.

  1. Implement an external redirect in .htaccess to redirect a request for /?<param-name>=<param-value> to /<param-name>/<param-value> (the "new" canonical URL). This needs to go before the above rewrite, immediately after the RewriteEngine directive:

    # Redirect "/?<param-name>=<param-value>" to "/<param-name>/<param-value>"
    RewriteCond %{ENV:REDIRECT_STATUS} ^$
    RewriteCond %{QUERY_STRING} ^([\w-]+)=([\w-]+)$
    RewriteRule ^(index\.php)?$ /$1/$2 [R=301,L]

    The index.php part of the URL is entirely optional, so it matches both /?<param-name>=<param-value> and /index.php?<param-name>=<param-value>.

    The first condition that checks against the REDIRECT_STATUS environment variable is necessary in order to redirect direct requests only and not rewritten requests by the later rewrite - which would otherwise cause a redirect loop.

    However, always test first with a 302 (temporary) redirect in order to avoid potential caching issues and only change to a 301 (permanent) redirect once you have tested that it works as intended.



Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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