I need to rewrite URLs in NGINX. I tried many examples from google searches but failed.


I need to rewrite it as


or something like this


Edit 1: can we simply replace '&' and '=' from URL to '/'. In this way we will get something like


Edit 2: here is my complete configuration file.

server {
        server_name example.com www.example.com *.example.com;
        listen default ssl;
        root /home/example/public_html;
        index index.php index.htm index.html;
        rewrite_log on;
#HMPRESS rewrite config
#       location /manager {
#       try_files $uri $uri/ /manager/?whmpca=$uri&$args;
#       }
location ~ ^/manager/?$ {
    return 302 /manager/cart/a/$arg_a/pid/$arg_pid/currency/$arg_currency/billingcycle/$arg_billingcycle;
## wordpress configuration

        location = /favicon.ico {
         log_not_found off; access_log off;
        location / {
        try_files $uri $uri/ /index.php$args;
## wordpress conf ends
        include /etc/nginx/fastcgi_cache.conf;
        include /etc/nginx/static-files.conf;
        include /etc/nginx/exclusions.conf;
        access_log /var/log/virtualmin/example.com_access_log;
        error_log /var/log/virtualmin/example.com_error_log notice;
        fastcgi_param GATEWAY_INTERFACE CGI/1.1;
        fastcgi_param SERVER_SOFTWARE nginx;
        fastcgi_param QUERY_STRING $query_string;
        fastcgi_param REQUEST_METHOD $request_method;
        fastcgi_param CONTENT_TYPE $content_type;
        fastcgi_param CONTENT_LENGTH $content_length;
        fastcgi_param SCRIPT_FILENAME /home/example/public_html$fastcgi_script_name;
        fastcgi_param SCRIPT_NAME $fastcgi_script_name;
        fastcgi_param REQUEST_URI $request_uri;
        fastcgi_param DOCUMENT_URI $document_uri;
        fastcgi_param DOCUMENT_ROOT /home/example/public_html;
        fastcgi_param SERVER_PROTOCOL $server_protocol;
        fastcgi_param REMOTE_ADDR $remote_addr;
        fastcgi_param REMOTE_PORT $remote_port;
        fastcgi_param SERVER_ADDR $server_addr;
        fastcgi_param SERVER_PORT $server_port;
        fastcgi_param SERVER_NAME $server_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_param HTTPS $https;
        location ~ \.php(/|$) {
                try_files $uri $fastcgi_script_name =404;
                fastcgi_pass unix:/var/php-nginx/134783825911919.sock/socket;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        ssl_certificate /home/example/ssl.combined;
        ssl_certificate_key /home/example/ssl.newkey.bak;

  • can we achieve it in a different way? For example simply replace '&' and '=' with '/'. we will then get the url /manager/whmpca/order_process/a/add/pid/1/a/add/currency/1/billingcycle/monthly – Faheem Jun 1 at 16:39
  • No, there is no search & replace functionality like that in nginx. One could achieve this with OpenResty nginx and custom Lua module. I think the best way to implement this is in your backend. The rewriting logic might be too complex to implement in nginx. – Tero Kilkanen Jun 1 at 18:08
if ( $args ~ "whmpca=order_process&a=add&pid=(\d)&a=add&currency=(\d)&billingcycle=monthly" ) {
  set $pid $1;
  set $cur $2;
rewrite /manager/cart/a/add/pid/$pid/currency/$cur/billingcycle/monthly/ redirect;
  • Thanks for your answer but unfortunately it is not working. below is error nginx: [emerg] unexpected "}" in /etc/nginx/sites-enabled/example.com.conf:22 I then moved "}" at the end of this code like below: if ( $args ~ "whmpca=order_process&a=add&pid=(\d)&a=add&currency=(\d)&billingcycle=monthly" ) { set $pid $1 set $cur $2 rewrite /manager/cart/a/add/pid/$pid/currency/$cur/billingcycle/monthly/ redirect; } but unfortunately following is the error: nginx: [emerg] invalid number of arguments in "set" directive in /etc/nginx/sites-enabled/example.com.conf:23 – Faheem Jun 1 at 14:31
  • I forgot the semicolons!! – Gerard H. Pille Jun 1 at 14:34
  • nginx: [emerg] the duplicate "pid" variable in /etc/nginx/sites-enabled/example.com.conf:20 – Faheem Jun 1 at 14:52
  • if ( someting ) { do bla }; <-- Semicolon is missing – djdomi Jun 1 at 15:03
  • @djdomi no it isn't. – Gerard H. Pille Jun 1 at 15:08

nginx stores individual query arguments to variables with $arg_ prefix.

In this case, you can use the following pattern:

location ~ ^/manager/?$ {
    return 302 /manager/cart/a/$arg_a/pid/$arg_pid/currency/$arg_currency/billingcycle/$arg_billingcycle;

However, if you need to limit actions based on value of whmpca argument, then additional restrictions are needed.

This also requires that every request has these arguments. If one argument is missing, it will break.

  • I got a 'too many redirects' error in the browser and also URL is missing arg values. /manager/cart/a//pid//currency//billingcycle/ – Faheem Jun 1 at 16:31
  • I changed the location to prevent matches to the redirected URL. Did you specify all the arguments in the original request? – Tero Kilkanen Jun 1 at 17:09
  • It is now working and rewriting URL but page not found error appears. one more thing, now I can't access other URLs in /manager/, it is redirecting all to /manager/cart/a/..... I posted a comment under the original question, can you please suggest something according to the comment. – Faheem Jun 1 at 17:21
  • If there is a page not found error, then it means your backend cannot understand the URLs you are creating. You need to check what is the correct format URLs your backend understands and then put correct information to the question. – Tero Kilkanen Jun 1 at 18:12

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.