Search code examples
regexapache.htaccessmod-rewriteurl-rewriting

How to only show id value on url path with htaccess?


What I have right now is

https://www.example.com/link.php?link=48k4E8jrdh

What I want to accomplish is to get this URL instead =

https://www.example.com/48k4E8jrdh

I looked on the internet but with no success :(

Could someone help me and explain how this works?

This is what I have right now (Am I in the right direction?)

RewriteEngine On
RewriteRule ^([^/]*)$ /link.php?link=$1

Solution

  • RewriteRule ^([^/]*)$ /link.php?link=$1
    

    This is close, except that it will also match /link.php (the URL being rewritten to) so will result in an endless rewrite-loop (500 Internal Server Error response back to the browser).

    You could avoid this loop by simply making the regex more restrictive. Instead of matching anything except a slash (ie. [^/]), you could match anything except a slash and a dot, so it won't match the dot in link.php, and any other static resources for that matter.

    For example:

    RewriteRule ^([^/.]*)$ link.php?link=$1 [L]
    

    You should include the L flag if this is intended to be the last rule. Strictly speaking you don't need it if it is already the last rule, but otherwise if you add more directives you'll need to remember to add it!

    If the id in the URL should only consist of lowercase letters and digits, as in your example, then consider just matching what is needed (eg. [a-z0-9]). Generally, the regex should be as restrictive as required. Also, how many characters are you expecting? Currently you allow from nothing to "unlimited" length.

    Just in case it's not clear, you do still need to change the actual URLs you are linking to in your application to be of the canonical form. ie. https://www.example.com/48k4E8jrdh.


    UPDATE:

    It works but now the site always sees that page regardless if it is link.php or not? So what happens now is this: example.com/idu33d3dh#dj3d3j And if I just do this: example.com then it keeps coming back to link.php

    This is because the regex ^([^/.]*)$ matches 0 or more characters (denoted by the * quantifier). You probably want to match at least one (or some minimum) of character(s)? For example, to match between 1 and 32 characters change the quantifier from * to {1,32}. ie. ^([^/.]{1,32})$.

    Incidentally, the fragment identifier (fragid) (ie. everything after the #) is not passed to the server so this does not affect the regex used (server-side). The fragid is only used by client-side code (JavaScript and HTML) so is not strictly part of the link value.