Nginx 301 redirect query string

nginx

I am trying to redirect this ugly url,

/index.php/component/qs/?com=qs&id=1234

to,

/product/?id=1234

So I thought to do something like this,

server {
listen 443 ssl http2 default_server;
listen 443 [::]:443 ssl http2 default_server;

server_name www.example.com;

root /home/example/public_html/;

index index.php index.html index.htm;

location / {
try_files $uri $uri/ =404;
if($query_string ~ "id=(\d+)") {
rewrite ^.*$ /products/?id=$1 permanent;
}}

location ~ \.php$ {
include snippets/fastcgi-php.conf
include /etc/nginx/fastcgi_params;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_script_name;
fastcgi_intercept_errors on;
}
}

when I run nginx -t I get the following error,

nginx: [emerg] unknown directive "if($query_string"

I had this working under Apache but am new to Nginx, any help would be appreciated.

Best Answer

nginx stores URL query parameters in $arg_name parameters.

Therefore, you can use $arg_id in your if statement. Furthermore, you should should use another location before your location / directive:

location /index.php/component/qs {
    if ($arg_id) {
        rewrite ^ /products/?id=$arg_id permanent;
    }
}

If $arg_id is an empty string, the if statement is not executed. In rewrite, ^ is the shortest form of telling it to rewrite any URL. Since the URL and id argument are matched earlier, there is no need to do any matching in rewrite statement.