Create an .htaccess file right in your browser and download it instantly for use on Apache servers.
<IfModule mod_rewrite.c>
RewriteEngine On
# Force HTTPS
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>
# Gzip compression
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript application/json application/xml application/rss+xml image/svg+xml
</IfModule>
# Browser caching
<IfModule mod_expires.c>
ExpiresActive On
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"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType text/html "access plus 1 hour"
</IfModule>A .htaccess file is Apache's per-directory configuration mechanism — small text files that override pieces of the main server config without a restart. XConvert's generator builds the rule blocks you actually need (mod_rewrite 301 redirects, force HTTPS, force or strip www, HSTS, gzip / Brotli mod_deflate, browser-cache headers, custom ErrorDocument pages, Options -Indexes, hotlink protection, IP / bot deny rules, password protection) from short forms — pick a recipe, fill the params, and copy a syntactically valid block. Everything runs in your browser; nothing is uploaded.
ErrorDocument 404 / 403 / 500), Gzip Compression (mod_deflate), Browser Caching (mod_expires / Cache-Control), Hotlink Protection, and Disable Directory Listing (Options -Indexes). Each recipe maps to a documented Apache module.example.com for force-www, source /old-page and target /new-page for a 301, IP range like 192.0.2.0/24 to deny, or a user-agent substring like AhrefsBot to block. The generator escapes regex metacharacters where needed and adds the matching RewriteCond lines.RewriteEngine On once at the top, redirect rules before rewrite rules, and <IfModule> guards around each module so the file degrades gracefully if a module isn't loaded..htaccess. Click Copy or Download, upload to the directory you want it to govern, and verify with curl -I before publishing — Apache does not validate .htaccess at write time, so a syntax error returns a 500 Internal Server Error on every request until you fix it..htaccess is the file Apache reads to apply per-directory overrides — URL rewriting, access control, MIME types, response headers, caching — without editing the main httpd.conf or restarting the server. That makes it indispensable on shared hosting (cPanel, Plesk, DreamHost, SiteGround) where you have no root access, and on WordPress / Magento / Laravel installs that ship a default .htaccess you customize per site. The flip side is that one typo brings the whole site down with a 500 until you SSH in or re-upload, so generating from templates beats hand-editing for most operators.
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]) leaves the first request unencrypted. Adding Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" and submitting to hstspreload.org tells every modern browser to skip HTTP entirely. The 31,536,000-second (1 year) max-age is the minimum the preload list requires.example.com and www.example.com as separate hosts and split link equity unless one 301-redirects to the other. The generator emits the canonical RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC] / RewriteRule ^(.*)$ https://%1/$1 [R=301,L] form (or the inverse) without typos./?p=123 to /post-slug/, or from .html to clean URLs, needs hundreds of one-off rules. Using RedirectMatch 301 for patterns and Redirect 301 /old /new for single URLs preserves crawl signals; 302 (temporary) is the wrong tool for permanent moves.AuthType Basic plus an AuthUserFile pointing at an .htpasswd file is the fastest way to gate a staging environment from the public web. The generator outputs the .htaccess block; you still need to upload the .htpasswd with bcrypt or APR1 hashes (never plain text).RewriteCond %{HTTP_USER_AGENT} (AhrefsBot|SemrushBot|GPTBot|CCBot|ClaudeBot) [NC] followed by RewriteRule ^ - [F] returns 403 to listed bots. Combine with a robots.txt (RFC 9309) for crawlers that respect it.AddOutputFilterByType DEFLATE text/html text/css application/javascript application/json halves the bytes for text assets, and ExpiresByType image/webp "access plus 1 year" lets browsers reuse static files instead of revalidating. Both are Lighthouse / PageSpeed Insights line items.ErrorDocument 404 /404.html keeps visitors on the site instead of dropping them on Apache's beige default. The path must be a server-relative URL (begin with /), not a filesystem path.| Property | Apache .htaccess |
nginx |
|---|---|---|
| Per-directory config | Yes — picked up automatically | No equivalent — central config only |
| Reload required | No — re-read on every request | Yes — nginx -s reload |
| Performance cost | Adds ~4 stat() calls per request even on misses (Apache docs) | Single config parse at startup |
| URL rewriting | mod_rewrite (RewriteRule, RewriteCond) |
rewrite directive in server / location blocks |
| Auth | AuthType Basic + .htpasswd |
auth_basic + auth_basic_user_file |
| Gzip compression | mod_deflate + AddOutputFilterByType |
gzip on; + gzip_types |
| Cache headers | mod_expires / Header set Cache-Control |
expires + add_header Cache-Control |
| Access from shared hosting | Almost always allowed | Almost never — root-only |
| Syntax error blast radius | 500 on every request until fixed | Reload fails — old config keeps running |
Apache's official guide explicitly recommends putting rules in httpd.conf when you have access: "If you have access to the main server configuration file, you should put all of your configuration there instead of in .htaccess files. Use of .htaccess files can be avoided completely if you have access to the main server configuration file." Use .htaccess when you don't have that access — which is the common case on shared hosting.
| Directive | Module | What it does |
|---|---|---|
RewriteEngine On |
mod_rewrite | Turns the rewrite engine on (required before any RewriteRule) |
RewriteCond |
mod_rewrite | Conditional that must match before the next RewriteRule fires |
RewriteRule pattern substitution [flags] |
mod_rewrite | Matches the URL path against a regex and rewrites or redirects |
Redirect 301 /old /new |
mod_alias | Simple permanent redirect (no regex) |
RedirectMatch 301 ^/old/(.*)$ /new/$1 |
mod_alias | Pattern-based 301 with capture groups |
Header set / always set |
mod_headers | Adds a response header (HSTS, CSP, X-Frame-Options) |
ExpiresByType image/webp "access plus 1 year" |
mod_expires | Sets a Cache-Control: max-age for a MIME type |
AddOutputFilterByType DEFLATE text/html |
mod_deflate | Gzip-compresses a MIME type on the fly |
ErrorDocument 404 /404.html |
core | Replaces Apache's default error page |
Options -Indexes |
core | Disables directory listing when no index file exists |
AuthType Basic + Require valid-user |
mod_auth_basic | HTTP Basic Auth gate |
Order / Require ip / Require not host |
mod_authz_host | IP / host allow / deny list |
<IfModule mod_xxx.c>...</IfModule> |
core | Guard so the file works on servers without that module loaded |
Each RewriteRule accepts [flags] — the common ones are R=301 (issue a 301 redirect), L (last — stop processing), NC (case-insensitive match), F (forbidden — return 403), QSA (append the original query string), and NE (don't escape special characters in the substitution).
Two reasons. First, you usually can't edit httpd.conf on shared hosting — that file is owned by root and shared across thousands of customer sites. .htaccess is the only override mechanism the hosting provider lets you touch. Second, even where you have root, .htaccess lets you change rules without restarting Apache — the file is re-read on every request, so edits take effect instantly. The Apache docs are blunt that you should prefer httpd.conf when you can use it, because .htaccess carries a per-request performance cost, but for any non-root deployment that choice doesn't exist.
The exact words from the Apache 2.4 documentation: "Permitting .htaccess files causes a performance hit, whether or not you actually even use them!" For a request that resolves to /www/htdocs/example/, Apache stats .htaccess in every parent directory — /, /www, /www/htdocs, /www/htdocs/example — even if those files don't exist, adding roughly 4 extra filesystem accesses per request. Regex patterns also recompile on every request (they're cached in httpd.conf). On a low-traffic site this is undetectable; on a busy site with AllowOverride All it's measurable. The fix is either move the rules into httpd.conf with AllowOverride None, or use AllowOverrideList to whitelist only the directives you need (e.g. RewriteEngine RewriteRule RewriteCond Redirect) so Apache short-circuits the rest.
There isn't one, by design. nginx parses a single tree of config files (nginx.conf plus included files) at startup and on nginx -s reload. It does not scan request paths for per-directory config — that's a deliberate architectural choice for performance. Equivalent rules go in a server { ... } or location { ... } block: Apache's RewriteRule becomes nginx's rewrite / return 301; Header set becomes add_header; mod_deflate becomes gzip on;; Basic Auth becomes auth_basic. The tradeoff: you need shell access and a reload after every change, but you avoid the per-request file-stat cost. NGINX's own documentation says it explicitly: nginx "does not interpret .htaccess files, and neither does it provide a mechanism for evaluating any per-directory configuration outside of the main configuration file."
For a single URL with no pattern, use mod_alias: Redirect 301 /old-page /new-page. For a pattern with capture groups, use RedirectMatch 301 ^/blog/([0-9]+)/(.*)$ /posts/$2. For anything that needs to inspect headers, the query string, or the host, drop into mod_rewrite:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]
Always use R=301 for permanent moves (302 is temporary and search engines won't transfer ranking signals). Add L to stop processing further rules, and NC for case-insensitive host matches.
Two blocks. First the redirect:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
Then the HSTS header, conditional on mod_headers:
<IfModule mod_headers.c>
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
</IfModule>
The preload token is your signal that you want to be added to the browser preload list — apply at hstspreload.org. Once preloaded, every modern browser refuses HTTP to your domain even on the first visit, eliminating the SSL-strip window. Removing yourself from the list later is slow (months), so make sure every subdomain works over HTTPS before you submit.
Options -Indexes in the directory's .htaccess (or any parent). When a visitor requests /uploads/ and there's no index.html or index.php, Apache will return 403 Forbidden instead of an auto-generated directory listing. The default on most distros is Options Indexes FollowSymLinks, which is exactly the auto-listing behavior you don't want exposed publicly. Pair with Options -ExecCGI if you accept user uploads and don't want them executed as scripts.
A small set of flags handles 95% of cases: R=301 for permanent redirect, L to stop after the rule fires, NC for case-insensitive, F to return 403, QSA to keep the original query string, and NE to preserve special characters in the substitution. Useful built-in variables: %{HTTP_HOST}, %{REQUEST_URI}, %{QUERY_STRING}, %{HTTPS} (on / off), %{REMOTE_ADDR}, %{HTTP_USER_AGENT}. The two file-existence tests -f and -d (plus their negations !-f, !-d) drive the front-controller pattern that WordPress, Laravel, and most PHP frameworks ship — route every request that doesn't match a real file or directory to index.php.
Apache does not validate .htaccess at write time, so the only feedback you get from a typo is a 500 on every request until you fix it. Three things help: (1) Keep a known-good copy and a one-line shell snippet ready (mv .htaccess.bak .htaccess) so you can roll back instantly. (2) On a server you control, run apachectl configtest after copying the rules into a <Directory> block in httpd.conf — that catches syntax errors without affecting live traffic. (3) Use curl -I https://example.com/test-path to verify the response code, redirect target, and headers after deploying. If you have shell access, tail -f /var/log/apache2/error.log shows the exact rewrite or syntax error.
Yes. For IPs on Apache 2.4 use the Require syntax (the old Order / Deny from syntax was for 2.2):
<RequireAll>
Require all granted
Require not ip 192.0.2.0/24
Require not ip 203.0.113.5
</RequireAll>
For User-Agents, use mod_rewrite with the F (forbidden) flag:
RewriteCond %{HTTP_USER_AGENT} (AhrefsBot|SemrushBot|MJ12bot|GPTBot|CCBot|ClaudeBot) [NC]
RewriteRule ^ - [F]
This returns 403 to the listed scrapers and AI-training bots. Layer it with a robots.txt (RFC 9309) for crawlers that respect that file, since User-Agent matching is trivially spoofable — treat it as a soft signal, not security.
Server-config files usually ship together. XConvert has companion generators for the adjacent pieces: Cron Expression Generator for log-rotation and cache-purge schedules, Password Generator for the .htpasswd credentials referenced by AuthUserFile, and URL Encoder for safely escaping characters in redirect targets.