Htaccess File Guide

The Definitive Resource

How to Configure a .htaccess File: Hosting Essentials

Copy-paste rules for redirects, HTTPS, security, and performance — without breaking your site

⚙️ ~5,200 words 📋 Copy-paste rules ⚡ Updated 2026

Few files have more power to make or break your website than .htaccess. Configured well, it forces HTTPS, redirects old URLs without losing SEO, blocks malicious bots, speeds up page loads with caching, and locks down sensitive directories. Configured poorly, it can take your entire site offline with a single misplaced character.

The good news: .htaccess isn’t actually that complicated. It’s a plain text file that gives directives to the Apache web server (and LiteSpeed, which works the same way), and once you understand the half-dozen common rule patterns, the rest is just copy-paste with light editing.

This guide walks through everything you actually need: where the file lives, how to edit it without breaking anything, the rule patterns you’ll use 95% of the time, and what to do if something goes wrong. Every code example here is production-tested. Copy them, adjust them to your specifics, and you’ll have a properly configured site in under an hour.

1. What .htaccess Actually Does

The .htaccess file (short for “hypertext access”) is a per-directory configuration file that the Apache web server reads on every request. It lets you override the server’s default behavior for a specific directory and all its subdirectories — without needing access to the main server config.

That last point is the key to why it matters. On shared hosting, you almost never have access to the main Apache configuration file (httpd.conf or apache2.conf). But you do have access to .htaccess. So it becomes the place where all your customizations live: redirects, security rules, caching headers, custom error pages, access control. Anything you’d want to configure at the server level, you configure here instead.

What It’s Commonly Used For

  • Redirects — sending visitors from old URLs to new ones (301 redirects), forcing HTTPS, forcing or removing www
  • URL rewriting — making pretty URLs from query strings (essential for WordPress permalinks)
  • Security — blocking specific IPs, blocking bad bots, hiding sensitive files like wp-config.php, disabling directory browsing
  • Performance — enabling browser caching with Expires headers, enabling GZIP/Brotli compression
  • Access control — password-protecting directories, restricting access by IP, allowing only certain users
  • Error pages — serving custom 404, 500, and other error pages instead of the default ugly ones
  • Headers — adding security headers like HSTS, X-Frame-Options, Content-Security-Policy
📁
One File Per Directory (Optional)

You can have .htaccess files in any directory, and rules apply to that directory plus its subdirectories. Most sites only use one in the root (e.g., public_html/), but you might add a separate one in /wp-admin/ for password protection or in /wp-content/uploads/ to disable PHP execution. Subdirectory .htaccess rules override the parent’s rules where they conflict.

2. Apache vs. Nginx: Does This Apply to You?

Before going further, the important caveat: .htaccess only works on Apache and Apache-compatible servers (mainly LiteSpeed). If you’re hosting on Nginx, none of this applies — Nginx uses an entirely different configuration approach.

How to Tell Which You’re On

Method 1: Ask your host or check your control panel

cPanel and Plesk hosts almost always run Apache or LiteSpeed. Managed WordPress hosts vary — Kinsta and WP Engine use Nginx, while SiteGround and Bluehost typically use Apache or LiteSpeed.

Method 2: Check the server response headers

Open your site in a browser, open DevTools (F12), go to Network, reload the page, click the main document request, and look at Response Headers. The Server: line tells you. Apache, Apache/2.4.x, or LiteSpeed means yes; nginx means no.

Method 3: Look for an .htaccess file in your root

If one exists in your public_html or www directory, you’re on Apache or LiteSpeed. If your host uses Nginx, there’s no .htaccess file because Nginx ignores them entirely.

ServerUses .htaccess?Notes
ApacheYesThe original; .htaccess is fully supported
LiteSpeedYesApache-compatible; reads .htaccess identically
OpenLiteSpeedYesOpen-source LiteSpeed; supports .htaccess
NginxNoUses server-block configs; .htaccess is ignored
CaddyNoUses Caddyfile config; .htaccess is ignored
IIS (Windows)NoUses web.config files instead

If you’re on Nginx, the equivalent rules need to go in your server-block config (typically managed by your host or via plugins like Really Simple SSL for HTTPS, or by editing the Nginx config if you have access).

3. Finding Your .htaccess File

The file is hidden by default — that’s what the leading dot means in Linux conventions. Here’s how to find it depending on your toolset.

Via cPanel File Manager

  1. Log into cPanel
  2. Open File Manager
  3. Click Settings in the upper right
  4. Check Show Hidden Files (dotfiles) and click Save
  5. Navigate to your site’s root directory (usually public_html)
  6. You should now see .htaccess in the file list

Via FTP/SFTP (FileZilla, etc.)

  1. Connect to your server
  2. Click the Server menu
  3. Enable Force showing hidden files
  4. Navigate to your site’s root
  5. .htaccess appears in the directory listing

Via SSH

The fastest method if you have terminal access. Connect to your server, navigate to your site root, and run ls -la to see all files including hidden ones. Edit with nano .htaccess or vim .htaccess.

What If There’s No .htaccess File?

Totally normal — many sites don’t have one until something needs it. WordPress generates one automatically the first time you save permalinks (Settings → Permalinks → Save Changes). For a static HTML site, you can simply create one:

  • Create a new plain text file
  • Name it .htaccess (with the leading dot, no file extension)
  • Upload it to your site root
⚠️
Watch the Filename

Common mistake: saving the file as htaccess.txt, .htaccess.txt, or htaccess (no leading dot). Apache only recognizes the exact filename .htaccess with the leading dot and no extension. Some Windows editors fight you on this — use Notepad++, VS Code, Sublime Text, or any editor that lets you save with a custom filename without auto-appending an extension.

4. Editing Safely (Read Before Touching)

This is the most important section in the guide. .htaccess is unforgiving — a single typo can take your entire site offline with a 500 Internal Server Error. The good news: that’s recoverable in seconds if you’ve prepared. Follow this routine every single time.

  1. Back up the existing file before any change Download a copy of the current .htaccess to your computer, or rename it on the server to .htaccess.bak as a quick backup. If new edits break the site, restoring the backup takes 10 seconds and brings the site back instantly.
  2. Edit with a code-friendly editor Use Notepad++, VS Code, Sublime Text, or similar. Avoid Microsoft Word or any rich-text editor — they’ll insert curly quotes, smart dashes, or hidden formatting that Apache rejects. Plain text only.
  3. Save with UNIX line endings Most editors offer this in their save options. Apache prefers LF line endings over CRLF (Windows-style). Most modern editors handle this transparently, but it’s worth checking if you’ve copied content from a Windows source.
  4. Make small, incremental changes Add one rule at a time, save, test the site. If something breaks, you know exactly which rule caused it. Adding 50 lines at once and discovering the site is broken is a debugging nightmare.
  5. Test the site immediately after upload Open your site in a fresh browser window or incognito tab right after every change. If you see a 500 Internal Server Error, revert immediately to your backup. Don’t try to debug live — restore first, then investigate.
  6. Check both the homepage and an inner page Some rules only affect specific URL patterns. The homepage might load fine while a product page or admin URL breaks. Test enough of the site to be confident.
💾
The Golden Rule

Always have a known-good backup within 30 seconds of access. .htaccess mistakes are almost never permanent — they take your site down for as long as it takes to revert. With a backup ready, that’s seconds. Without one, it’s a panic.

5. .htaccess Syntax Basics

Before the copy-paste rules, a quick orientation. The syntax is simple once you’ve seen it.

Comments

Anything after a # on a line is a comment, ignored by the server. Use comments liberally to label what each rule block does — your future self will thank you.

.htaccessComments
# This is a comment — Apache ignores it
# Use comments to explain what blocks of rules do

Module Blocks

Most rules are wrapped in <IfModule> tags. This tells Apache: “only run these rules if the named module is loaded.” It’s a safety mechanism — if the module isn’t installed, the rules are silently skipped instead of throwing errors.

.htaccessIfModule wrapper
<IfModule mod_rewrite.c>
  RewriteEngine On
  # Rules go here
</IfModule>

Common Modules

  • mod_rewrite — URL rewriting and redirects (most powerful module)
  • mod_headers — adds custom HTTP response headers
  • mod_expires — sets browser cache expiration times
  • mod_deflate — enables GZIP compression
  • mod_mime — handles file type associations

Order Matters

Apache processes .htaccess rules top to bottom. A rule near the bottom can override one near the top. When in doubt: more specific rules go before more general ones, and exclusions go before inclusions.

6. Redirects (HTTP → HTTPS, www, 301s)

Redirects are by far the most common .htaccess use case. Here are the patterns you’ll actually use.

Force HTTPS Site-Wide

The single most important redirect for any modern site. This sends all HTTP traffic to HTTPS automatically.

.htaccessForce HTTPS
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{HTTPS} off
  RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>

Force www (yoursite.com → www.yoursite.com)

.htaccessForce www
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{HTTP_HOST} ^yoursite\.com [NC]
  RewriteRule ^(.*)$ https://www.yoursite.com/$1 [L,R=301]
</IfModule>

Remove www (www.yoursite.com → yoursite.com)

.htaccessRemove www
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{HTTP_HOST} ^www\.yoursite\.com [NC]
  RewriteRule ^(.*)$ https://yoursite.com/$1 [L,R=301]
</IfModule>

301 Redirect a Single URL

For when a page has moved permanently and you want to preserve SEO equity. Always use 301 (not 302) for permanent redirects — 301s pass link equity to the new URL.

.htaccessSingle page 301
# Redirect a specific page
Redirect 301 /old-page.html https://yoursite.com/new-page

# Redirect an entire directory
Redirect 301 /old-folder https://yoursite.com/new-folder

Bulk Redirects with Patterns

For migrating from one URL structure to another. Useful when redesigning a site with predictable URL changes.

.htaccessPattern redirect
<IfModule mod_rewrite.c>
  RewriteEngine On
  # Redirect /blog/2024/ to /articles/2024/
  RewriteRule ^blog/(.*)$ /articles/$1 [L,R=301]
</IfModule>
💡
Combine HTTPS and www in One Block

Don’t create two separate redirect blocks for HTTPS and www — that causes a double redirect (HTTP → HTTP+www → HTTPS+www), which is slower and bad for SEO. Combine them into a single rule that goes straight to https://www.yoursite.com in one hop. Test with curl -I http://yoursite.com to confirm only one 301 fires.

7. Security Rules

Strong security defaults you should consider for every site.

Disable Directory Browsing

Without this, if someone navigates to a folder with no index file, Apache shows them a directory listing — exposing all files in that folder. Disable this universally.

.htaccessDisable directory browsing
Options -Indexes

Protect Sensitive Files

WordPress’s wp-config.php contains your database credentials. .htaccess itself can leak server config. Always block direct access to these.

.htaccessBlock sensitive files
# Protect .htaccess and wp-config.php
<FilesMatch "^(\.htaccess|wp-config\.php|\.env)$">
  Require all denied
</FilesMatch>

Block Specific IP Addresses

Useful for blocking known abusers. Note: dynamic IPs and proxies make this less effective long-term.

.htaccessBlock IPs
<RequireAll>
  Require all granted
  Require not ip 192.0.2.42
  Require not ip 198.51.100.0/24
</RequireAll>

Block Bad Bots and Scrapers

Stops the most common offenders by user agent string. Worth adding for any production site.

.htaccessBlock bad bots
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{HTTP_USER_AGENT} (semrushbot|ahrefsbot|mj12bot|dotbot) [NC]
  RewriteRule .* - [F,L]
</IfModule>

Add Security Headers

Modern HTTP security headers protect against common attacks. These are some of the most impactful with no real downside.

.htaccessSecurity headers
<IfModule mod_headers.c>
  # Force HTTPS for the next year
  Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
  # Prevent clickjacking
  Header always set X-Frame-Options "SAMEORIGIN"
  # Prevent MIME-sniffing
  Header always set X-Content-Type-Options "nosniff"
  # Control referrer information sharing
  Header always set Referrer-Policy "strict-origin-when-cross-origin"
  # Restrict browser features
  Header always set Permissions-Policy "geolocation=(), microphone=(), camera=()"
</IfModule>
🛡️
HSTS Is Permanent — Be Sure First

The Strict-Transport-Security header tells browsers to remember “this site is HTTPS only” for the duration you specify (one year above). Once browsers cache that, they’ll refuse to load the site over HTTP — even if you remove the header. Only enable HSTS when you’re certain HTTPS is fully working across the entire site, including all subdomains if you use includeSubDomains.

8. Performance: Caching & Compression

Two settings that meaningfully improve page load speed for almost any site.

Browser Caching with Expires Headers

Tells visitors’ browsers how long they can cache static files. Aggressive caching = repeat visitors load pages much faster.

.htaccessBrowser caching
<IfModule mod_expires.c>
  ExpiresActive On
  # Images — cache for a year
  ExpiresByType image/jpeg "access plus 1 year"
  ExpiresByType image/png "access plus 1 year"
  ExpiresByType image/webp "access plus 1 year"
  ExpiresByType image/svg+xml "access plus 1 year"
  # CSS and JS — cache for a month
  ExpiresByType text/css "access plus 1 month"
  ExpiresByType application/javascript "access plus 1 month"
  # Fonts — cache for a year
  ExpiresByType font/woff2 "access plus 1 year"
  # HTML — cache for an hour (changes more often)
  ExpiresByType text/html "access plus 1 hour"
  # Default for everything else
  ExpiresDefault "access plus 1 week"
</IfModule>

GZIP Compression

Compresses text-based files (HTML, CSS, JS) before sending them to browsers, often reducing transfer size by 60–80%.

.htaccessGZIP compression
<IfModule mod_deflate.c>
  AddOutputFilterByType DEFLATE text/html
  AddOutputFilterByType DEFLATE text/css
  AddOutputFilterByType DEFLATE text/javascript
  AddOutputFilterByType DEFLATE application/javascript
  AddOutputFilterByType DEFLATE application/json
  AddOutputFilterByType DEFLATE application/xml
  AddOutputFilterByType DEFLATE image/svg+xml
</IfModule>
Don’t GZIP Already-Compressed Files

JPG, PNG, WebP, MP4, and WOFF2 are already compressed in their native format. GZIPing them again wastes CPU cycles for no gain. Only apply DEFLATE filters to text-based content types like above. Most “complete” .htaccess templates online get this wrong.

9. Custom Error Pages

Default Apache error pages are ugly and unbranded. A custom 404 page is one of the easiest UX wins for any site.

.htaccessCustom error pages
# Point each error code to your custom page
ErrorDocument 400 /errors/400.html
ErrorDocument 401 /errors/401.html
ErrorDocument 403 /errors/403.html
ErrorDocument 404 /errors/404.html
ErrorDocument 500 /errors/500.html

Then create the actual HTML files at those paths. A good 404 page should: explain what happened in plain language, link prominently to the homepage and main sections, and ideally include a search box. Don’t forget to make it match your site’s design — a generic “Not Found” doesn’t build trust.

10. Access Control & Password Protection

Restrict who can access specific directories or files. Useful for staging sites, internal tools, or admin areas.

Password Protect a Directory

Browser-level authentication — visitors get a username/password prompt before they can access anything in the directory.

Step 1: Create an .htpasswd file

This stores the username and encrypted password. Generate one with an online .htpasswd generator or via SSH:

SSHCreate .htpasswd
htpasswd -c /home/youruser/.htpasswds/admin.passwd yourusername

Store this file outside your public web directory so visitors can’t download it. A common location: /home/youruser/.htpasswds/ rather than inside public_html.

Step 2: Add the .htaccess rule

Place this in the .htaccess of the directory you want protected:

.htaccessPassword protection
AuthType Basic
AuthName "Restricted Area"
AuthUserFile /home/youruser/.htpasswds/admin.passwd
Require valid-user

Restrict Access by IP Address

Allow only specific IPs (e.g., your office or VPN) to access a directory.

.htaccessIP whitelist
<RequireAll>
  Require ip 203.0.113.42
  Require ip 198.51.100.0/24
</RequireAll>

Block Access to Specific File Types

For example, blocking direct access to log files or backup files that shouldn’t be web-accessible.

.htaccessBlock file types
<FilesMatch "\.(log|sql|bak|old|backup)$">
  Require all denied
</FilesMatch>

11. The WordPress .htaccess Block

If you run WordPress, your .htaccess already contains a specific block that handles “pretty permalinks” — the SEO-friendly URLs. Never remove this block. Removing it breaks every URL on the site.

.htaccessWordPress default block
# BEGIN WordPress
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
  RewriteBase /
  RewriteRule ^index\.php$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /index.php [L]
</IfModule>
# END WordPress

Where to Add Your Custom Rules

WordPress regenerates everything between # BEGIN WordPress and # END WordPress automatically when permalinks are saved. Never put your custom rules inside that block — they’ll be overwritten without warning.

Always add your custom rules either above the WordPress block or below it, never inside. A clean structure looks like:

.htaccessRecommended structure
# Your custom redirects, security headers, caching rules
# go ABOVE the WordPress block

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{HTTPS} off
  RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>

# 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

Disable PHP Execution in /uploads

One of the most useful WordPress hardening rules. Prevents attackers from executing PHP files they’ve uploaded as image filenames. Place this in a separate .htaccess inside /wp-content/uploads/:

.htaccessuploads/.htaccess
<Files *.php>
  Require all denied
</Files>

12. Common Mistakes to Avoid

The mistakes that crash sites most often. Avoid these specifically and you’ll dodge 90% of .htaccess problems.

Mistake 1: Editing Without a Backup

Every .htaccess outage starts here. Always back up before any change. The cost of skipping this step is occasional site downtime; the cost of doing it is 5 seconds.

Mistake 2: Wrong Filename

Saving as htaccess.txt, .htaccess.txt, or htaccess means Apache won’t read your rules. The file must be named exactly .htaccess — leading dot, no extension.

Mistake 3: Curly Quotes from Word/Pages

Pasting from Word or Apple Pages converts straight quotes (") to curly quotes ("). Apache rejects curly quotes and throws errors. Always use a code editor.

Mistake 4: Custom Rules Inside the WordPress Block

Anything between # BEGIN WordPress and # END WordPress gets wiped whenever permalinks are saved. Custom rules go outside this block.

Mistake 5: Overlapping Redirects

Configuring HTTPS redirect and www redirect as separate rules creates a double redirect (HTTP → HTTPS → HTTPS+www), which is slower and harms SEO. Combine them into a single redirect to the final canonical URL.

Mistake 6: Forgetting IfModule Wrappers

Using a directive without checking the module is loaded means: if the host disables that module, your site 500s instead of gracefully skipping the rule. Always wrap module-specific rules in <IfModule>.

Mistake 7: Too Many .htaccess Files

Apache reads .htaccess on every request, walking up the directory tree from the requested file to the document root. Excessive nested .htaccess files in subdirectories slow down every page load. Consolidate where possible.

Mistake 8: Enabling HSTS Before HTTPS Is Solid

HSTS tells browsers to refuse HTTP connections for a year. If you enable it before SSL is fully working everywhere, you can lock yourself out of your own site. Get HTTPS working flawlessly first, then add HSTS.

Mistake 9: Not Testing After Each Change

Adding 50 lines and discovering the site is broken means you don’t know which line broke it. Add a few rules, save, test. Add more, save, test. You’ll trace any issue in seconds instead of hours.

13. Troubleshooting a Broken Site

Edited .htaccess, hit save, and now your site shows a 500 Internal Server Error? Don’t panic. Here’s the diagnosis flow.

  1. Restore the backup immediately The fastest path to a working site: replace your edited .htaccess with the backup you took before changes. Site comes back instantly. Then debug the broken version offline at your leisure.
  2. Check the Apache error log cPanel → Errors, or check error_log in your site root via SSH/FTP. Apache logs the exact line number and reason for any .htaccess error. This is by far the fastest way to identify what broke.
  3. Look for typos in your edited rules Common culprits: missing closing tag (</IfModule>, </FilesMatch>), unclosed quotes, wrong directive name, curly quotes from a rich-text editor, missing semicolon or pipe character in regex.
  4. Verify module availability Some directives only work if the corresponding Apache module is loaded. If you’re using a directive from mod_headers but the module isn’t enabled, Apache errors. Wrapping the rules in <IfModule mod_headers.c> prevents this.
  5. Test rules in isolation Comment out everything except one rule block at a time. The rule that breaks the site when uncommented is your culprit. Tedious but always works.
  6. Check AllowOverride Some hosts disable .htaccess overrides by default. If your rules don’t seem to apply at all (no errors, but no effect either), ask your host whether AllowOverride is set to All for your account. On managed hosts, the answer is sometimes a polite “no, we don’t allow that — but we’ll do the equivalent at server level for you.”
🛠️
Use an .htaccess Tester

Online tools like the htaccess Tester at htaccess.madewithlove.com let you paste your rules plus a URL and see what would happen — redirects, rewrites, blocks — without touching your live site. Invaluable for debugging complex rewrite rules before deploying.

14. Frequently Asked Questions

The questions that actually come up when working with .htaccess.

Does .htaccess slow down my site?

A small amount, yes — Apache reads the file on every single request, walking up from the requested file to the document root looking for .htaccess files at each level. Each file adds a tiny processing cost. For a typical site with one or two .htaccess files, the cost is negligible. For sites with dozens of nested .htaccess files in many subdirectories, it can add up. The general rule: keep rules in your root .htaccess when possible, and only use subdirectory .htaccess files when needed.

Can I have multiple .htaccess files on one site?

Yes — and it’s often useful. Common pattern: one in the site root with general rules, plus targeted ones in /wp-admin/ for password protection or /wp-content/uploads/ to disable PHP execution. Subdirectory files apply only to that directory and its subdirectories, and override conflicting rules from parent .htaccess files.

What’s the difference between 301 and 302 redirects?

A 301 is a “permanent” redirect — Google passes the SEO equity from the old URL to the new one, and browsers cache the redirect. A 302 is “temporary” — no SEO equity passes, browsers don’t cache it as aggressively. For URL changes that are really permanent (page moved, structure changed), always use 301. Use 302 only when you genuinely intend to revert the redirect later.

Why isn’t my .htaccess file working?

Most common causes, in order of likelihood: (1) wrong filename — must be exactly .htaccess with leading dot, no extension; (2) AllowOverride disabled by the host — your rules are being ignored at the server level; (3) syntax error somewhere causing Apache to ignore the entire file (check error logs); (4) you’re on Nginx, where .htaccess doesn’t apply; (5) caching — your browser or a CDN is serving a cached version.

Should I use .htaccess or modify Apache’s main config?

If you have access to the main Apache config (httpd.conf or apache2.conf), that’s faster — Apache reads it once at startup, not on every request. But on shared hosting and most managed hosts, you don’t have that access, which is why .htaccess exists. The performance difference for typical small-to-medium sites is rarely measurable. Use whatever you actually have access to.

Can I edit .htaccess directly in WordPress?

Yes — Yoast SEO and Rank Math both have built-in .htaccess editors under their tools menu. So does the WP Htaccess Editor plugin. These are convenient but with a catch: a syntax error here can lock you out of WordPress entirely. Always back up before saving, and have FTP/cPanel access ready as a fallback to revert manually if the dashboard becomes inaccessible.

How do I redirect a single old URL to a new one?

The simplest approach uses the Redirect directive: Redirect 301 /old-page-url https://yoursite.com/new-page-url. Place it above your WordPress block (if applicable). For more complex pattern-based redirects (e.g., redirecting an entire /blog/ structure), use RewriteRule with regex inside an <IfModule mod_rewrite.c> block.

My host uses Nginx — what do I use instead of .htaccess?

Nginx uses server-block configuration files (typically in /etc/nginx/sites-available/) that you edit directly with terminal access. On managed hosts running Nginx (Kinsta, WP Engine, Cloudways with default Nginx setups), you can’t edit these files directly — instead you contact support or use the host’s dashboard to request changes. For HTTPS redirects specifically, plugins like Really Simple SSL handle the equivalent within WordPress.

Will rules in .htaccess override security plugins like Wordfence?

Generally no — .htaccess rules execute at the Apache layer before PHP runs, while Wordfence operates inside WordPress at the PHP layer. They run at different stages and typically complement each other. .htaccess can block traffic before it ever reaches PHP (faster, lower resource use), while plugins offer more sophisticated logic for what does reach PHP. Use both for layered defense.

How do I see the current .htaccess rules taking effect?

For redirects, run curl -I https://yoursite.com from a terminal — it shows you the response headers including any 301/302 redirect chains. Browser DevTools (Network tab) shows the same information visually. For caching headers, look at any static asset’s response headers in DevTools — you should see Cache-Control and Expires values matching what you configured. Online .htaccess testers also let you simulate rule behavior without affecting your live site.

Can I block visitors from a specific country?

Yes, but it requires either a long list of IP ranges (impractical to maintain) or the GeoIP module (not always available on shared hosting). The cleaner approach is using Cloudflare’s free plan, which has a built-in country-blocking firewall rule that runs before traffic ever reaches your server. Cloudflare-based blocking is much more effective than IP-list-based blocking in .htaccess.

What’s the easiest way to force HTTPS without breaking anything?

First confirm your SSL certificate is fully working — visit https://yoursite.com directly and verify there are no warnings. Then add the standard HTTPS-forcing block (shown in section 6) above your WordPress block. Test with curl -I http://yoursite.com — you should see a single 301 redirect to the HTTPS version. Don’t enable HSTS until you’ve confirmed HTTPS is working everywhere for at least a few days.

Why does my .htaccess work locally but not on my live server?

Possible causes: (1) different Apache version with different supported syntax, (2) modules enabled locally but not on the live server (check with <IfModule> guards), (3) different AllowOverride settings, (4) different RewriteBase needs (subdirectory installations), (5) the local environment is actually using a different web server (XAMPP/MAMP both use Apache, but with different default modules than most production hosts). Always test on the actual production environment before assuming rules work.

How long should browser cache durations be?

For static assets that rarely change (images, fonts, versioned CSS/JS): 1 year (access plus 1 year). For HTML: short, like 1 hour, since you want changes to propagate quickly. The trick for handling updates to long-cached assets is “cache-busting” — appending a version string to filenames (style.css?v=1.2) so changes get a new URL that visitors haven’t cached. WordPress and most modern frameworks do this automatically.

Is .htaccess still relevant in 2026?

Yes, on Apache and LiteSpeed hosts (which is most shared hosting and a significant chunk of managed hosting). The Nginx-based managed hosts have moved away from .htaccess and handle equivalent functionality through dashboards or CDN rules — but Apache-based hosts haven’t gone anywhere and .htaccess remains the standard way to configure them. Even with the rise of CDN-level rule engines (Cloudflare, Fastly), .htaccess is still the right tool for site-level redirect logic, server-level security headers, and access control on Apache servers.

Powerful, Forgiving With a Backup,
Disastrous Without One.

The .htaccess file looks intimidating, but it’s really just a list of instructions for your web server, written in a syntax that becomes second nature after a few hours of use. Once you’ve forced HTTPS, set up a couple of redirects, added some security headers, and enabled caching, you’ve already done 80% of what most sites ever need.

The remaining 20% is specific edge cases — password-protecting a directory, blocking a specific bot, fine-tuning a complex rewrite — and the patterns from this guide cover almost all of them. When something doesn’t work, the answer is almost always in the Apache error log. Read the log, fix the typo, restore the backup if needed.

The single discipline that separates safe .htaccess users from people who occasionally take their own sites offline: backup before every edit, no exceptions. Do that, and the worst-case outcome of any mistake is 30 seconds of downtime while you restore.

Master a half-dozen rule patterns, keep backups handy, and your hosting becomes meaningfully faster, safer, and more controlled.