
{"id":30207,"date":"2026-04-09T13:36:04","date_gmt":"2026-04-09T11:36:04","guid":{"rendered":"https:\/\/contabo.com\/blog\/?p=30207"},"modified":"2026-04-24T13:45:40","modified_gmt":"2026-04-24T11:45:40","slug":"nginx-redirect-guide","status":"publish","type":"post","link":"https:\/\/contabo.com\/blog\/nginx-redirect-guide\/","title":{"rendered":"Nginx Redirect Guide: 301, 302, Rewrite Rules"},"content":{"rendered":"\n<p>Setting up an nginx redirect wrong doesn&#8217;t just frustrate users. It tanks your SEO rankings, creates redirect loops that crash browsers, and leaves old URLs returning 200s when they shouldn&#8217;t. Get the directives right the first time.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-what-is-an-nginx-redirect\">What Is an Nginx Redirect?<\/h2>\n\n\n\n<p>An nginx redirect is a server-side configuration that sends visitors and search engines from one URL to another. Nginx evaluates incoming requests against server blocks and location blocks, then decides whether to serve content, proxy it, or redirect it to a new destination.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-301-vs-302-which-one-to-use\">301 vs 302: Which One to Use<\/h3>\n\n\n\n<p>301 is permanent. Use it when a URL has moved forever and you want search engines to transfer ranking signals to the new location. 302 is temporary. Use it for maintenance windows, A\/B testing, or situations where the original URL will return. Browsers cache 301s aggressively, so don&#8217;t use them for anything you might reverse.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-prerequisites-and-file-locations\">Prerequisites and File Locations<\/h3>\n\n\n\n<p>You need root or sudo access to edit nginx configuration files. The main config lives at \/etc\/nginx\/nginx.conf. Site-specific configs go in \/etc\/nginx\/sites-available\/, with symlinks in \/etc\/nginx\/sites-enabled\/ to activate them. Always back up before editing:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo cp \/etc\/nginx\/nginx.conf \/etc\/nginx\/nginx.conf.bak<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-how-to-configure-nginx-redirects\">How to Configure Nginx Redirects<\/h2>\n\n\n\n<p>Nginx offers three main directives for redirects: return, rewrite, and try_files. Each has a specific use case.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-using-the-return-directive\">Using the return Directive<\/h3>\n\n\n\n<p>The return directive is the most efficient option. It stops processing immediately and sends the status code and URL to the client. Syntax:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>return &#91;status_code] &#91;URL];<\/code><\/pre>\n\n\n\n<p>Example: redirect all traffic from an old domain to a new one:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>server { \u00a0 \u00a0 listen 80; \u00a0 \u00a0 server_name old-domain.com; \u00a0 \u00a0 return 301 https:\/\/new-domain.com$request_uri; }<\/code><\/pre>\n\n\n\n<p>The $request_uri variable preserves the path and query string, so \/blog\/post becomes https:\/\/new-domain.com\/blog\/post.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-using-the-rewrite-directive\">Using the rewrite Directive<\/h3>\n\n\n\n<p>The rewrite directive uses regex to match and transform URLs. It&#8217;s more flexible than return but slower and harder to debug:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>rewrite ^\/old-path(.*)$ \/new-path$1 permanent;<\/code><\/pre>\n\n\n\n<p>The permanent flag makes it a 301. Use redirect for 302. If you don&#8217;t need regex matching, use return instead. Rewrite rules evaluate in sequence and can trigger multiple rewrites per request.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-using-try-files-for-fallback-redirects\">Using try_files for Fallback Redirects<\/h3>\n\n\n\n<p>try_files checks for files in order and falls back to a specified location if none exist:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>location \/ { \u00a0 \u00a0 try_files $uri $uri\/ \/index.php?$query_string; }<\/code><\/pre>\n\n\n\n<p>This isn&#8217;t a traditional redirect but handles cases where clean URLs need to fall back to a front controller.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-common-nginx-redirect-use-cases\">Common Nginx Redirect Use Cases<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-redirect-http-to-https\">Redirect HTTP to HTTPS<\/h3>\n\n\n\n<p>The standard pattern for forcing HTTPS:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>server { \u00a0 \u00a0 listen 80; \u00a0 \u00a0 server_name example.com www.example.com; \u00a0 \u00a0 return 301 https:\/\/example.com$request_uri; }<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-redirect-www-to-non-www\">Redirect www to Non-www<\/h3>\n\n\n\n<p>Canonical redirect to strip the www subdomain:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>server { \u00a0 \u00a0 listen 443 ssl; \u00a0 \u00a0 server_name www.example.com; \u00a0 \u00a0 return 301 https:\/\/example.com$request_uri; }<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-redirect-a-specific-url-or-path\">Redirect a Specific URL or Path<\/h3>\n\n\n\n<p>Single URL redirect using a location block:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>location = \/old-page { \u00a0 \u00a0 return 301 \/new-page; }<\/code><\/pre>\n\n\n\n<p>The = modifier makes an exact match, which is faster than prefix or regex matching.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-redirect-an-entire-domain\">Redirect an Entire Domain<\/h3>\n\n\n\n<p>Catch-all redirect for domain migrations:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>server { \u00a0 \u00a0 listen 80; \u00a0 \u00a0 server_name old-site.com; \u00a0 \u00a0 return 301 https:\/\/new-site.com$request_uri; }<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-nginx-redirect-best-practices\">Nginx Redirect Best Practices<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-avoiding-redirect-chains-and-loops\">Avoiding Redirect Chains and Loops<\/h3>\n\n\n\n<p>A redirect chain is when URL A redirects to B, which redirects to C. Each hop adds latency and can confuse crawlers. Keep chains to a maximum of one redirect. A redirect loop is when A redirects to B and B redirects back to A, which kills the request entirely. Always test with curl:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>curl -I http:\/\/example.com<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-testing-your-configuration\">Testing Your Configuration<\/h3>\n\n\n\n<p>Before reloading nginx, validate the config:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo nginx -t<\/code><\/pre>\n\n\n\n<p>If it passes, reload without dropping connections:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo systemctl reload nginx<\/code><\/pre>\n\n\n\n<p>Never skip validation. A syntax error in the config file brings down the entire server.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-faq-nginx-redirect\">FAQ: Nginx Redirect<\/h2>\n\n\n\n<div class=\"schema-faq wp-block-yoast-faq-block\"><div class=\"schema-faq-section\" id=\"faq-question-1777030871469\"><strong class=\"schema-faq-question\">What is the difference between return and rewrite in nginx?<\/strong> <p class=\"schema-faq-answer\">return is faster because it stops processing immediately. rewrite runs through the full nginx processing cycle and supports regex transformations. Use return for simple redirects and rewrite only when you need regex-based URL manipulation.<\/p> <\/div> <div class=\"schema-faq-section\" id=\"faq-question-1777030882166\"><strong class=\"schema-faq-question\">How do I redirect HTTP to HTTPS in nginx?<\/strong> <p class=\"schema-faq-answer\">Add a server block listening on port 80 with: return 301 https:\/\/yourdomain.com$request_uri; That sends all HTTP traffic to the HTTPS equivalent permanently.<\/p> <\/div> <div class=\"schema-faq-section\" id=\"faq-question-1777030891839\"><strong class=\"schema-faq-question\">How do I redirect www to non-www in nginx?<\/strong> <p class=\"schema-faq-answer\">Create a server block for www.yourdomain.com and return 301 https:\/\/yourdomain.com$request_uri; Make sure your SSL certificate covers both the www and non-www versions.<\/p> <\/div> <div class=\"schema-faq-section\" id=\"faq-question-1777030900228\"><strong class=\"schema-faq-question\">How do I test nginx redirects without breaking production?<\/strong> <p class=\"schema-faq-answer\">Run sudo nginx -t to validate syntax. Then use curl -IL https:\/\/yourdomain.com\/path to trace the full redirect chain before reloading the live server.<\/p> <\/div> <\/div>\n","protected":false},"excerpt":{"rendered":"<p>Setting up an nginx redirect wrong doesn&#8217;t just frustrate users. It tanks your SEO rankings, creates redirect loops that crash browsers, and leaves old URLs returning 200s when they shouldn&#8217;t. Get the directives right the first time. What Is an Nginx Redirect? An nginx redirect is a server-side configuration that sends visitors and search engines [&hellip;]<\/p>\n","protected":false},"author":44,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"_uag_custom_page_level_css":"","site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"set","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[18],"tags":[],"ppma_author":[3402],"class_list":["post-30207","post","type-post","status-publish","format-standard","hentry","category-tutorials"],"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false},"uagb_author_info":{"display_name":"Milan Ivanovic","author_link":"https:\/\/contabo.com\/blog\/author\/milan\/"},"uagb_comment_info":0,"uagb_excerpt":"Setting up an nginx redirect wrong doesn&#8217;t just frustrate users. It tanks your SEO rankings, creates redirect loops that crash browsers, and leaves old URLs returning 200s when they shouldn&#8217;t. Get the directives right the first time. What Is an Nginx Redirect? An nginx redirect is a server-side configuration that sends visitors and search engines&hellip;","authors":[{"term_id":3402,"user_id":0,"is_guest":1,"slug":"contabro","display_name":"ContaBro","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/?s=96&d=mm&r=g","0":null,"1":"","2":"","3":"","4":"","5":"","6":"","7":"","8":""}],"_links":{"self":[{"href":"https:\/\/contabo.com\/blog\/wp-json\/wp\/v2\/posts\/30207","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/contabo.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/contabo.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/contabo.com\/blog\/wp-json\/wp\/v2\/users\/44"}],"replies":[{"embeddable":true,"href":"https:\/\/contabo.com\/blog\/wp-json\/wp\/v2\/comments?post=30207"}],"version-history":[{"count":1,"href":"https:\/\/contabo.com\/blog\/wp-json\/wp\/v2\/posts\/30207\/revisions"}],"predecessor-version":[{"id":30208,"href":"https:\/\/contabo.com\/blog\/wp-json\/wp\/v2\/posts\/30207\/revisions\/30208"}],"wp:attachment":[{"href":"https:\/\/contabo.com\/blog\/wp-json\/wp\/v2\/media?parent=30207"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/contabo.com\/blog\/wp-json\/wp\/v2\/categories?post=30207"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/contabo.com\/blog\/wp-json\/wp\/v2\/tags?post=30207"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/contabo.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=30207"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}