keepcalculator

06 Numbers and Powers

Convert htaccess Rewrite Rules to Nginx Config: Step-by-Step

Card No. 06·14752 · Updated · Standard formula, shown below

Converting Apache .htaccess rewrite rules to nginx is a common task when migrating a website to a faster, more modern server. The key difference is that Apache processes rewrite rules in a per-directory context (often inside .htaccess), while nginx processes them in a server or location block using its own syntax. This guide walks you through the exact steps to translate your rules accurately, including handling common patterns like WordPress permalinks and query string redirects. You will need access to your nginx configuration file and the ability to test and reload the server.

What You’ll Need

  • Your existing .htaccess file with the rewrite rules you want to convert.
  • SSH or terminal access to your nginx server (or a local nginx installation for testing).
  • Text editor (nano, vim, or a local editor) to modify the nginx configuration file (usually /etc/nginx/nginx.conf or a site file in /etc/nginx/sites-available/).
  • Basic familiarity with the command line and the ability to run nginx -t and systemctl reload nginx (or equivalent) to test and apply changes.

Step-by-Step

  1. Identify the RewriteRule lines. Open your .htaccess file and locate all lines that start with RewriteRule. Also note any RewriteCond lines that precede them, as these conditions must be translated together with the rule they apply to. Ignore lines like RewriteEngine On (nginx always has rewriting enabled) and Options -Indexes (handled separately).
  2. Understand the Apache pattern syntax. Apache uses Perl-compatible regular expressions. Nginx also uses PCRE, so the pattern part of the rule (the first argument) is usually identical. The main differences are in the flags and the substitution. For example, ^/old/(.*)$ in Apache becomes ^/old/(.*)$ in nginx, but the replacement and flags change.
  3. Translate the substitution and flags. In Apache, RewriteRule ^old$ /new [R=301,L] means redirect the request for /old to /new with a 301 status and stop processing. In nginx, this becomes rewrite ^/old$ /new permanent;. The R=301 flag maps to permanent (or redirect for 302). The L flag is implicit in nginx—a rewrite stops processing further rewrites unless you use the last or break flag explicitly. Use break when the rewritten URI should be processed by the current location block, and last when it should be re-evaluated against other location blocks.
  4. Handle RewriteCond lines. Apache conditions use %{HTTP_HOST}, %{REQUEST_FILENAME}, and other server variables. In nginx, you use $host, -f for file existence, and -d for directory existence. For example, a common WordPress rule is:
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule . /index.php [L]
        

    In nginx, this becomes:

        location / {
            try_files $uri $uri/ /index.php?$args;
        }
        

    The try_files directive is the nginx idiomatic way to handle this pattern, so you don’t need to write explicit rewrite rules for it.

  5. Place the rules in the correct location block. Nginx rewrites are usually placed inside a location block. If your rules apply to all requests, put them in the location / block. If they only apply to a specific path, create a location block for that path. For example, RewriteRule ^/blog/(.*)$ /articles/$1 [L] would go inside location /blog/ { ... }.
  6. Convert query string redirects. Apache uses RewriteCond %{QUERY_STRING} combined with a rule to redirect based on query parameters. In nginx, you can use the $args variable or the if directive. For example, to redirect index.php?id=5 to /page/5/:
        if ($args ~ "id=(\d+)") {
            set $page_id $1;
            rewrite ^/index\.php$ /page/$page_id? permanent;
        }
        

    Note that using if in nginx is discouraged except for specific cases like this, so keep it minimal.

  7. Test the configuration. Before reloading, run nginx -t to check for syntax errors. If it passes, reload nginx with systemctl reload nginx (or service nginx reload). Then test the URLs manually with curl -I to verify the redirects and rewrites work as expected.
  8. Repeat for each rule. Go through your .htaccess file rule by rule, translating each one. Keep a checklist to ensure you haven’t missed any. Pay special attention to rules that use RewriteBase—you may need to adjust paths in nginx to match the server root.

Common Mistakes

  • Forgetting the leading slash. Apache patterns often assume the leading slash is stripped. In nginx, the URI always includes the leading slash, so ^old$ in Apache becomes ^/old$ in nginx.
  • Using last instead of break. If you use last in a rewrite inside a location block, nginx will restart the location matching process, which can lead to unexpected behavior or infinite loops. Use break when you want the rewritten URI to be processed by the same location block.
  • Overusing the if directive. Nginx’s if is not a general-purpose conditional. It can cause issues like unexpected redirects or broken rewrites. Prefer try_files or separate location blocks whenever possible.
  • Ignoring the proxy_pass interaction. If you have a reverse proxy setup, rewrites that change the URI will affect what gets proxied. Make sure your rewrite rules are in the correct location block and that the proxy_pass directive uses the rewritten URI as intended.
  • Not testing with query strings. A rewrite that works for a clean URL may fail when query parameters are present. Always test with curl -I 'http://example.com/page?param=value' to see the full behavior.

Tips

  • Use a staging environment. Test your nginx configuration on a development server or a local nginx instance before applying it to production. This avoids downtime and lets you experiment freely.
  • Comment your rules. Add comments in your nginx config to explain what each rewrite does, especially if you’re converting a complex .htaccess file. This will save you time when debugging later.
  • Check for WordPress-specific patterns. If you’re converting a WordPress site, the standard .htaccess rules are almost always handled by try_files $uri $uri/ /index.php?$args; in nginx. You rarely need to write explicit rewrite rules for WordPress.
  • Use regex101.com to test your patterns. Before putting a pattern into nginx, verify it matches exactly what you expect using an online regex tester. This is especially helpful for complex patterns with capture groups.
  • Keep a backup. Always back up your nginx configuration file before making changes. A simple cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak can save you from a major headache.

Troubleshooting

  • Redirect loop. If you see a redirect loop error, check that your rewrite rule isn’t matching the rewritten URI. For example, if you rewrite /old to /new, make sure the rule for /new doesn’t also match /old. Add a condition like if ($request_uri !~* ^/new) or use a more specific pattern.
  • 404 errors after conversion. This usually means the rewrite rule isn’t being applied at all. Check that the rewrite is inside the correct location block and that the pattern matches the actual request URI. Use curl -I to see what nginx returns.
  • Rules work but query strings are lost. In nginx, when you use rewrite, the original query string is preserved by default unless you add a ? at the end of the replacement. If you want to discard the query string, add a trailing ? to the replacement. For example, rewrite ^/old$ /new? permanent; discards the original query string.
  • HTTPS redirects not working. If you have a rule that redirects HTTP to HTTPS, make sure it’s in a server block that listens on port 80. A common mistake is placing it in the HTTPS server block, causing an infinite loop.
  • Nginx won’t reload. Run nginx -t to see the syntax error. Common issues include missing semicolons, unclosed braces, or using an invalid variable name. Fix the error and test again.

Frequently Asked Questions

Can I use .htaccess directly in nginx?

No. Nginx does not read .htaccess files. You must translate the rules into nginx’s configuration syntax. There are online converters, but they are often incomplete, so manual translation is recommended for accuracy.

What does the L flag in Apache mean in nginx?

The L (last) flag tells Apache to stop processing further rules. In nginx, this is the default behavior for a rewrite directive—it stops processing further rewrites in the same location block. If you need to restart location matching, use last; if you want to continue in the same block, use break.

How do I handle a 301 redirect with a query string in nginx?

Use the $args variable to capture the query string and append it to the new URL. For example: rewrite ^/old$ /new?$args permanent;. If you want to drop the query string, omit $args and add a trailing ? to the replacement.

Why do I get a 500 error after converting?

This usually indicates a syntax error in the nginx configuration. Run nginx -t to see the exact error message. Common causes include missing semicolons, unclosed parentheses in regex, or using an undefined variable.

Is there an automatic converter tool I can use?

There are several online tools that attempt to convert .htaccess rules to nginx, such as winginx.com/en/htaccess. However, they often fail on complex rules or flags. Use them as a starting point, but always manually verify and test each rule.

What about RewriteBase?

RewriteBase is used in Apache to set the base URL for relative substitutions. In nginx, this is not needed because the substitution is always relative to the server root or the location block. Simply adjust the paths in your rewrite rules to be absolute (starting with /) or relative to the location block.

Related

Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.

More cards in this drawer

The whole Numbers and Powers drawer →