Search code examples
apachemod-rewrite

Apache rewriterule assistance needed


I am trying to remove query string: ?id= from this URL:

https://example.com/news-and-events/news/?id=/nodle/nodle-io/ledger-integration-update-compatibility-status-236699676dc6

and keep the page loading/working fine

I tried this:

RewriteEngine On

RewriteCond %{QUERY_STRING} ^(.)?id=(.)?$ [NC]

RewriteRule ^(.*)?$ $1%2? [R=301,L]

it seems to strip the ?id= out fine but the page won't load, just 404s.

My issue is making the content load / carry over on the new URL.

https://example.com/news-and-events/news/nodle/nodle-io/ledger-integration-update-compatibility-status-236699676dc6

Any help appreciated, Thanks Rob

Was expecting URL to load fine and not 404, but with the shorter URL.


Solution

  • Updated Answer:

    The / is missing because you probably have not declared the RewriteBase. As you are using the whole REQUEST_URI this one below in the code should do it.

    Additionally the second bracket expression of the RewriteCond needs an * to provide the full QUERY_STRING (reduced by the search pattern id=/).

    File: /news-and-events/news/.htaccess:

    RewriteEngine On
    RewriteBase "/news-and-events/news/"
    
    RewriteCond %{QUERY_STRING} ^(.)?id=/(.*)?$ [NC]
    RewriteRule ^(.*)?$ $1%2? [R=301,L]
    

    Simplyfied Version

    File: /news-and-events/news/.htaccess:

    RewriteBase /news-and-events/news/
    RewriteCond "%{QUERY_STRING}" "^id=/(.*)" [NC]
    RewriteRule "(.*)" "$1%1?" [R=301,L]
    

    OR within your virtualhost.conf-file:

    Here the context is essential:

    <VirtualHost *:80>
    
        DocumentRoot "/var/www/vhosts/myhost/htdoc/"
        # Other directives
        
        # Only required once:
        RewriteEngine On
            
        <Directory "/var/www/vhosts/myhost/htdoc/news-and-events/news/">
            RewriteBase "/news-and-events/news/"
            RewriteCond "%{QUERY_STRING}" "^id=/(.*)" [NC]
            RewriteRule "(.*)" "$1%1?" [R=301,L]
        </Directory>
        
        # More <Directory> container
        
    </VirtualHost>
    

    BTW: It is a good habit to enclose the patterns in double quotes, even if not always necessary.

    Some Comments

    You match against QUERY_STRING:

    QUERY_STRING = 'id=/nodle/nodle-io/ledger-integration-update-compatibility-status-236699676dc6'
    

    It will always begin with the character after the ? in the URL. So the match in the RewriteCond does not

    As the regex is greedy and you select the whole string forcing the ^ start and $stop of the string is obsolete. Also making it optional by ? is unnecessary, as (.*) may evaluate to empty by itself.

    Notes

    • Meanwhile you've disclosed, that the code shall reside in a virtualhost.conf-file of the apache server.
    • Also the configuration is not standalone but a sub-directory of a Wordpress installation, that also uses some Rewrite rules. As you have enabled the directive for .htaccess, but want to write the rules in the virtualhost.conf-file.
    • Using the propper container is essential to prohibit cross-influences with your Wordpress installation (in both directions).
    AllowOverride All
    

    you should first cleanup all possibly still existing previous "experiments" within .htaccess files to solve your problem. — Really important!


    But obviously your intent has been the inverse of that what has been your question:

    So besides the fact, the presented solution does what you've asked, there is obviously no content at the rewritten URL and you end up with a 404 · Not found. HTML client error.

    Doing something like this has its sense, when it comes to a changed URI-structure (i.e. because of a change of the serving software) and you want your visitors to be able to follow the content. Also by the HTML status code 301 · Moved permanently the search engines will quickly learn to use the new URI logic and keep the SEO up.