.htaccess Copypasta

.htaccess


# =============================================
# 0. GENERAL SETTINGS
# =============================================
AddDefaultCharset UTF-8
# Redirect to an initial page other than index.html
# DirectoryIndex 0000_table_of_contents.html index.html

# =============================================
# 1. SEO & SECURITY: Canonical Domain (Force non-www and HTTPS)
# =============================================
RewriteEngine On
RewriteBase /

# Force non-www:
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [L,R=301]

# Force HTTPS (Proxy-Safe):
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

# =============================================
# 2. PERFORMANCE: Compression & Browser Caching
# =============================================
<IfModule mod_deflate.c>
  AddOutputFilterByType DEFLATE text/plain text/html text/xml text/css application/xml application/xhtml+xml application/rss+xml application/javascript application/x-javascript application/json image/svg+xml
</IfModule>

<IfModule mod_expires.c>
  ExpiresActive On
  ExpiresDefault                          "access plus 0 seconds"
  ExpiresByType text/html                 "access plus 0 seconds"
  
  # Bumped static assets to 1 year for better Lighthouse/PageSpeed scores
  ExpiresByType image/x-icon              "access plus 1 year"
  ExpiresByType image/gif                 "access plus 1 year"
  ExpiresByType image/png                 "access plus 1 year"
  ExpiresByType image/jpeg                "access plus 1 year"
  ExpiresByType image/webp                "access plus 1 year"
  ExpiresByType image/svg+xml             "access plus 1 year"
  ExpiresByType font/woff                 "access plus 1 year"
  ExpiresByType font/woff2                "access plus 1 year"
  ExpiresByType text/css                  "access plus 1 year"
  ExpiresByType application/javascript    "access plus 1 year"
</IfModule>

# =============================================
# 3. SECURITY: HTTP Headers & Secure Folders
# =============================================
<IfModule mod_headers.c>
  Header always set X-Frame-Options "SAMEORIGIN"
  Header always set X-Content-Type-Options "nosniff"
  Header always set Referrer-Policy "strict-origin-when-cross-origin"
  
  # HSTS (Removed includeSubDomains to prevent accidental lockouts)
  Header always set Strict-Transport-Security "max-age=31536000" env=HTTPS
  
  # Content Security Policy (Not necessary for my static website on private VPS...) 
  # Note: Add a report-uri if you want to capture these reports externally!
  # Header always set Content-Security-Policy-Report-Only "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self';"
  #Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'wasm-unsafe-eval'; connect-src 'self';"
  Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'wasm-unsafe-eval'; style-src 'self' 'unsafe-inline'; connect-src 'self';"
</IfModule>

# Password-protect all subdirectories named "secure" only when HTTPS is active
<If "%{HTTPS} == 'on' && %{REQUEST_URI} =~ m#(^|/)secure(/|$)#i">
    AuthType Basic
    AuthName "Restricted Secure Area"
    AuthUserFile /home/justinmichaelbonanno/.htpasswd
    Require user bonju
</If>
<If "%{HTTPS} == 'on' && %{REQUEST_URI} =~ m#(^|/)qsjwbuf(/|$)#i">
    AuthType Basic
    AuthName "Restricted Secure Area"
    AuthUserFile /home/justinmichaelbonanno/.htpasswd
    Require user bonju
</If>
<If "%{HTTPS} == 'on' && %{REQUEST_URI} =~ m#(^|/)secure_guest(/|$)#i">
    AuthType Basic
    AuthName "Restricted Secure Area"
    AuthUserFile /home/justinmichaelbonanno/.htpasswd
    Require valid-user
</If>

# =============================================
# 4. GENERAL SECURITY & ERROR HANDLING
# =============================================
# MultiViews MUST be off for extensionless URL routing to work properly
Options -Indexes -MultiViews

<FilesMatch "^\.ht">
    Require all denied
</FilesMatch>

ErrorDocument 401 /401.html
ErrorDocument 404 /404.html
ErrorDocument 500 /500.html
ErrorDocument 503 /503.html

# =============================================
# 5. URL AESTHETICS & ROUTING (Internal Rewrites)
# =============================================
# Force trailing slash for ACTUAL directories
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.*[^/])$ /$1/ [L,R=301]

# Remove trailing slash from non-directories (prevents 404 on /page/)
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]

# SEO: Redirect /index.html to root /
RewriteCond %{THE_REQUEST} \s/+(.*?/)?index\.html[\s?] [NC]
RewriteRule ^ /%1 [R=301,L]

# SEO: Redirect /page.html directly to /page
RewriteCond %{THE_REQUEST} \s/+(.+)\.html[\s?] [NC]
RewriteRule ^ /%1 [R=301,L]

# INTERNAL: Allow accessing /page by serving /page.html silently
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^(.*)$ $1.html [L]
Search Titles & Keywords