.htaccess Redirect Generator

Turn a list of old and new URLs into tested 301 rules for .htaccess or Nginx, with HTTPS, www and domain moves in one hop, and automatic checks for chains and loops.

Separate with a space, tab, comma or ->. Paste two columns from Excel or a CSV. Full URLs or paths. * at the end moves a whole folder. Leave the new URL empty, or write gone, for 410. Add 302 after a pair to change just that line.

Try:
Whole site
Matching options

      Test every redirect in the list

      Runs entirely in your browser. Your URLs aren’t sent to DanialTV. Always keep a copy of your old .htaccess before changing it.

      How to use the rules

      1. Enter your domain and paste your old and new URLs. Turn on the whole-site rules you need.
      2. Fix anything the yellow notes point out, and use Test a URL to check a few addresses.
      3. In cPanel File Manager, open your site’s main folder, tick Show Hidden Files in Settings, and download a copy of .htaccess first.
      4. Edit .htaccess and paste the rules at the very top, above # BEGIN WordPress. Save it as UTF-8.
      5. Open a few old URLs in a private window, or check them from a terminal: curl -sI http://www.example.com/old-page/. You want one 301 line and a location: with the final address.

      Why above # BEGIN WordPress? WordPress’s own block sends every request that isn’t a real file to index.php. Rules placed after it never get a chance to run. And WordPress rewrites everything between its # BEGIN and # END markers when you save permalinks, so anything you put inside is lost.

      Tested on a real server

      A generator is only useful if its output works. I put the rules this tool makes into a test folder on this site’s LiteSpeed server and requested each old URL. All 14 cases ended at the expected address:

      CaseRequestResult
      With and without trailing slash/old-page, /old-page/Both → /new-page/
      Upper case/OLD-PAGE→ /new-page/
      Persian source/سلام-دنیا/→ /hello/
      Persian target/to-persian→ /دنیا/, correctly encoded, not %25D8
      Specific query string/page.php?id=5 and ?id=6id=5 → /contact/ with no query; id=6 untouched
      Visitor’s query kept/promo?ref=1→ /sale?ref=1
      Whole folder/category/news/2026/x/?a=1→ /news/2026/x/?a=1
      Folder with Persian inside/category/news/سلام/→ /news/سلام/
      Persian folder target with a space/fa-old/a b/→ /فارسی/a%20b/
      Deleted page/deleted410 Gone
      Space in the old URL/my page→ /my-page/
      Target with its own query/old-search→ /search/?q=a+b&x=%2F, unchanged

      The logic behind the tool is also covered by 48 automated tests, and the Test a URL box follows the same rules, so you can check your own list before it goes live.

      Which status code?

      CodeUse it when
      301The page moved for good: new slug, new structure, new domain. Google moves rankings to the new URL. This is the one you want almost every time.
      302 / 307Short-term: a sale page, maintenance, an A/B test. Google keeps the old URL indexed.
      308Like 301, but a form sent with POST is resent with POST. Useful for APIs; for normal pages 301 is fine.
      410The page is gone on purpose and has no replacement. Better than redirecting everything to the home page, which Google treats as a soft 404 anyway.

      5 mistakes the tool prevents

      1. Redirect chains

      After a few redesigns, lists end up with /a → /b and /b → /c. Every extra hop costs time and Google follows only a limited number. With Fix redirect chains on, /a goes straight to /c. The same goes for the site-wide rules: an old URL requested as http://www. would normally hop to https://, then to the non-www host, then to the new page. Because page redirects come first and point at the final https:// address, it’s one hop.

      2. Loops

      /x → /y and /y → /x, or a page redirected to itself with a different slash, end in “too many redirects”. The tool finds circles, says which lines cause them and leaves them out.

      3. Old URLs with ?id= that never redirect

      RewriteRule and Redirect never see the query string, so a rule for /page.php?id=5 written the obvious way does nothing. The tool adds a RewriteCond %{QUERY_STRING} line and the QSD flag, so ?id=5 isn’t carried over to the new URL.

      4. Persian, Arabic and other non-English URLs

      Apache and LiteSpeed decode the URL before matching, so the old address must be written with readable letters (^سلام-دنیا/?$), not %D8%B3…. That’s why you can paste either form here: the tool decodes it. The new address goes the other way: it’s written encoded with the NE flag. Without NE, Apache encodes the % signs again and visitors land on a double-encoded %25D8%25B3… URL that gives a 404. If you’ve seen that, the URL encoder & decoder shows what happened.

      5. Redirect loops behind Cloudflare

      With Cloudflare’s Flexible SSL, visitors use https but Cloudflare talks to your server over plain http. A normal “force HTTPS” rule sees http every time and redirects forever. Tick Behind Cloudflare or a proxy and the rule checks the X-Forwarded-Proto header instead. Better still, switch Cloudflare to Full (strict) SSL.

      Why RewriteRule instead of Redirect?

      Many guides use the shorter Redirect 301 /old /new. It works for simple cases, but it matches the beginning of the path, so Redirect 301 /blog /news also sends every /blog/any-post to /news/any-post, and it can’t look at query strings. RewriteRule with ^…$ matches exactly the page you listed, handles query strings and runs alongside WordPress’s own rewrite rules, which is why every rule here uses it.

      Trailing slash and WordPress

      WordPress already redirects posts and pages to the form set in Settings → Permalinks: if the structure ends with /, /my-post is sent to /my-post/. Only add a trailing-slash rule if it matches that setting, otherwise the server and WordPress keep sending visitors back and forth. The rules here skip wp-admin, wp-json and real files.

      Nginx

      Nginx ignores .htaccess files. The Nginx tab uses a map on $request_uri, which scales to thousands of redirects without slowing the server, plus return lines in the server block. $request_uri is the address exactly as the browser sent it, still encoded, so Persian URLs are matched in their %D8… form; the tool does that conversion for you. After editing, run nginx -t before reloading.

      FAQ

      .htaccess or a redirect plugin?

      .htaccess redirects run before WordPress loads, so they’re faster and keep working even if a plugin breaks. A plugin like Redirection is easier to edit and logs 404s, but every redirect goes through PHP. For a big one-off move, such as a redesign or a new domain, I use .htaccess.

      My site shows error 500 after saving .htaccess

      Upload your backup copy, then add the rules again in smaller parts to find the line. The most common causes are editing the file in a word processor (curly quotes) or saving it with a BOM. Use a plain-text editor, or the cPanel editor.

      How long should redirects stay?

      Google recommends keeping them for at least a year. In practice, keep them as long as old links point to those URLs: backlinks, bookmarks and old social posts don’t update themselves.

      More free tools: the URL & domain extractor pulls every link out of an old sitemap or a crawl export, ready to paste here, and the robots.txt tester checks that Google may crawl the new URLs.