
.htaccess Generator
Generate Apache .htaccess rules for redirects, security, performance caching, and URL rewrites.
Last reviewed: April 2026New to this tool? Click here for instructions
Build Apache .htaccess rules visually — redirects, rewrites, security headers, caching, gzip, HSTS, IP blocks, and hotlink protection — then copy or download the finished file. Every byte is generated in your browser; nothing you type leaves the page.
What This Tool Does
The .htaccess Generator emits production-ready Apache configuration snippets for the most common per-directory needs: HTTP-to-HTTPS redirects, URL rewrites, security headers (X-Frame-Options, CSP, HSTS), file access restrictions (Deny from all for .env, .git, .log), gzip compression via mod_deflate, browser caching via mod_expires, and password-protected directories via .htpasswd references. Each rule is grouped by category so you can toggle exactly what you need without touching the others.
The tool covers the four directives Apache administrators reach for daily: RewriteEngine / RewriteCond / RewriteRule from mod_rewrite; Redirect from mod_alias; Header set from mod_headers; and ExpiresByType from mod_expires. Output is generated entirely client-side — your domain names, redirect targets, IP allowlists, and custom regex patterns never touch a server outside your local browser session.
How to Use It
The interface is organized around four rule categories, each with its own option panel. Pick the category that matches what you are trying to accomplish, toggle the checkboxes for the rules you want, and watch the right-hand pane fill with a live preview of your .htaccess file.
Step 1: Pick a Rule Type
Click one of the four mode chips at the top of the tool — Redirects, Security, Performance, or Custom Rewrite. The option panel on the left updates immediately to show the checkboxes and input fields relevant to that category. You can switch between modes without losing your in-progress configuration in each panel; the right-hand preview only displays the active category's output, but the underlying state is preserved.
Step 2: Fill in the Fields
For redirects, check HTTP to HTTPS for a universal force-HTTPS rule, www to non-www (or vice versa) for canonical-host normalization, and Remove trailing slashes to unify /page and /page/. Use Add Redirect to enter one-off mappings — old URL on the left, new URL on the right, 301 or 302 status code on the drop-down. For security, toggle every header you want emitted; the tool wraps them in a single <IfModule mod_headers.c> block automatically. For performance, the Expires checkboxes generate mod_expires directives with sensible long-cache values for static assets and shorter values for HTML. For custom rewrites, click + Add Rule and enter a regex pattern, substitution string, and flag list (L, R=301, QSA, etc.).
Step 3: Copy or Download the Snippet
The right-hand preview updates live as you toggle options. Hit Copy to grab the entire snippet to your clipboard, or Download to save it as a literal .htaccess file ready to upload via SFTP or cPanel's file manager. The status bar at the bottom shows a running count of rules generated — a quick sanity check that the file isn't empty before you deploy.
Worked Example: Force HTTPS, Drop www, and Enable Two-Year HSTS
This example builds a complete redirect-and-hardening configuration for a domain that should always be served over HTTPS at its bare apex (example.com, not www.example.com), with HSTS preload-ready headers attached on every response. The result is a single .htaccess block you can drop into the document root of any Apache-served site.
- Goal
- Every request — regardless of scheme or host — ends up at
https://example.com/...with HSTS, includeSubDomains, and preload directives set - Modules required
mod_rewrite,mod_headers(both enabled by default in modern Apache)- AllowOverride
- Must include at least
FileInfo Indexesin the controlling<Directory>block, or the .htaccess will be ignored
- Click the Redirects tab. Check HTTP to HTTPS redirect (301) and www to non-www redirect. The preview pane immediately shows a
RewriteEngine Online followed by two redirect blocks. - Switch to the Security tab. Check the headers you want — at minimum X-Content-Type-Options, X-Frame-Options, and Referrer-Policy. The HSTS line is not in the default checklist, so you will add it manually in the next step.
- Manually append the HSTS directive. Inside the
<IfModule mod_headers.c>block, add:Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload". Thealwayskeyword ensures the header is emitted on error responses too, which is required for HSTS preload qualification. - Copy the merged output. The final file combines the redirect block from the Redirects tab with the headers block from the Security tab. Save it as
.htaccessin your document root and upload it via SFTP. - Verify with curl. Run
curl -I http://www.example.com/— you should see a 301 withLocation: https://example.com/. Thencurl -I https://example.com/and confirm the Strict-Transport-Security header is present in the response. - Submit to the preload list. Once the header has been live for at least 24 hours and you have verified every subdomain is HTTPS-capable, submit your domain at hstspreload.org. Inclusion takes 6–12 weeks to roll into stable browser builds.
RewriteCond in sequence; a matching condition triggers its associated RewriteRule, which can issue a 301 redirect (terminating the request) or rewrite the URL internally and continue. After all rewrite logic passes, mod_headers attaches response headers before the resource is served.Expected output: a 301-chain that converts http://www.example.com/page to https://example.com/page, with HSTS attached on the final 200 response. Any future plain-HTTP attempt to the domain will be downgrade-resistant for 63072000 seconds (two years) after the first HTTPS visit — and instantly downgrade-resistant on any browser that ships the preload entry.
Common Use Cases
Six scenarios cover roughly 90% of the rules a typical site owner ever writes. Each one is a one-checkbox-or-two operation in the generator above.
1. Legacy URL Preservation After a CMS Migration
When you move from WordPress to a static-site generator, or from a custom PHP app to a headless CMS, old permalinks like /?p=1234 need to keep working — both for bookmarks and for the backlinks Google has already indexed. Use the Add Redirect button in the Redirects tab to enter one row per legacy URL. A 301 status code (the default) tells search engines to transfer ranking signal to the new URL; a 302 is for temporary moves and does not transfer authority. Bulk migrations of hundreds of redirects are better expressed with RedirectMatch regex patterns in the Custom Rewrite tab — for example RedirectMatch 301 ^/blog/(\d+)/(\d+)/(.*)$ /posts/$3 collapses date-based WordPress permalinks into a flat /posts/slug structure.
2. Country or Region-Based Redirects
Geographic redirects are typically driven by mod_geoip or mod_maxminddb, which expose the visitor's country code as an environment variable. A rule like RewriteCond %{ENV:GEOIP_COUNTRY_CODE} ^DE$ [NC] followed by RewriteRule ^$ /de/ [L,R=302] sends German visitors to the German subfolder on first visit. Use a 302 (temporary) rather than 301 (permanent) so that VPN users and travelers don't get cached into the wrong locale. The generator's Custom Rewrite tab accepts the regex pattern and substitution directly; you'll need to enable mod_geoip server-side first since .htaccess cannot load modules itself.
3. Password-Protected Directories with .htpasswd
For admin areas, staging environments, or restricted client folders, Basic Auth via .htpasswd is the simplest gate. Generate the password file with htpasswd -c /path/to/.htpasswd username (the -c creates the file; omit it for subsequent additions). Then add to .htaccess: AuthType Basic / AuthName "Restricted Area" / AuthUserFile /absolute/path/to/.htpasswd / Require valid-user. The .htpasswd file must live outside the document root or be explicitly denied access via <Files ".htpasswd"> Require all denied </Files>. Combine with the IP allowlist for a two-factor effect: even with valid credentials, only requests from specific IPs can authenticate.
4. Image Hotlink Prevention
Hotlinking — third-party sites embedding your images via <img src> tags that point at your server — burns your bandwidth without sending traffic. The generator's Hotlink protection checkbox emits a RewriteCond that checks the Referer header against your own domain, then a RewriteRule that returns 403 Forbidden for image extensions when the referer is external. The allowlist for empty-referer requests (!^$) is important: direct image loads, bookmarked URLs, and some privacy-respecting browsers all send empty referers, and blocking those would break ordinary use. Add google. and bing. to the allowlist if you want image search to keep showing your photos.
5. Gzip and Brotli Compression for Faster Transfers
Compression is one of the highest-impact performance levers available — modern HTML/CSS/JS payloads typically shrink by 65–80% after gzip, and Brotli typically beats gzip by another 10–20% on text payloads. The generator's Enable mod_deflate gzip compression checkbox emits an AddOutputFilterByType DEFLATE block covering HTML, CSS, JavaScript, JSON, SVG, and font formats. For Brotli, you would add a parallel AddOutputFilterByType BROTLI_COMPRESS block (requires mod_brotli, which is bundled with Apache 2.4.26+ but may need explicit enabling on some distributions). Apache's content negotiation automatically picks the best-supported encoding per request based on the client's Accept-Encoding header.
6. Security Headers (X-Frame-Options, CSP, Referrer-Policy)
A handful of response headers eliminate entire categories of vulnerabilities at almost zero cost. X-Frame-Options: SAMEORIGIN blocks your pages from being embedded in third-party iframes — the primary defense against clickjacking. X-Content-Type-Options: nosniff stops browsers from second-guessing your declared MIME types, which prevents a class of attacks where uploaded files are interpreted as scripts. Referrer-Policy: strict-origin-when-cross-origin stops leaking full URLs (including query strings) to external sites in the Referer header. Content-Security-Policy is the most powerful and the most complex; start with a report-only policy to learn what your site actually loads, then enforce. The Security tab in the generator handles the first three with checkboxes; for CSP, use the Custom Rewrite tab to paste your full policy string.
Edge Cases and Pitfalls
The .htaccess format is famously order-sensitive and famously easy to break. The pitfalls below cover the most common failure modes.
.htaccess is read on every request. Apache stats and parses every .htaccess file in the path of a requested resource on every single hit when AllowOverride is enabled. For /a/b/c/file.html, that means four filesystem stat calls and four parse passes — every request. On a busy site, this is a measurable latency cost. The fix is to migrate the same directives into the main server config inside a <Directory> block and set AllowOverride None, which lets Apache cache the parsed configuration at startup. Use .htaccess only when you do not control the main config — most commonly on shared hosting.
RewriteRule and RedirectMatch are not interchangeable. RewriteRule matches against the URL path with the leading slash stripped (^old-page, not ^/old-page); RedirectMatch matches against the full path including the leading slash (^/old-page). Mixing the two conventions in the same file is a common source of "why doesn't my rule fire" bugs. The generator emits the correct form for each directive automatically, but be aware when reading or modifying existing .htaccess files by hand.
mod_rewrite and mod_alias evaluate at different phases. mod_alias directives (Redirect, RedirectMatch, Alias) run during URL translation; mod_rewrite directives run during the fixup phase, which is later in the request lifecycle. When both are present in the same .htaccess, mod_rewrite sees the URL after mod_alias has already had its turn. Mixing them in a single file works for simple cases but produces confusing chains when rewrites and redirects overlap. Pick one module per file and stay consistent.
AllowOverride must permit the directive class. Even a perfectly written .htaccess file is silently ignored if the controlling <Directory> block sets AllowOverride None. The five override classes — AuthConfig, FileInfo, Indexes, Limit, Options — gate different directive families. RewriteRule needs FileInfo; Options -Indexes needs Options and (in Apache 2.4) Options=Indexes; AuthType needs AuthConfig. Check the vhost config first if your .htaccess seems to have no effect.
The file is line-and-block order sensitive. Multiple RewriteCond lines apply only to the next RewriteRule — they do not accumulate across rules. A misplaced blank line between RewriteCond and RewriteRule is harmless, but a misplaced rule between two conditions silently breaks the intended grouping. Always read .htaccess top-to-bottom as Apache does.
A single typo can break the entire site. A missing closing > on a directive, an unmatched <IfModule> block, or a misspelled directive name produces an Apache 500 Internal Server Error for every URL under the affected directory until the file is fixed. Always test .htaccess changes on a staging environment first, always have a known-good backup, and always have a way to roll back quickly (the generator's Download button gives you a clean version to keep alongside any in-progress edits).
Behind the Scenes: How Apache Processes .htaccess
mod_rewrite History and Design
mod_rewrite was written by Ralf S. Engelschall in 1996 as an external module for Apache 1.x, and was absorbed into the Apache core distribution in 1997. Engelschall called it "the Swiss Army knife of URL manipulation," and the module's reputation for power-and-complexity has stuck ever since — the official documentation famously opens with the line "The great thing about mod_rewrite is it gives you all the configurability and flexibility of Sendmail. The downside to mod_rewrite is that it gives you all the configurability and flexibility of Sendmail." The module's regex-based pattern matching, conditional preconditions, and chained-pass evaluation model were genuinely unique for a web server in 1996, and the design has held up remarkably well across 28 years.
The Rewrite Engine as a State Machine
Internally, mod_rewrite implements a fixed-point state machine over the request URI. Each pass through the ruleset starts with the current URI, evaluates every active RewriteRule in order, applies the first matching rule (or every matching rule if the [L] flag is absent), and produces a potentially-rewritten URI. If the URI changed during the pass, the engine optionally restarts at the top of the ruleset (the [N] flag forces this; default behavior is single-pass for performance). The fixed point is reached either when a pass completes without any rule matching, or when an [L] (last) flag terminates evaluation explicitly. RewriteCond directives stack as preconditions on the immediately-following RewriteRule; multiple conditions combine with logical AND by default, or with OR if the [OR] flag is present. This makes the syntax compact at the cost of being noticeably non-obvious — a single rule may have five preceding conditions, and you have to read the entire block to understand what triggers the rewrite.
How nginx Handles the Same Problems
Nginx — designed by Igor Sysoev in 2002 specifically to fix Apache's concurrency problems — deliberately omitted any per-directory configuration mechanism. The entire nginx configuration is parsed once at startup or reload, indexed into in-memory data structures, and consulted without filesystem I/O on subsequent requests. To accomplish what .htaccess does, nginx uses location blocks inside the main config: location /admin/ { auth_basic "restricted"; auth_basic_user_file /etc/nginx/.htpasswd; }. Rewrites use the rewrite directive with the same PCRE flavor Apache uses; redirects use return 301 https://...; security headers use add_header. The trade-off is explicit: nginx is faster (no per-request stat calls) and more uniform (one config file, one source of truth) at the cost of requiring root access and a reload to change anything. Apache trades that for the .htaccess affordance, which is invaluable on shared hosting where users have no other way to configure their virtual host.
Comparison: Apache .htaccess vs Nginx vs Caddy vs Cloudflare Page Rules
Four mainstream options exist for the kinds of rules you would write in .htaccess. The right pick depends on your hosting model, your tolerance for restart cycles, and whether you want edge or origin enforcement.
| Tool | Where Rules Live | Reload Required? | Per-Request Cost | Best For |
|---|---|---|---|---|
| Apache .htaccess | Per-directory file in document root | No — read on every request | Highest (filesystem stat + parse per request) | Shared hosting; sites where you cannot edit the main config |
| Apache httpd.conf / vhost | Main server config; <Directory> blocks |
Yes — apachectl graceful |
Negligible (parsed once at startup) | Self-hosted Apache where you control the box |
| Nginx | nginx.conf — single global config | Yes — nginx -s reload |
Negligible (parsed once, in-memory lookup) | High-concurrency sites; reverse proxies; CDN origins |
| Caddy | Caddyfile — declarative format | Yes — auto-reload on file change, or API call | Negligible | Modern stacks with automatic HTTPS; HTTP/3 by default |
| Cloudflare Page Rules / Rulesets | Cloudflare dashboard or API | No — propagates globally in seconds | None at origin — runs at the edge | Sites already on Cloudflare; geographic rules; bulk redirects |
The practical decision matrix is simple. On shared hosting (Bluehost, DreamHost, SiteGround), you have only .htaccess — use it. On a VPS or dedicated server running Apache where you have root, move everything to httpd.conf and set AllowOverride None for the performance win. If you're starting greenfield with no Apache investment, pick Caddy for automatic HTTPS or nginx for raw throughput. If you are already on Cloudflare, push as much rule logic as possible to Rulesets (the modern replacement for the deprecated Page Rules) so it runs at the edge and never touches your origin server.