Plasma Ball

8-minute read

ClassicPress .htaccess Hacks for Performance and Security

Rocket your ClassicPress site performance and security with .htaccess – no plugins required!! 100% applicable to WordPress, too!

The following .htaccess directives can help to boost your ClassicPress performance and security. Your existing `.htaccess` file may contain some of these directives already, so, feel free to pick and choose only those that you want. Before adding any directives. head on over to GTMetrix and get your site’s baseline scores – later, after you’ve applied the various directives, you can retest your site to see the improvements in actual numbers.

Getting Started

Make a copy of your existing `.htaccess` file to get started. With the directives below, don’t just do a straight copy/paste! Instead, add one complete directive at a time, refreshing your site in a browser each time to ensure that an Error 500 didn’t occur. If an error did occur, you can delete (or amend) the directive you just added. There are a couple of places where you need to add your own URL, so, be sure to see the comments above each directive.

.htaccess Hacks for ClassicPress

# Default error messages for when someone accesses a blocked file.
ErrorDocument 401 "Denied"
ErrorDocument 403 "Denied"

# Require authentication before accessing wp-login.php
# Note that you will need to point the path to your own .htpasswd file that
# contains the http auth credentials.
<Files wp-login.php>
AuthType Basic
AuthName "Secure Area"
AuthUserFile "/home/path/to/.htpasswd"
require valid-user

# Prevent access to .htaccess file.
<files ~ "^.*\.([Hh][Tt][Aa])">
order allow,deny
deny from all
satisfy all

# Prevent access to xmlrpc.php
<Files xmlrpc.php>
order deny,allow
deny from all

# Prevent access to wp-config.php
<files wp-config.php>
order allow,deny
deny from all

# Enable strict HTTPS transport; not the same as forcing connections to HTTPS.
# There is another directive below for that.
Header set Strict-Transport-Security "max-age=86400" env=HTTPS

# Ensure a strict character set for certain types.
AddDefaultCharset utf-8
<IfModule mod_mime.c>
	AddCharset utf-8 .appcache \
		 .bbaw \
		 .css \
		 .htc \
		 .ics \
		 .js \
		 .json \
		 .manifest \
		 .map \
		 .markdown \
		 .md \
		 .mjs \
		 .svg \
		 .topojson \
		 .vtt \
		 .vcard \
		 .vcf \
		 .webmanifest \

# Ensure proper mimetypes; prevent browser sniffs in case of issues.
<IfModule mod_mime.c>
	AddType application/atom+xml atom
	AddType application/json json map topojson
	AddType application/ld+json jsonld
	AddType application/rss+xml rss
	AddType application/geo+json geojson
	AddType application/rdf+xml rdf
	AddType application/xml xml
	AddType text/javascript js mjs
	AddType application/manifest+json webmanifest
	AddType application/x-web-app-manifest+json webapp
	AddType text/cache-manifest appcache
	AddType audio/mp4 f4a f4b m4a
	AddType audio/ogg oga ogg opus
	AddType image/bmp bmp
	AddType image/svg+xml svg svgz
	AddType image/webp webp
	AddType video/mp4 f4v f4p m4v mp4
	AddType video/ogg ogv
	AddType video/webm webm
	AddType video/x-flv flv
	AddType image/x-icon cur ico
	AddType application/wasm wasm
	AddType font/woff woff
	AddType font/woff2 woff2
	AddType application/ eot
	AddType font/ttf ttf
	AddType font/collection ttc
	AddType font/otf otf
	AddType application/octet-stream safariextz
	AddType application/x-bb-appworld bbaw
	AddType application/x-chrome-extension crx
	AddType application/x-opera-extension oex
	AddType application/x-xpinstall xpi
	AddType text/calendar ics
	AddType text/markdown markdown md
	AddType text/vcard vcard vcf
	AddType text/vnd.rim.location.xloc xloc
	AddType text/vtt vtt
	AddType text/x-component htc
<IfModule mod_headers.c>
	Header set X-Content-Type-Options "nosniff"
	Header set Connection keep-alive
	ServerSignature Off
	Header always unset "X-Powered-By"
	Header unset "X-Powered-By"
	Header unset ETag
	FileETag None

# Serve webp images, if possible.
<IfModule pagespeed_module>
	ModPagespeed on
	ModPagespeedEnableFilters convert_png_to_jpeg,convert_jpeg_to_webp
	ModPagespeedEnableFilters collapse_whitespace,remove_comments

# Force HTTPS for all connections; be sure to change the URL to your own!
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$$1 [R,L]

# Cross-origin resource sharing - for images.
<IfModule mod_setenvif.c>
	<IfModule mod_headers.c>
		<FilesMatch "\.(bmp|cur|gif|ico|jpe?g|png|svgz?|webp)$">
			SetEnvIf Origin ":" IS_CORS
			Header set Access-Control-Allow-Origin "*" env=IS_CORS

# Cross-origin resource sharing - for fonts. 
<IfModule mod_headers.c>
	<FilesMatch "\.(eot|otf|tt[cf]|woff2?)$">
		Header set Access-Control-Allow-Origin "*"
<IfModule mod_headers.c>
	Header set X-UA-Compatible "IE=edge"
	<FilesMatch "\.(appcache|atom|bbaw|bmp|br|crx|css|cur|eot|f4[abpv]|flv|geojson|gif|gz|htc|ic[os]|jpe?g|m?js|json(ld)?|m4[av]|manifest|map|markdown|md|mp4|oex|og[agv]|opus|otf|pdf|png|rdf|rss|safariextz|svgz?|swf|topojson|tt[cf]|txt|vcard|vcf|vtt|wasm|webapp|web[mp]|webmanifest|woff2?|xloc|xml|xpi)$">
		Header unset X-UA-Compatible

# Enable server compression.
<IfModule mod_deflate.c>
	<FilesMatch "\.(html|php|txt|xml|js|css)$">
		SetOutputFilter DEFLATE
	<IfModule mod_setenvif.c>
		<IfModule mod_headers.c>
			SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding
			RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding
	<IfModule mod_filter.c>
		AddOutputFilterByType DEFLATE "application/atom+xml" \
			 "application/javascript" \
			 "application/json" \
			 "application/ld+json" \
			 "application/manifest+json" \
			 "application/rdf+xml" \
			 "application/rss+xml" \
			 "application/schema+json" \
			 "application/geo+json" \
			 "application/" \
			 "application/wasm" \
			 "application/x-font-ttf" \
			 "application/x-javascript" \
			 "application/x-web-app-manifest+json" \
			 "application/xhtml+xml" \
			 "application/xml" \
			 "font/woff" \
			 "font/woff2" \
			 "font/eot" \
			 "font/opentype" \
			 "font/otf" \
			 "image/bmp" \
			 "image/svg+xml" \
			 "image/" \
			 "text/cache-manifest" \
			 "text/calendar" \
			 "text/css" \
			 "text/html" \
			 "text/javascript" \
			 "text/plain" \
			 "text/markdown" \
			 "text/text" \
			 "text/vcard" \
			 "text/vnd.rim.location.xloc" \
			 "text/vtt" \
			 "text/x-component" \
			 "text/x-cross-domain-policy" \
	<IfModule mod_mime.c>
		AddEncoding gzip svgz

# Add expires headers.
<IfModule mod_expires.c>
	ExpiresActive on
	ExpiresDefault "access plus 1 month"
	ExpiresByType text/css "access plus 1 year"
	ExpiresByType application/atom+xml "access plus 1 hour"
	ExpiresByType application/rdf+xml "access plus 1 hour"
	ExpiresByType application/rss+xml "access plus 1 hour"
	ExpiresByType application/json "access plus 0 seconds"
	ExpiresByType application/ld+json "access plus 0 seconds"
	ExpiresByType application/schema+json "access plus 0 seconds"
	ExpiresByType application/geo+json "access plus 0 seconds"
	ExpiresByType application/xml "access plus 0 seconds"
	ExpiresByType text/calendar "access plus 0 seconds"
	ExpiresByType text/xml "access plus 0 seconds"
	ExpiresByType image/ "access plus 1 week"
	ExpiresByType image/x-icon "access plus 1 week"
	ExpiresByType text/html "access plus 0 seconds"
	ExpiresByType application/javascript "access plus 1 year"
	ExpiresByType application/x-javascript "access plus 1 year"
	ExpiresByType text/javascript "access plus 1 year"
	ExpiresByType application/manifest+json "access plus 1 week"
	ExpiresByType application/x-web-app-manifest+json "access plus 0 seconds"
	ExpiresByType text/cache-manifest "access plus 0 seconds"
	ExpiresByType text/markdown "access plus 0 seconds"
	ExpiresByType audio/ogg "access plus 1 month"
	ExpiresByType image/bmp "access plus 1 month"
	ExpiresByType image/gif "access plus 1 month"
	ExpiresByType image/jpeg "access plus 1 year"
	ExpiresByType image/png "access plus 1 month"
	ExpiresByType image/svg+xml "access plus 1 month"
	ExpiresByType image/webp "access plus 1 month"
	ExpiresByType video/mp4 "access plus 1 month"
	ExpiresByType video/ogg "access plus 1 month"
	ExpiresByType video/webm "access plus 1 month"
	ExpiresByType application/wasm "access plus 1 year"
	ExpiresByType font/collection "access plus 1 month"
	ExpiresByType application/ "access plus 1 month"
	ExpiresByType font/eot "access plus 1 month"
	ExpiresByType font/opentype "access plus 1 month"
	ExpiresByType font/otf "access plus 1 month"
	ExpiresByType application/x-font-ttf "access plus 1 month"
	ExpiresByType font/ttf "access plus 1 month"
	ExpiresByType application/font-woff "access plus 1 month"
	ExpiresByType application/x-font-woff "access plus 1 month"
	ExpiresByType font/woff "access plus 1 month"
	ExpiresByType application/font-woff2 "access plus 1 month"
	ExpiresByType font/woff2 "access plus 1 month"
	ExpiresByType text/x-cross-domain-policy "access plus 1 week"
	ExpiresByType text/x-component A31536000
	ExpiresByType text/x-js A31536000
	ExpiresByType text/richtext A3600
	ExpiresByType text/plain A3600
	ExpiresByType text/xsd A3600
	ExpiresByType text/xsl A3600

# Prevent directory listing.
Options -Indexes

# Block access to other potentially sensitive files.
<IfModule mod_rewrite.c>
	RewriteEngine On
	RewriteCond %{REQUEST_URI} "!(^|/)\.well-known/([^./]+./?)+$" [NC]
	RewriteCond %{SCRIPT_FILENAME} -d [OR]
	RewriteCond %{SCRIPT_FILENAME} -f
	RewriteRule "(^|/)\." - [F]
<IfModule mod_authz_core.c>
	<FilesMatch "(^#.*#|\.(bak|conf|dist|fla|in[ci]|log|orig|psd|sh|sql|sw[op])|~)$">
		Require all denied

How did it go?

Did you have trouble with any of the directives? How did your performance scores change? Do you know any other `.htaccess` directives that can improve performance and security? I’d love to hear your thoughts – let me know in the comments!