The default .htaccess of WordPress look like…

# BEGIN WordPress
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteRule ^index\.php$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [L]
</IfModule>
# END WordPress

SSL Forwarding

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{HTTPS} !=on
    RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>

CORS Security

<IfModule mod_headers.c>
    <FilesMatch "\.(ttf|ttc|otf|eot|woff|woff2|font.css|css|js|gif|png|jpe?g|svg|svgz|ico|webp)$">
        Header set Access-Control-Allow-Origin "*"
    </FilesMatch>
</IfModule>

Browser Caching

Enable browser caching for Google’s PageSpeed.

<IfModule mod_expires.c>
    ExpiresActive on
    ExpiresDefault "access plus 1 month"

    # CSS
    ExpiresByType text/css "access plus 1 year"

    # Data
    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/vnd.geo+json "access plus 0 seconds"
    ExpiresByType application/xml "access plus 0 seconds"
    ExpiresByType text/xml "access plus 0 seconds"

    # Favicon (cannot be renamed!) and cursor images
    ExpiresByType image/vnd.microsoft.icon "access plus 1 week"
    ExpiresByType image/x-icon "access plus 1 week"

    # HTML
    ExpiresByType text/html "access plus 0 seconds"

    # JavaScript
    ExpiresByType application/javascript "access plus 1 year"
    ExpiresByType application/x-javascript "access plus 1 year"
    ExpiresByType text/javascript "access plus 1 year"

    # Manifest files
    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"

    # Media files
    ExpiresByType audio/ogg "access plus 1 year"
    ExpiresByType image/bmp "access plus 1 year"
    ExpiresByType image/gif "access plus 1 year"
    ExpiresByType image/jpeg "access plus 1 year"
    ExpiresByType image/png "access plus 1 year"
    ExpiresByType image/svg+xml "access plus 1 year"
    ExpiresByType image/webp "access plus 1 year"
    ExpiresByType video/mp4 "access plus 1 year"
    ExpiresByType video/ogg "access plus 1 year"
    ExpiresByType video/webm "access plus 1 year"

    # Web Fonts

    # Embedded OpenType (EOT)
    ExpiresByType application/vnd.ms-fontobject "access plus 1 year"
    ExpiresByType font/eot "access plus 1 year"

    # OpenType
    ExpiresByType font/opentype "access plus 1 year"

    # TrueType
    ExpiresByType application/x-font-ttf "access plus 1 year"

    # Web Open Font Format (WOFF) 1.0
    ExpiresByType application/font-woff "access plus 1 year"
    ExpiresByType application/x-font-woff "access plus 1 year"
    ExpiresByType font/woff "access plus 1 year"

    # Web Open Font Format (WOFF) 2.0
    ExpiresByType application/font-woff2 "access plus 1 year"

    # Other
    ExpiresByType text/x-cross-domain-policy "access plus 1 week"
</IfModule>

Compression

Insert filters. Compress text, HTML, Javascript, CSS, XML files.

<IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/plain
    AddOutputFilterByType DEFLATE text/html
    AddOutputFilterByType DEFLATE text/xml
    AddOutputFilterByType DEFLATE text/css
    AddOutputFilterByType DEFLATE text/vtt
    AddOutputFilterByType DEFLATE text/x-component
    AddOutputFilterByType DEFLATE application/xml
    AddOutputFilterByType DEFLATE application/xhtml+xml
    AddOutputFilterByType DEFLATE application/rss+xml
    AddOutputFilterByType DEFLATE application/js
    AddOutputFilterByType DEFLATE application/javascript
    AddOutputFilterByType DEFLATE application/x-javascript
    AddOutputFilterByType DEFLATE application/x-httpd-php
    AddOutputFilterByType DEFLATE application/x-httpd-fastphp
    AddOutputFilterByType DEFLATE application/atom+xml
    AddOutputFilterByType DEFLATE application/json
    AddOutputFilterByType DEFLATE application/ld+json
    AddOutputFilterByType DEFLATE application/vnd.ms-fontobject
    AddOutputFilterByType DEFLATE application/x-font-ttf
    AddOutputFilterByType DEFLATE application/font-woff2
    AddOutputFilterByType DEFLATE application/x-font-woff
    AddOutputFilterByType DEFLATE application/x-web-app-manifest+json font/woff
    AddOutputFilterByType DEFLATE font/woff
    AddOutputFilterByType DEFLATE font/opentype
    AddOutputFilterByType DEFLATE image/svg+xml
    AddOutputFilterByType DEFLATE image/x-icon

    # Exception: Images
    SetEnvIfNoCase REQUEST_URI \.(?:gif|jpg|jpeg|png|svg)$ no-gzip dont-vary

    # Drop problematic browsers
    BrowserMatch ^Mozilla/4 gzip-only-text/html
    BrowserMatch ^Mozilla/4\.0[678] no-gzip
    BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html

    # Make sure proxies don't deliver the wrong content
    Header append Vary User-Agent env=!dont-vary
</IfModule>

Caching on Apache

Alternative caching using Apache’s “mod_headers”, if it’s installed. Caching of common files.

<IfModule mod_headers.c>
    <FilesMatch "\.(ico|pdf|flv|swf|js|css|gif|png|jpg|jpeg|txt|woff2|woff)$">
        Header set Cache-Control "max-age=31536000, public"
    </FilesMatch>
</IfModule>

<IfModule mod_headers.c>
    <FilesMatch "\.(js|css|xml|gz)$">
        Header append Vary Accept-Encoding
    </FilesMatch>
</IfModule>

Keep-Alive Header

Set Keep Alive Header

<IfModule mod_headers.c>
    Header set Connection keep-alive
</IfModule>

Disable ETags on Server

If your server don’t support ETags deactivate with “None” and remove header.

<IfModule mod_expires.c>
    <IfModule mod_headers.c>
        Header unset ETag
    </IfModule>

    FileETag None
</IfModule>

<IfModule mod_headers.c>
    <FilesMatch ".(js|css|xml|gz|html|woff|woff2|ttf)$">
        Header append Vary: Accept-Encoding
    </FilesMatch>
</IfModule>

File Protection

No access to the install.php

<Files install.php>
    Order allow,deny
    Deny from all
</Files>

No access to the wp-config.php

<Files wp-config.php>
    Order allow,deny
    Deny from all
</Files>

No access to the readme.html
I prefer to delete this file right away.

<Files readme.html>
    Order allow,deny
    Deny from all
    Satisfy all
</Files>

No access to the liesmich.html (only for DE version!)
I prefer to delete this file right away.

<Files liesmich.html>
    Order allow,deny
    Deny from all
    Satisfy all
</Files>

No error log access.

<Files error_log>
    Order allow,deny
    Deny from all
</Files>

No access to the .htaccess und .htpasswd

<FilesMatch "(\.htaccess|\.htpasswd)">
    Order deny,allow
    Deny from all
</FilesMatch>

Block access to includes folder.

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteRule ^wp-admin/includes/ - [F,L]
    RewriteRule !^wp-includes/ - [S=3]
    RewriteRule ^wp-includes/[^/]+\.php$ - [F,L]
    RewriteRule ^wp-includes/js/tinymce/langs/.+\.php - [F,L]
    RewriteRule ^wp-includes/theme-compat/ - [F,L]
</IfModule>

Block XML-RPC file.

<Files xmlrpc.php>
    Order deny,allow
    Deny from all
</Files>

No-Referrer Header

<IfModule mod_headers.c>
    Header set Referrer-Policy "no-referrer"
</IfModule>

X-Frame-Options Header

<IfModule mod_headers.c>
    Header set X-Frame-Options "sameorigin"
</IfModule>

X-XSS-Protection Header

<IfModule mod_headers.c>
    Header set X-XSS-Protection "1; mode=block"
</IfModule>

X-Content-Type-Options Header

<IfModule mod_headers.c>
    Header set X-Content-Type-Options "nosniff"
</IfModule>

Strict-Transport-Security Header – HTTPS

<IfModule mod_headers.c>
    Header set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
</IfModule>