2

I would like to rewrite an url from

/shop/?category=kitset-kitchens

to

shop/category/kitset-kitchens

What I tried:

rewrite ^/shop.*$ /shop/category/$arg_category permanent;
goes to:
shop/category/kitset-kitchens?category=kitset-kitchens

if I put "?" like so:

rewrite ^/shop.*$ /shop/category/$arg_category? permanent;
goes to:
shop/category/

I tried to play with variables, but the result is the same. As soon as $args set to '' all other variables are empty, otherwise, it adds get query at the end of the URL. What am I doing wrong?

I would like to not use conditions

Nikita
  • 123
  • 4

1 Answers1

2

I'm not sure that the browser will take into consideration the query parameters after caching the redirect. This means that after browser follow a redirect from /shop/?category=kitset-kitchens to /shop/category/kitset-kitchens once, it will redirect you to the same page even if the category query parameter will have another value. Different browsers can behave differently, so this subject needs some testing.

Back to the question, for clearing category query parameter preserving all the others you can use

    location = /shop/ {
        if ($args ~ (.*)(^|&)category=[^&]*(\2|$)&?(.*)) {
            # preserve 'category' parameter value
            set $category $arg_category;
            # remove 'category' parameter from query string
            set $args $1$3$4;
            # rewrite URI or do redirection
            rewrite ^ /shop/category/$category break;
        }
        # if you need to pass the request to an upstream, use
        proxy_pass http://upstream$uri$is_args$args;
    }

Please note that with this configuration web address in the user's browser won't change from example.com/shop/?category=kitset-kitchens to example.com/shop/category/kitset-kitchens (we use only internal rewriting here). You can try a redirect (change break flag of rewrite directive to permanent), but as I already said, this configuration needs testing through various browsers because of possible caching issues. You can also try temporary redirection (use redirect flag for that).

You said that you would like to not use conditions, but since there are no other directives except set and rewrite inside the if block, it may be considered safe.

Ivan Shatsky
  • 2,726
  • 2
  • 7
  • 19