⚙️ Technical Implementation
Complete guide to implementing 301 redirects across different server configurations and platforms
📚 Table of Contents
🔧 Apache .htaccess Implementation
💡 Most Popular Method
.htaccess redirects work on Apache servers and are the most commonly used method for implementing 301 redirects. They're processed at the server level for optimal performance.
📋 Basic Setup Requirements
Locate .htaccess File
Find the .htaccess file in your website's root directory (public_html, www, or similar)
Create Backup
Always backup your existing .htaccess file before making changes
Verify mod_rewrite
Ensure mod_rewrite is enabled on your server (most hosts enable this by default)
Test in Staging
Always test redirects in a staging environment before implementing on live site
🎯 Single Page Redirects
The simplest form of redirects for individual pages:
# Simple page redirect
Redirect 301 /old-page.html /new-page.html
# Multiple page redirects
Redirect 301 /old-about.html /about
Redirect 301 /old-contact.php /contact
Redirect 301 /products/old-item /products/new-item
# Redirect with file extensions
Redirect 301 /old-page.htm /new-page.html
🌐 Domain-Level Redirects
Redirect entire domains while preserving URL structure:
# Redirect entire domain to new domain
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www\.)?olddomain\.com$ [NC]
RewriteRule ^(.*)$ https://newdomain.com/$1 [R=301,L]
# Redirect old domain to specific page on new domain
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www\.)?olddomain\.com$ [NC]
RewriteRule ^(.*)$ https://newdomain.com/welcome [R=301,L]
🔐 HTTP to HTTPS Redirects
Force secure connections across your entire site:
# Method 1: Standard HTTPS redirect
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# Method 2: Alternative for some servers
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.yourdomain.com/$1 [R=301,L]
# Method 3: For Cloudflare users
RewriteEngine On
RewriteCond %{HTTP:CF-Visitor} '"scheme":"http"'
RewriteRule ^(.*)$ https://yourdomain.com/$1 [L,R=301]
🌍 WWW Canonicalization
Choose between www and non-www versions of your site:
# Redirect www to non-www
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.yourdomain\.com$ [NC]
RewriteRule ^(.*)$ https://yourdomain.com/$1 [R=301,L]
# Redirect non-www to www
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
📂 Trailing Slash Management
Maintain consistency in URL structure:
# Remove trailing slash
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} ^(.+)/$
RewriteRule ^(.*)$ /$1 [R=301,L]
# Add trailing slash
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ /$1/ [L,R=301]
🔄 Pattern-Based Redirects
Use patterns and wildcards for multiple similar redirects:
# Redirect by file extension
RedirectMatch 301 ^(.*)\.html$ /$1.php
# Redirect category structure
RedirectMatch 301 ^/old-category/(.*)$ /new-category/$1
# Redirect with parameters
RewriteEngine On
RewriteCond %{QUERY_STRING} ^id=([0-9]+)$
RewriteRule ^product\.php$ /products/%1? [R=301,L]
# Date-based blog redirects
RedirectMatch 301 ^/([0-9]{4})/([0-9]{2})/(.*)$ /blog/$3
⚠️ Common .htaccess Mistakes
- Order Matters: Place specific redirects before general rules
- Infinite Loops: Test redirects to prevent circular redirections
- Missing Flags: Always use [R=301,L] for permanent redirects
- Case Sensitivity: Use [NC] flag for case-insensitive matching
- Special Characters: Escape dots and other regex characters
📄 Complete .htaccess Example
A comprehensive example showing proper order and structure:
# Complete .htaccess example with multiple redirects
RewriteEngine On
# 1. Force HTTPS first
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# 2. Force www (or remove based on preference)
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
# 3. Remove trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} ^(.+)/$
RewriteRule ^(.*)$ /$1 [R=301,L]
# 4. Specific page redirects (before general rules)
Redirect 301 /old-page /new-page
Redirect 301 /old-about /about
Redirect 301 /contact-us /contact
# 5. Category redirects
RedirectMatch 301 ^/old-blog/(.*)$ /blog/$1
# 6. WordPress rules (always last)
# BEGIN WordPress
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress
🌐 Nginx Configuration
⚡ High Performance
Nginx redirects are processed at the server level and are typically faster than .htaccess redirects. Perfect for high-traffic websites.
📍 Simple Page Redirects
# Simple page redirect
location /old-page {
return 301 /new-page;
}
# Multiple specific redirects
location /old-about {
return 301 /about;
}
location /old-contact {
return 301 /contact;
}
# Exact match redirect
location = /old-exact-page {
return 301 /new-exact-page;
}
🌐 Domain-Level Nginx Redirects
# Redirect entire domain
server {
listen 80;
server_name olddomain.com www.olddomain.com;
return 301 https://newdomain.com$request_uri;
}
# Redirect with path preservation
server {
listen 80;
listen 443 ssl;
server_name olddomain.com;
return 301 https://newdomain.com$request_uri;
}
🔐 HTTPS and WWW Nginx Redirects
# Force HTTPS
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
return 301 https://$server_name$request_uri;
}
# Force www
server {
listen 80;
listen 443 ssl;
server_name yourdomain.com;
return 301 https://www.yourdomain.com$request_uri;
}
# Remove www
server {
listen 80;
listen 443 ssl;
server_name www.yourdomain.com;
return 301 https://yourdomain.com$request_uri;
}
🔄 Pattern-Based Nginx Redirects
# Redirect with regex
location ~ ^/old-category/(.*)$ {
return 301 /new-category/$1;
}
# Redirect based on file extension
location ~ ^(.*)\.html$ {
return 301 $1.php;
}
# Complex redirect with conditions
location /products {
if ($args ~ "^id=([0-9]+)$") {
set $product_id $1;
return 301 /products/$product_id;
}
return 301 /products/;
}
📄 Complete Nginx Server Block
# Complete nginx configuration example
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
return 301 https://www.yourdomain.com$request_uri;
}
server {
listen 443 ssl http2;
server_name yourdomain.com;
return 301 https://www.yourdomain.com$request_uri;
}
server {
listen 443 ssl http2;
server_name www.yourdomain.com;
# SSL configuration
ssl_certificate /path/to/certificate.crt;
ssl_certificate_key /path/to/private.key;
# Specific page redirects
location /old-page { return 301 /new-page; }
location /old-about { return 301 /about; }
# Pattern redirects
location ~ ^/old-blog/(.*)$ {
return 301 /blog/$1;
}
# Main site configuration
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# PHP processing
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
}
}
🐘 PHP Implementation
💻 Dynamic Redirects
PHP redirects are useful for dynamic content and when server configuration access is limited. They're processed at the application level.
📜 Basic PHP Redirect Syntax
<?php
// Simple 301 redirect
header('HTTP/1.1 301 Moved Permanently');
header('Location: https://newdomain.com/new-page');
exit();
?>
// Alternative shorter syntax
<?php
header('Location: https://newdomain.com/new-page', true, 301);
exit();
?>
🎯 Conditional PHP Redirects
<?php
// Redirect based on specific page
if ($_SERVER['REQUEST_URI'] == '/old-page/') {
header('Location: https://yourdomain.com/new-page/', true, 301);
exit();
}
// Redirect based on URL parameter
if (isset($_GET['old_param'])) {
$new_url = 'https://yourdomain.com/new-page/';
header('Location: ' . $new_url, true, 301);
exit();
}
// Multiple redirect conditions
$redirects = [
'/old-about/' => '/about/',
'/old-contact/' => '/contact/',
'/old-services/' => '/services/',
];
$current_uri = $_SERVER['REQUEST_URI'];
if (array_key_exists($current_uri, $redirects)) {
header('Location: https://yourdomain.com' . $redirects[$current_uri], true, 301);
exit();
}
?>
🔄 Advanced PHP Redirect System
<?php
// Advanced redirect system with database or array
class RedirectManager {
private $redirects = [
'/old-product-1/' => '/products/new-product-1/',
'/old-category/' => '/categories/new-category/',
'/legacy/page/' => '/modern/page/',
];
public function handleRedirect() {
$current_uri = $_SERVER['REQUEST_URI'];
$current_uri = rtrim($current_uri, '/') . '/'; // Normalize trailing slash
if (isset($this->redirects[$current_uri])) {
$this->redirect301($this->redirects[$current_uri]);
}
// Check for pattern matches
foreach ($this->redirects as $pattern => $destination) {
if (strpos($pattern, '*') !== false) {
$regex = str_replace('*', '(.*)', preg_quote($pattern, '/'));
if (preg_match('/^' . $regex . '$/', $current_uri, $matches)) {
$final_url = str_replace('$1', $matches[1], $destination);
$this->redirect301($final_url);
}
}
}
}
private function redirect301($url) {
header('HTTP/1.1 301 Moved Permanently');
header('Location: https://yourdomain.com' . $url);
exit();
}
}
// Usage
$redirectManager = new RedirectManager();
$redirectManager->handleRedirect();
?>
🌐 WordPress-Specific PHP Redirects
<?php
// Add to functions.php for WordPress redirects
function custom_redirects() {
$current_url = $_SERVER['REQUEST_URI'];
// Old blog structure to new structure
if (preg_match('/^\/(\d{4})\/(\d{2})\/(.+)\/$/', $current_url, $matches)) {
$year = $matches[1];
$month = $matches[2];
$slug = $matches[3];
wp_redirect(home_url('/blog/' . $slug . '/'), 301);
exit();
}
// Specific page redirects
$redirects = [
'/old-page/' => '/new-page/',
'/legacy-contact/' => '/contact/',
];
if (array_key_exists($current_url, $redirects)) {
wp_redirect(home_url($redirects[$current_url]), 301);
exit();
}
}
add_action('template_redirect', 'custom_redirects');
?>
🖥️ Server-Level Redirects
🎛️ cPanel Redirect Setup
Access cPanel
Navigate to "Domains" → "Redirects"
Select Redirect Type
Choose "Permanent (301)"
Choose Domain
Select the domain to redirect from
Enter Path
Add specific path if redirecting individual pages
Set Destination
Enter the complete destination URL
Save Settings
Click "Add" to implement the redirect
⚠️ cPanel Limitation
cPanel redirects are added to the end of .htaccess file and may not work properly with WordPress or other CMS systems that have their own rewrite rules.
⚙️ IIS Web.config Redirects
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<!-- Force HTTPS -->
<rule name="Redirect to HTTPS" stopProcessing="true">
<match url="^(.*)$" />
<conditions>
<add input="{HTTPS}" pattern="^OFF$" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}"
redirectType="Permanent" />
</rule>
<!-- Remove www -->
<rule name="Remove WWW" stopProcessing="true">
<match url="^(.*)$" />
&