Control your Apache server configuration with .htaccess
.htaccess (hypertext access) is a configuration file used by Apache web servers. It allows you to control server behavior on a per-directory basis without accessing the main server configuration.
Important: Always backup .htaccess before editing! A syntax error can break your entire website.
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]Redirect 301 /old-page.html https://yourdomain.com/new-page.htmlRedirectMatch 301 ^/old-directory/(.*)$ https://yourdomain.com/new-directory/$1ErrorDocument 404 /404.html
ErrorDocument 403 /403.html
ErrorDocument 500 /500.html<RequireAll>
Require all granted
Require not ip 192.168.1.1
Require not ip 10.0.0.0/8
</RequireAll><Files .htaccess>
Require all denied
</Files>Options -Indexes<FilesMatch "\.(env|log|sql|md|txt|sh)quot;>
Require all denied
</FilesMatch># Place in /wp-content/uploads/.htaccess
<Files *.php>
Require all denied
</Files><IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css
AddOutputFilterByType DEFLATE text/javascript application/javascript application/x-javascript
AddOutputFilterByType DEFLATE application/json
AddOutputFilterByType DEFLATE application/xml application/xhtml+xml
</IfModule><IfModule mod_expires.c>
ExpiresActive On
# Images
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/gif "access plus 1 year"
ExpiresByType image/webp "access plus 1 year"
ExpiresByType image/svg+xml "access plus 1 year"
# CSS and JavaScript
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType text/javascript "access plus 1 month"
# HTML
ExpiresByType text/html "access plus 1 hour"
</IfModule>RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/]+)$ $1.html [L]RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [R=301,L]RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*[^/])$ $1/ [L,R=301]Prevent other sites from directly linking to your images:
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^https://(www\.)?yourdomain\.com [NC]
RewriteRule \.(jpg|jpeg|png|gif|webp)$ - [F,L]# 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<Files wp-config.php>
Require all denied
</Files>Common causes: Syntax errors, unsupported directives, conflicting rules
Solution: Rename .htaccess to .htaccess.bak, add rules back one section at a time
Check for conflicting redirect rules, ensure RewriteCond conditions are correct, clear browser cache
Verify mod_rewrite is enabled, check rule order (top to bottom), ensure [L] flag is used to stop processing
While .htaccess is powerful, consider alternatives when: