How to Use .htaccess and Nginx for URL Redirection


Redirecting URLs is a critical skill for managing website traffic and ensuring a seamless user experience. Using an .htaccess file or Nginx configuration, you can easily create redirects to handle URL changes, enforce HTTPS, or switch domains without losing search engine rankings. This guide provides step-by-step examples of common redirect techniques for both .htaccess and Nginx, covering single-page redirects, complex query string handling, and more.

Why Use .htaccess Redirects?

Redirects help maintain SEO rankings, fix broken links, and enhance user navigation. With .htaccess, you can set up server-side redirects efficiently without modifying your application code.

Redirecting a Single URL

Redirecting a specific page to another is straightforward using .htaccess. For example, redirecting /old-page.html to /new-page.html can be done with the following line of code:

Apache
# Permanent 301 Redirect for a Specific Page
# - Redirects /old-page.html to a new URL

Redirect 301 /old-page.html https://example.com/new-page.html
Nginx
location /old-page.html {
    return 301 https://example.com/new-page.html;
}

Remember to:

  • Test your configuration with sudo nginx -t
  • Reload Nginx after making changes with sudo systemctl reload nginx
  • 301 indicates a permanent redirect.
  • Replace /old-page.html with the old path and https://example.com/new-page.html with the new URL.

The 301 status code signals search engines that the change is permanent. Browsers and search engines will cache this redirect

Redirect HTTP to HTTPS and WWW

Redirect HTTP to HTTPS and WWW Using .htaccess

Redirect All URLs to a New Domain

If you are migrating from an old domain to a new one, you can redirect all traffic:

Apache
# Domain Redirect
# Redirects multiple domain variations to a new primary domain
# - Handles both naked domain and www subdomain
# - [NC] flag makes the match case-insensitive
# - [OR] allows checking multiple conditions before applying the rule
# - [R=301] creates a permanent redirect (SEO-friendly)

RewriteEngine On

# Catch requests to old domain (without www)
RewriteCond %{HTTP_HOST} ^oldexample\.com$ [NC,OR]

# Catch requests to old domain with www
RewriteCond %{HTTP_HOST} ^www\.oldexample\.com$ [NC]

# Redirect to new domain, maintaining original path
RewriteRule ^(.*)$ https://www.newexample.com/$1 [L,R=301,NC]
Nginx
server {
    server_name oldexample.com www.oldexample.com;
    return 301 https://www.newexample.com$request_uri;
}
  • Replace oldexample.com with the old domain.
  • Replace newexample.com with the target domain.

Examples of how it works:

  • http://oldexample.com/productshttps://www.newexample.com/products
  • https://www.oldexample.com/abouthttps://www.newexample.com/about

Handling Query Strings in Redirects

Query strings are the part of a URL that follows the ?, often used to pass data to web pages (e.g., example.com/page?id=123). When creating .htaccess redirects, you can choose to preserve or remove query strings based on your requirements.

Preserve Query Strings in Redirects

Redirect all requests from /search to /new-search, keeping any query strings:

Apache
RewriteEngine On
# Match only exact /search path
RewriteCond %{REQUEST_URI} ^/search$

# Redirect to new search page, preserving query parameters
RewriteRule ^(.*)$ /new-search?$1 [L,R=301]
Nginx
location = /search {
    return 301 /new-search?$query_string;
}

Example

  • Original URL: https://example.com/search?q=redirect
  • Redirects to: https://example.com/new-search?q=redirect

Remove Query Strings in Redirects

To redirect a URL and discard the query string, append a ? at the end of the new URL.

Redirect /page to /new-page, dropping any query strings:

Apache
RewriteEngine On
RewriteRule ^page$ /new-page? [L,R=301]
  • Original URL: https://example.com/page?id=123
  • Redirects to: https://example.com/new-page

Conditional Redirect Based on Query Strings

To redirect only when a specific query string is present:

Example:

Redirect /page to /new-page only if id=123 is in the query string:

Apache
# Conditional Redirect Based on Specific Query Parameter
# Redirects a page only when a specific query parameter matches
# - Checks if query string exactly matches 'id=123'
# - Redirects '/page' to '/new-page' only for this specific condition

RewriteEngine On
# Condition: Check if query string is exactly 'id=123'
RewriteCond %{QUERY_STRING} ^id=123$

# Redirect rule for the specific page
RewriteRule ^page$ /new-page? [L,R=301]
Nginx
location /page {
    if ($query_string = "id=123") {
        return 301 /new-page?;
    }
}

Example in Action:

  • Original URL: /page?id=123 Redirects to: /new-page
  • /page?id=456 → (no redirect)
  • Other query strings will not trigger this redirect.

Rewriting URLs with Multiple Query Parameters

To improve the readability and SEO of URLs with multiple query parameters, you can rewrite them into a more user-friendly format.

For example, you can rewrite /product.php?id=123&category=electronics into /product/123/electronics. Here is how to set it up using .htaccess:

Apache
RewriteEngine On
# Rewrite /product/{id}/{category} to /product.php?id={id}&category={category}
RewriteRule ^product/([0-9]+)/([a-zA-Z0-9_-]+)$ product.php?id=$1&category=$2 [L,QSA]
Nginx
location ~ ^/product/([0-9]+)/([a-zA-Z0-9_-]+)$ {
    rewrite ^/product/([0-9]+)/([a-zA-Z0-9_-]+)$ /product.php?id=$1&category=$2 last;
}

Behavior:

  • User Visits: /product/123/electronics
  • Server Internally Loads: /product.php?id=123&category=electronics
  • Address Bar Shows: /product/123/electronics
  • /product/42/computers → internally serves /product.php?id=42&category=computers

Redirect All Traffic to a Specific Page

Redirects all site traffic to a single page (e.g., maintenance):

Apache
# Enable Maintenance Mode Redirect
# This rule redirects ALL incoming requests to a maintenance page
# - Useful when performing site-wide updates or maintenance
# - [L] flag ensures no further rules are processed
# - [R=302] creates a temporary redirect (browser keeps original URL in address bar)
# - Replace 'https://www.example.com/maintenance.html' with your actual maintenance page URL

RewriteEngine On
RewriteRule ^(.*)$ https://www.example.com/maintenance.html [L,R=302]
Nginx
server {
    listen 80;
    listen 443 ssl;
    server_name _;

    location / {
        return 302 https://www.example.com/maintenance.html;
    }
}

Use R=302 for a temporary redirect.

Redirects every single request to the maintenance page

Redirect Without Changing URL

Internally redirect without showing the new URL in the browser:

Apache
RewriteEngine On

# Redirects all content from 'old-path' to 'new-path'
RewriteRule ^old-path/(.*)$ /new-path/$1 [L]
Nginx
location /old-path/ {
    rewrite ^/old-path/(.*)$ /new-path/$1 last;
}

How this works:

  1. Matches any URL starting with /old-path/
  2. Captures everything after old-path/
  3. Internally rewrites to /new-path/ while preserving the rest of the path

Examples:

  • /old-path/document.pdf → internally serves /new-path/document.pdf
  • /old-path/images/logo.png → internally serves /new-path/images/logo.png
  • /old-path/subdir/page.html → internally serves /new-path/subdir/page.html

Redirecting to a Hidden File Path

Example: If your website has an admin panel located at /admin/dashboard.php, but you want users to access it via /dashboard

Apache
RewriteEngine On
RewriteRule ^dashboard$ /admin/dashboard.php [L]
Nginx
location = /dashboard {
    rewrite ^/dashboard$ /admin/dashboard.php last;
}

How this works:

  1. Matches exactly /dashboard
  2. Internally rewrites to /admin/dashboard.php
  3. Ensures only the exact path is matched

Examples:

  • User URL: https://example.com/dashboard
  • Server Serves Content From: /admin/dashboard.php
  • Address Bar Stays As: https://example.com/dashboard
  • /dashboard/ → (will not match)
  • /dashboard/extra → (will not match)

Rewriting Dynamic Query Parameter

Your website uses dynamic query parameters like /product.php?id=123. You want users to access products using /product/123.

Apache
RewriteEngine On

# Converts clean URL format
# - Matches URLs in the format /product/{numeric-id}
# Capture numeric ID from URL and pass to product.php
# ([0-9]+) ensures only numeric IDs are matched
RewriteRule ^product/([0-9]+)$ /product.php?id=$1 [L]
Nginx
location ~ ^/product/([0-9]+)$ {
    rewrite ^/product/([0-9]+)$ /product.php?id=$1 last;
}

How this works:

  1. Matches URLs like /product/123
  2. Internally rewrites to /product.php?id=123
  3. Captures only numeric IDs

Examples:

  • User URL: https://example.com/product/123
  • Server Serves Content From: /product.php?id=123
  • Address Bar Stays As: https://example.com/product/123
  • /product/7890 → internally serves /product.php?id=7890

Virtual Paths for Organization

You have images stored in /assets/images/, but you want users to access them via /images.

Apache
RewriteEngine On

# Rewrite any request from /images/* to /assets/images/*
# Captures everything after 'images/' and maintains it in the new path
RewriteRule ^images/(.*)$ /assets/images/$1 [L]
Nginx
location /images/ {
    rewrite ^/images/(.*)$ /assets/images/$1 last;
}

How this works:

  1. Matches any path starting with /images/
  2. Internally rewrites to /assets/images/
  3. Preserves the rest of the path/filename

Examples:

  • User URL: https://example.com/images/photo.jpg
  • Server Serves Content From: /assets/images/photo.jpg
  • Address Bar Stays As: https://example.com/images/photo.jpg
  • /images/product.jpg → internally serves /assets/images/product.jpg
  • /images/category/banner.png → internally serves /assets/images/category/banner.png

Differences Between 301 and 302 Redirects

When configuring URL redirection using .htaccess, it is essential to choose the correct type of redirect based on your goals. The two most common types are 301 and 302 redirects. Here is a breakdown of their differences:

What is a 301 Redirect?

A permanent redirect, indicated by the status code 301, tells browsers and search engines that a URL has permanently moved to a new location. It transfers the SEO value of the old URL to the new one, ensuring your website maintains its search engine rankings.

Use Cases:

  • When restructuring your website’s URLs.
  • Changing a domain name.
  • Permanently redirecting outdated pages.

Rule:

Apache
Redirect 301 /old-page.html /new-page.html

What is a 302 Redirect?

A temporary redirect, indicated by the status code 302 (or 307 in some cases), tells browsers and search engines that the move is temporary. Unlike 301, it does not pass SEO value to the new URL.

Use Cases:

  • When performing website maintenance.
  • Testing new pages before making them permanent.
  • Temporarily redirecting users during A/B testing.

Rule:

Apache
Redirect 302 /old-page.html https://www.example.com/maintenance-page.html

Key Differences Between 301 and 302 Redirects

Feature301 (Permanent Redirect)302 (Temporary Redirect)
PurposePermanent moveTemporary move
SEO Value TransferYesNo
Browser CacheCached permanentlyNot cached or temporarily cached

Conclusion:

Choosing between a 301 and 302 redirect depends on whether the change is permanent or temporary. Misusing these redirects can affect your website's SEO and user experience. Always test your redirects to ensure they function as intended.