.htaccess might look like a mess of syntax at first glance, but it gives you a ridiculous amount of control over how your site behaves. From managing status codes to forcing redirects, cleaning up URLs, and protecting sensitive files, these little rules can shape how search engines and users interact with your site. If you're learning about technical SEO, learning how to use htaccess directives properly, then this post is well worth the read.
The list below is a collection of rules I’ve used or tweaked over the years (and decades). They're not for show, they’re the kinds of fixes and improvements that tighten things up in the background. Some are small wins, others can pull you out of a hole when something breaks or gets messy. Use what fits your setup, test everything properly, and remember that a bad rule can take down your whole site if you're not careful.
Turns on the mod_rewrite engine so rewrite rules can run.
Checks if HTTPS is not being used.
Forces all traffic to HTTPS to avoid protocol duplication.
Detects www. requests to redirect them to non-www version.
Redirects from www to non-www using a permanent 301 redirect.
Redirects non-www to www (flip of the previous pattern).
Ensures www is added to all incoming requests.
Custom 404 error page to help users and preserve brand.
Redirects outdated or moved URLs to new destination with 301.
Forces UTF-8 encoding to ensure consistent text rendering.
Prevents directory listing, keeping crawl clean and secure.
Disables ETags to reduce unnecessary duplicate cache validations.
Prevents indexing of certain pages like search results or admin.
Stops browsers from MIME-sniffing, keeps content-type consistent.
Enforces HTTPS through HSTS for security and consistency.
Targets tracking parameters for cleanup.
Strips query strings (like UTM) to reduce crawl bloat.
Detects double slashes in URLs.
Normalises URLs by removing double slashes.
Redirects canonical root away from index.php.
Allows rewrites only if the file doesn't physically exist.
Allows rewrites only if the directory doesn't physically exist.
Redirects standard sitemap to a more organised sitemap index.
Turns on browser caching to improve load speed and crawl efficiency.
Adds cache rules to assets for improved performance scores.
Flags certain folders to be excluded from indexing.
Adds a canonical link header to non-HTML resources.
Prevents your pages from being embedded elsewhere, avoids clickjacking.
Stops caching of sensitive or temporary pages.
[/code]RedirectMatch 403 ^/admin
Blocks access to admin area for external users or bots.
Overrides a legacy category URL structure to the new format.
Returns a 410 Gone status for pages you want removed from the index.
Returns a 410 for a dead product page, signalling permanent removal.
Blocks access to internal folders with a 403 Forbidden response.
Issues a temporary 302 redirect to a campaign landing page.
Overrides a URL to simplify and align with preferred structure.
Returns 404 for any product PDF that no longer exists.
Blocks and signals a Gone status for old tag archives.
Moves versioned API endpoints to a new base path.
Prevents accidental exposure of backup directories.
Blocks traffic from a specific referrer with a 403.
Temporarily redirects users to a maintenance notice.
Normalises and consolidates tag URLs.
Redirects unnecessary index.html to the root for cleaner URLs.
Blocks access to WordPress XML-RPC to reduce attack surface.
Blocks admin includes from being accessed directly.
Mitigates open redirect attempts by blocking dodgy query strings.
Sets a header to prevent indexing of sensitive or temporary content.
Cleans out entire sections with a clear gone response.
Forces all unresolved requests to route through index for SEO control.
When used well, htaccess rules keep your site lean, redirecting with purpose, and control how good and bad bots, and users hit your pages. There’s no single perfect setup. What works for one site might break another, so always test in a staging environment first. Even a tiny syntax error can cause major issues. Learn to roll back quickly, and keep backups before making any changes.
This kind of control is what technical SEO is really about. You don’t always need new tools or big platforms. Sometimes it’s about understanding what you’ve already got and using it properly. And htaccess is a one of the best places to start. Go spin up a WordPress site and practice on that.
The list below is a collection of rules I’ve used or tweaked over the years (and decades). They're not for show, they’re the kinds of fixes and improvements that tighten things up in the background. Some are small wins, others can pull you out of a hole when something breaks or gets messy. Use what fits your setup, test everything properly, and remember that a bad rule can take down your whole site if you're not careful.
Code:
RewriteEngine On
Code:
RewriteCond %{HTTPS} off
Code:
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Code:
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
Code:
RewriteRule ^ https://%1%{REQUEST_URI} [R=301,L]
Code:
RewriteCond %{HTTP_HOST} !^www\.
Code:
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
Code:
ErrorDocument 404 /404.html
Code:
Redirect 301 /old-url https://example.com/new-url
Code:
AddDefaultCharset UTF-8
Code:
Options -Indexes
Code:
FileETag None
Code:
Header set X-Robots-Tag "noindex, noarchive"
Code:
Header set X-Content-Type-Options "nosniff"
Code:
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Code:
RewriteCond %{QUERY_STRING} (^|&)utm_ [NC]
Code:
RewriteRule ^(.*)$ /$1? [R=301,L]
Code:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s(.*)//+(.*)\sHTTP/
Code:
RewriteRule . https://example.com/%1/%2 [R=301,L]
Code:
RewriteRule ^index\.php$ https://example.com/ [R=301,L]
Code:
RewriteCond %{REQUEST_FILENAME} !-f
Code:
RewriteCond %{REQUEST_FILENAME} !-d
Code:
RewriteRule ^sitemap\.xml$ sitemap-index.xml [L]
Code:
ExpiresActive On
Code:
ExpiresByType image/webp "access plus 1 year"
Code:
SetEnvIf Request_URI "^/private/" noindex
Code:
Header set Link "<https://example.com>; rel=\"canonical\""
Code:
Header always set X-Frame-Options "SAMEORIGIN"
Code:
Header set Cache-Control "no-store"
[/code]RedirectMatch 403 ^/admin
Blocks access to admin area for external users or bots.
Code:
RewriteRule ^category/?$ /categories/ [R=301,L]
Code:
Redirect 410 /old-landing-page
Code:
RewriteRule ^deprecated-product/?$ - [G,L]
Code:
RewriteCond %{REQUEST_URI} ^/internal/
RewriteRule .* - [F]
Code:
Redirect 302 /temporary-offer https://example.com/summer-sale
Code:
RewriteEngine On
RewriteRule ^checkout$ /basket [R=301,L]
Code:
RedirectMatch 404 ^/products/.*.pdf$
Code:
RewriteCond %{REQUEST_URI} ^/blog/.*/old-tag/
RewriteRule ^ - [G]
Code:
RedirectMatch 301 ^/v1/api/(.*)$ /api/$1
Code:
RewriteCond %{REQUEST_URI} ^/backup/
RewriteRule ^ - [F,L]
Code:
RewriteCond %{HTTP_REFERER} example.com
RewriteRule ^ - [F]
Code:
RewriteRule ^maintenance/?$ /maintenance.html [R=302,L]
Code:
Redirect 301 /tag/seo-basics /tags/seo
Code:
RewriteRule ^index.html$ / [R=301,L]
Code:
RewriteCond %{REQUEST_URI} ^/xmlrpc.php$
RewriteRule ^ - [F,L]
Code:
RedirectMatch 403 ^/wp-admin/includes/
Code:
RewriteCond %{QUERY_STRING} (.+)=http
RewriteRule ^(.*)$ / [F]
Code:
Header set X-Robots-Tag "noindex, nofollow"
Code:
RedirectMatch 410 ^/old-section/(.*)$
Code:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
When used well, htaccess rules keep your site lean, redirecting with purpose, and control how good and bad bots, and users hit your pages. There’s no single perfect setup. What works for one site might break another, so always test in a staging environment first. Even a tiny syntax error can cause major issues. Learn to roll back quickly, and keep backups before making any changes.
This kind of control is what technical SEO is really about. You don’t always need new tools or big platforms. Sometimes it’s about understanding what you’ve already got and using it properly. And htaccess is a one of the best places to start. Go spin up a WordPress site and practice on that.
Last edited: