---
title: Free Nginx Redirect Generator
slug: nginx-redirect-generator
last_reviewed: 2026-08-09
author: editorial
source: LemAudit Free Tools
---

## Intro

Nginx has no `.htaccess`. There is no per-directory file you can drop in to add a redirect, which surprises people moving from Apache and leads to a specific failure: Apache syntax pasted into an nginx server block, followed by a config test that refuses to reload. Redirects on nginx live in the main configuration and take effect when you reload the service.

This generator turns a plain list of old and new URLs into config you can paste. It offers two shapes. Location blocks are the clearest form and read well for a handful of rules. A map block is one lookup table that nginx evaluates in constant time, which is the right choice once the list runs long. Everything happens in your browser; no URL you paste leaves the page.

## Location blocks or a map

Use **location blocks** for up to roughly forty redirects. Each block is an exact match, self-documenting, and easy for the next person to edit:

```nginx
location = /old-page {
    return 301 /new-page;
}
```

The `=` matters. Without it the match is a prefix, so `/old-page` would also capture `/old-page-two` and send it somewhere wrong.

Use a **map** for larger lists, especially after a migration where you have hundreds of legacy URLs. The map lives in the `http` context and the server block does one lookup:

```nginx
map $request_uri $redirect_target {
    default off;
    /old-page /new-page;
}
```

Nginx resolves a map as a hash rather than by walking every rule, so a thousand entries cost about the same as ten. A thousand location blocks do not.

## Use return, not rewrite

The most common inherited mistake is writing redirects as rewrites:

```nginx
rewrite ^/old-page$ /new-page permanent;
```

That works, and it is slower and less clear than it needs to be. `rewrite` compiles and evaluates a regular expression on every matching request; `return` does not. Use `rewrite` only when you genuinely need a captured group from the old path, and `return` for everything else. The nginx documentation makes the same recommendation.

## Choosing the status code

**301** is permanent. It passes ranking signals to the destination, and browsers cache it hard, sometimes indefinitely. This is what you want for a moved page.

**302** is temporary. The old URL stays in the index and the destination inherits nothing. Use it for genuine short-term diversions, such as a seasonal landing page, and nothing else. A 302 left in place for a year is one of the most common causes of a page that never quite ranks after a redesign.

**307** and **308** preserve the request method. A browser following a 301 or 302 after a POST may convert it to a GET; 307 and 308 will not. They matter for API endpoints and form handlers, rarely for content pages.

Because browsers cache 301s so aggressively, test with a 302 during a migration and switch to 301 once the mapping is confirmed. A wrong 301 shipped to real users is difficult to take back.

## Two failure modes worth checking

**Loops.** A rule whose source and destination are the same path makes nginx return the same redirect forever, and the browser gives up with a too-many-redirects error. The generator drops those lines rather than emitting them. Loops also form across rules: `/a` to `/b` while `/b` goes to `/a`. Check your list for pairs before deploying.

**Chains.** If `/a` redirects to `/b` and `/b` redirects to `/c`, every visitor pays two round trips and each hop is another chance for something to break. Point `/a` straight at `/c`. Redirect chains from successive redesigns are extremely common and are worth flattening whenever you touch the file.

## Deploying safely

Always test before reloading:

```bash
nginx -t && systemctl reload nginx
```

`nginx -t` parses the configuration and reports the file and line of any error. `reload` applies the new config without dropping connections, unlike `restart`. Running them together means a broken config never reaches production.

After the reload, verify the status code rather than trusting the browser, which may be showing you a cached hop:

```bash
curl -sI https://example.com/old-page | head -n 3
```

## FAQ

### Where exactly do these rules go?

Location blocks go inside the `server { }` block for the site, above the catch-all `location /`. A map goes in the `http { }` context, outside any server block, and the `if` that uses it goes inside the server block. On Debian and Ubuntu the site file is usually under `/etc/nginx/sites-available/`.

### Can I put redirects in a separate file?

Yes, and you should once there are more than a few. Put them in their own file and pull it in with `include /etc/nginx/redirects.conf;`. That keeps the site config readable and makes the redirect list reviewable on its own.

### How do I redirect a whole directory?

Use a prefix match with `rewrite` and a capture, because you need the remainder of the path: `rewrite ^/old-section/(.*)$ /new-section/$1 permanent;`. This is the case where `rewrite` is the correct tool.

### Do redirects hurt SEO?

A single well-formed 301 passes essentially all ranking signal. What hurts is chains, loops, redirecting everything to the homepage instead of the closest equivalent page, and leaving temporary codes in place after the move is permanent.

### What about www to apex?

Handle it in its own server block that listens for the `www` host and returns a 301 to the apex, rather than as a per-path rule. It should be one rule covering every URL, not one rule per page.

### Is there an Apache version of this tool?

Yes — our [.htaccess redirect generator](/tools/htaccess-redirect-generator) produces the equivalent rules for Apache.
