Cookie Consent by Free Privacy Policy Generator

Useful htaccess rules for SEO and site management

.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.

Code:
RewriteEngine On
Turns on the mod_rewrite engine so rewrite rules can run.

Code:
RewriteCond %{HTTPS} off
Checks if HTTPS is not being used.

Code:
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Forces all traffic to HTTPS to avoid protocol duplication.

Code:
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
Detects www. requests to redirect them to non-www version.

Code:
RewriteRule ^ https://%1%{REQUEST_URI} [R=301,L]
Redirects from www to non-www using a permanent 301 redirect.

Code:
RewriteCond %{HTTP_HOST} !^www\.
Redirects non-www to www (flip of the previous pattern).

Code:
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
Ensures www is added to all incoming requests.

Code:
ErrorDocument 404 /404.html
Custom 404 error page to help users and preserve brand.

Code:
Redirect 301 /old-url https://example.com/new-url
Redirects outdated or moved URLs to new destination with 301.

Code:
AddDefaultCharset UTF-8
Forces UTF-8 encoding to ensure consistent text rendering.

Code:
Options -Indexes
Prevents directory listing, keeping crawl clean and secure.

Code:
FileETag None
Disables ETags to reduce unnecessary duplicate cache validations.

Code:
Header set X-Robots-Tag "noindex, noarchive"
Prevents indexing of certain pages like search results or admin.

Code:
Header set X-Content-Type-Options "nosniff"
Stops browsers from MIME-sniffing, keeps content-type consistent.

Code:
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Enforces HTTPS through HSTS for security and consistency.

Code:
RewriteCond %{QUERY_STRING} (^|&)utm_ [NC]
Targets tracking parameters for cleanup.

Code:
RewriteRule ^(.*)$ /$1? [R=301,L]
Strips query strings (like UTM) to reduce crawl bloat.

Code:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s(.*)//+(.*)\sHTTP/
Detects double slashes in URLs.

Code:
RewriteRule . https://example.com/%1/%2 [R=301,L]
Normalises URLs by removing double slashes.

Code:
RewriteRule ^index\.php$ https://example.com/ [R=301,L]
Redirects canonical root away from index.php.

Code:
RewriteCond %{REQUEST_FILENAME} !-f
Allows rewrites only if the file doesn't physically exist.

Code:
RewriteCond %{REQUEST_FILENAME} !-d
Allows rewrites only if the directory doesn't physically exist.

Code:
RewriteRule ^sitemap\.xml$ sitemap-index.xml [L]
Redirects standard sitemap to a more organised sitemap index.

Code:
ExpiresActive On
Turns on browser caching to improve load speed and crawl efficiency.

Code:
ExpiresByType image/webp "access plus 1 year"
Adds cache rules to assets for improved performance scores.

Code:
SetEnvIf Request_URI "^/private/" noindex
Flags certain folders to be excluded from indexing.

Code:
Header set Link "<https://example.com>; rel=\"canonical\""
Adds a canonical link header to non-HTML resources.

Code:
Header always set X-Frame-Options "SAMEORIGIN"
Prevents your pages from being embedded elsewhere, avoids clickjacking.

Code:
Header set Cache-Control "no-store"
Stops caching of sensitive or temporary pages.

[/code]RedirectMatch 403 ^/admin
Blocks access to admin area for external users or bots.

Code:
RewriteRule ^category/?$ /categories/ [R=301,L]
Overrides a legacy category URL structure to the new format.

Code:
Redirect 410 /old-landing-page
Returns a 410 Gone status for pages you want removed from the index.

Code:
RewriteRule ^deprecated-product/?$ - [G,L]
Returns a 410 for a dead product page, signalling permanent removal.

Code:
RewriteCond %{REQUEST_URI} ^/internal/
RewriteRule .* - [F]
Blocks access to internal folders with a 403 Forbidden response.

Code:
Redirect 302 /temporary-offer https://example.com/summer-sale
Issues a temporary 302 redirect to a campaign landing page.

Code:
RewriteEngine On
RewriteRule ^checkout$ /basket [R=301,L]
Overrides a URL to simplify and align with preferred structure.

Code:
RedirectMatch 404 ^/products/.*.pdf$
Returns 404 for any product PDF that no longer exists.

Code:
RewriteCond %{REQUEST_URI} ^/blog/.*/old-tag/
RewriteRule ^ - [G]
Blocks and signals a Gone status for old tag archives.

Code:
RedirectMatch 301 ^/v1/api/(.*)$ /api/$1
Moves versioned API endpoints to a new base path.

Code:
RewriteCond %{REQUEST_URI} ^/backup/
RewriteRule ^ - [F,L]
Prevents accidental exposure of backup directories.

Code:
RewriteCond %{HTTP_REFERER} example.com
RewriteRule ^ - [F]
Blocks traffic from a specific referrer with a 403.

Code:
RewriteRule ^maintenance/?$ /maintenance.html [R=302,L]
Temporarily redirects users to a maintenance notice.

Code:
Redirect 301 /tag/seo-basics /tags/seo
Normalises and consolidates tag URLs.

Code:
RewriteRule ^index.html$ / [R=301,L]
Redirects unnecessary index.html to the root for cleaner URLs.

Code:
RewriteCond %{REQUEST_URI} ^/xmlrpc.php$
RewriteRule ^ - [F,L]
Blocks access to WordPress XML-RPC to reduce attack surface.

Code:
RedirectMatch 403 ^/wp-admin/includes/
Blocks admin includes from being accessed directly.

Code:
RewriteCond %{QUERY_STRING} (.+)=http
RewriteRule ^(.*)$ / [F]
Mitigates open redirect attempts by blocking dodgy query strings.

Code:
Header set X-Robots-Tag "noindex, nofollow"
Sets a header to prevent indexing of sensitive or temporary content.

Code:
RedirectMatch 410 ^/old-section/(.*)$
Cleans out entire sections with a clear gone response.

Code:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
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.
 
Last edited:
Back
Top