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.
Contents
- Redirecting Single URL
- Redirect All URLs to New Domain
- Handle Query Strings in Redirects
- Rewriting URLs with Multiple Query Parameters
- Redirect All Traffic to Specific Page
- Redirecting to a Hidden File Path
- Rewriting Dynamic Query Parameter
- Virtual Paths for Organization
- Differences Between 301 and 302 Redirect
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:
# 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
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 andhttps://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:
# 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]
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/products
→https://www.newexample.com/products
https://www.oldexample.com/about
→https://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:
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]
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:
- 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:
# 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]
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:
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]
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):
# 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]
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:
RewriteEngine On
# Redirects all content from 'old-path' to 'new-path'
RewriteRule ^old-path/(.*)$ /new-path/$1 [L]
How this works:
- Matches any URL starting with
/old-path/
- Captures everything after
old-path/
- 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
How this works:
- Matches exactly
/dashboard
- Internally rewrites to
/admin/dashboard.php
- 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
.
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]
How this works:
- Matches URLs like
/product/123
- Internally rewrites to
/product.php?id=123
- 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
.
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]
How this works:
- Matches any path starting with
/images/
- Internally rewrites to
/assets/images/
- 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:
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:
Key Differences Between 301 and 302 Redirects
Feature | 301 (Permanent Redirect) | 302 (Temporary Redirect) |
---|---|---|
Purpose | Permanent move | Temporary move |
SEO Value Transfer | Yes | No |
Browser Cache | Cached permanently | Not 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.