.htaccess & Nginx Redirect Generator
Generate Apache .htaccess and Nginx redirect rules from a form: force HTTPS, normalise www and trailing slashes, add 301s, with loop and chain warnings.
Tick the common cases, such as forcing HTTPS, normalising www and trailing slashes or stripping index.html, add any individual rules as rows, and get the equivalent configuration for Apache .htaccess and Nginx from the same input. Loops, duplicate sources and chains that would cause a double redirect are flagged as you type.
Patterns with regex become RewriteRule (Apache) / rewrite (Nginx); plain paths become Redirect / location =. A trailing * is treated as (.*).
RewriteEngine On
# Force HTTPS + Normalise to non-www
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^example\.com$ [NC]
RewriteRule ^(.*)$ https://example.com/$1 [R=301,L]Note: if .htaccess has no effect, check that AllowOverride All is set and mod_rewrite is enabled in the Apache config.
// .htaccess & Nginx Redirect Generator: Features
301 vs 302: which redirect to use
A 301 says the resource has moved permanently; a 302 says it is temporarily somewhere else. Search engines treat a 301 as a signal to transfer the old URL's ranking to the new one, while a 302 keeps the old URL indexed. Anything you do not intend to undo, which covers moved pages, the switch to HTTPS and www normalisation, should be a 301. Reserve 302 for maintenance pages, A/B tests and similar short-lived detours. 307 and 308 are the method-preserving versions of 302 and 301 and only matter when POST requests need to follow the redirect. The HTTP Status Codes reference describes each in more detail.
Redirect vs RewriteRule in .htaccess
Apache offers two ways to write a redirect. Redirect 301 /old /new belongs to mod_alias: it only does prefix matching, but it works even when mod_rewrite is disabled. RewriteRule belongs to mod_rewrite and supports regular expressions, back-references and RewriteCond conditions on the host name or protocol. The generator emits Redirect for rows whose source contains no regex characters and RewriteRule for the rest. Forcing HTTPS or normalising www needs a condition, so those always come out as RewriteCond plus RewriteRule.
Force HTTPS and www in a single 301
If a request for http://www.example.com/ is first sent to https://www.example.com/ and then on to https://example.com/, every visitor pays for two round trips, and search engines pass on slightly less ranking signal through each hop. When both options are selected, the generator writes a single rule with an [OR] condition that sends any non-canonical request straight to the final URL in one 301. When editing an existing configuration by hand, it is worth checking that each redirect lands on the final destination rather than an intermediate one.
Nginx 301 redirect: server blocks instead of if
Nginx's if directive behaves unexpectedly inside location blocks, which is why the project documents it under the heading "If Is Evil". The recommended way to force HTTPS or normalise www is to give the non-canonical host its own server block that does nothing but return 301. The "Nginx" tab emits the compact if form that can be pasted into an existing server block; the "Nginx (split server)" tab emits the recommended structure. Use the latter for a new deployment and add your SSL certificate paths and location blocks to the main server.
Catching loops and chains before they go live
A pair of rules such as /a to /b and /b to /a produces an endless loop, and the browser gives up with a "too many redirects" error. A chain such as /a to /b and /b to /c is not an error but means every visit to /a goes through two redirects. The generator cross-checks the individual rules and warns about loops, chains and duplicate sources where only the first rule would ever match. To confirm what a server actually sends in its Location header, paste the response into the HTTP Header Analyzer.
// .htaccess & Nginx Redirect Generator: FAQ
.htaccess redirect not working: what should I check?
- First check that the Apache configuration grants AllowOverride All, or at least FileInfo, for the directory; with AllowOverride None the file is never read. Rules using RewriteRule also need mod_rewrite enabled, for example via a2enmod rewrite. If both are in place, confirm that the file is literally named .htaccess with the leading dot, that it is saved as UTF-8 without a byte order mark, and that it uses LF line endings.
How do I write a RewriteRule pattern with (.*) and $1?
- Write (.*) in the source to match any string and refer to it as $1 in the target. For example /blog/(.*) to /articles/$1 sends /blog/hello to /articles/hello. The generator also accepts a trailing * as shorthand for (.*), so /old/* to /new/$1 works too. Remember that a dot matches any single character in a regex, so write \.html when you need to match a literal .html.
Should I add or remove the trailing slash?
- Either is fine as long as the site is consistent. When /about and /about/ both return a page, search engines see two URLs and split the ranking between them. Directory-style URLs backed by index files naturally take a slash; file-style URLs such as /about.html naturally do not. The "Add" option skips URLs with a file extension and the "Remove" option skips real directories, so static assets and directory listings keep working.
How do I redirect an old domain to a new domain and keep the paths?
- Choose the "Site move" preset. It adds a rule from /(.*) to https://new-example.com/$1; replace the host with your new domain. Place the resulting configuration on the old domain's server and a request for /old/page.html is redirected with a 301 to the same path on the new domain. Submitting the change through Google Search Console's change-of-address tool as well helps search engines pick up the move faster.
Does this work with WordPress?
- Yes. WordPress rewrites the part of .htaccess between # BEGIN WordPress and # END WordPress, so put the generated rules above that block. WordPress's own permalink rule routes everything to index.php and stops processing with the [L] flag, which is why your redirects must be evaluated first. The "WordPress" preset includes examples for the ?p=123 style of old URL and for a renamed category.
Where does the Nginx output go?
- The "Nginx" tab is meant to be pasted directly inside an existing server { ... } block, at the server level rather than inside a location. The "Nginx (split server)" tab emits complete server blocks, so it goes into a file under /etc/nginx/sites-available/ or equivalent, with the SSL certificate paths filled in. Run nginx -t to validate the syntax, then nginx -s reload to apply it.
Why does the old 301 redirect keep happening after I changed it?
- The browser has cached the 301. Because a 301 is permanent, browsers follow it on subsequent visits without asking the server again. Test in a private window or with curl -I https://example.com/old, neither of which is affected by the cache. There is no way to clear a wrong 301 from visitors' browsers once it has been served, so when a change is uncertain it is safer to deploy it as a 302 first and switch to 301 once it is confirmed.
Is matching case-sensitive?
- Both Redirect and RewriteRule in Apache are case-sensitive by default. Add the [NC] flag to a RewriteRule to ignore case. The generated www rules already compare the host name with [NC], but the individual rules do not, so change [R=301,L] to [R=301,L,NC] by hand where needed. Nginx's rewrite is case-sensitive unless the pattern uses ~*.
Can the generated configuration do anything dangerous?
- It only contains standard RewriteCond, RewriteRule, Redirect, return and rewrite directives and nothing that alters server configuration. Rules whose target uses $1 pass the input through unchanged, so only point them at URLs you control. Verifying the result on a staging server before deploying it to production is still recommended.
Is my input sent anywhere?
- No. Everything is generated in your browser, so internal host names, unannounced destination domains and lists of legacy URLs never leave your machine.
// How to Use .htaccess & Nginx Redirect Generator
-
Pick a preset or the common settings
Start from a preset such as "HTTPS + non-www", or tick Force HTTPS, www normalisation, trailing slash handling and index.html stripping individually. Enter the domain name if you are normalising www.
-
Add individual redirects as rows
Enter a source and a target and choose the status code. Use (.*) or a trailing * to redirect whole groups of URLs. If a loop or chain is detected, point the source straight at the final URL.
-
Choose the output and copy it
For Apache, save the output directly as .htaccess. For Nginx, choose between the if form and the split-server form, paste it into the server block, validate with nginx -t and reload.
Category Network