Suppose we need to make NGINX redirect according to this scheme:
example.com/tags?tag=cool => example.com/something
The original url with parameters must be redirected to the new url. The parameter name and value are not used in the new url.
A standard redirect for this type of issue will not work.
## It will not work
location = /tags?tag=cool {
return 301 https://example.com/something;
}
The solution is to use the MAP directive.
MAP
Before all server declarations, at the beginning of the configuration file we write the “mapping” table:
map $arg_tag $tag_new_destination {
'cool' /something;
'6.0.1' /tags/601;
'alfa' /newone;
}
In this example, the redirects will be:
example.com/tags?tag=cool => example.com/something
example.com/tags?tag=6.0.1 => example.com/tags/601
example.com/tags?tag=alfa => example.com/newone
The $arg_tag — this is nginx variable, it is created by the pattern $arg_* from query string. Here we have a parameter ?tag, this is why the variable is named $arg_tag.
$tag_new_destination — our custom variable.
If the table is large, nginx asks you to increase the size of map_hash_bucket_size. This should be changed in the nginx.conf file. For example, for 100 addresses, with long Russian transliterations, a value of 256 was enough.
map_hash_bucket_size 256;
Location
In the appropriate server section you need to write:
location /tags {
error_page 420 = @tags_redirects;
if ( $args ~ "tag=" ) { return 420; }
try_files $uri $uri/ /index.php?$query_string;
}
location @tags_redirects {
if ($tag_new_destination) {
return 301 $tag_new_destination;
}
}
We declare the location we need, in this case /tags. We want redirects to be processed only at these addresses. It contains a condition for the presence of a string with the tag parameters ($args ~ "tag ="). If this condition does not work (that is, the address /tags is without parameters and a redirect is not needed), then we forward it to try_files (or another standard solution).
If the query condition with the parameter is triggered, then its location @tags_redirects is declared, where mapping is checked. $tag_new_destination is just a variable that is equal to 1 if it exists in the mapping table.
If there are many redirects, they can be moved to a separate file.
At the beginning of the configuration file, write include for the file, where there will be a list with redirects:
map $arg_tag $tag_new_destination {
include includes/tags-redirects.conf;
}
The includes/tags-redirects.conf file lists all matches of old and new addresses. For our example, its content will be:
'cool' /something;
'6.0.1' /tags/601;
'alfa' /newone;