Where Apache configuration lives
Apache httpd reads its settings from httpd.conf or apache2.conf, from per-site files in sites-available, and from .htaccess files dropped into any web directory. That last one is the file most developers actually edit: WordPress permalinks, Laravel’s public/.htaccess, single-page-app fallbacks, HTTPS redirects and cache headers all live there, frequently on shared hosting where it is the only config you are allowed to touch. The syntax is line based. Each line is one directive, such as RewriteRule or Header set, and container sections like <VirtualHost>, <Directory>, <IfModule>, <FilesMatch> and <If> wrap groups of directives in XML-like opening and closing tags.
How to use it
Paste the configuration or drop the file onto the input. Section tags such as <VirtualHost> or directives like RewriteEngine and DocumentRoot identify it as Apache config. The output follows your edits live; use Ctrl/Cmd+Enter to reformat explicitly, and Ctrl/Cmd+Shift+C to put the result on the clipboard.
Choose 2 spaces, 4 spaces or tabs with Indent in the toolbar; that is the only setting, because the rest of the style follows from the structure of the file. The built-in Apache config printer processes everything inside your browser, which is worth knowing when the file contains basic-auth paths, internal proxy targets or IP allow-lists.
How the output is laid out
- Every directive inside a section is indented one level per enclosing section, so a
RewriteRuleinside<IfModule>inside<VirtualHost>sits two levels in. - Closing tags line up with their opening tags. Apache matches section names without regard to case, and so does the formatter; a mismatched-case closer such as
</DIRECTORY>is rewritten to the spelling of its opening tag. - Runs of spaces and tabs between arguments shrink to a single space, which straightens out hand-aligned
ProxyPassandSSLCertificateFilecolumns. Quoted arguments such as"^/a b$"or aHeader setvalue keep their inner spacing. - Directive names keep their case.
rewriteengine onis valid for Apache, and it is not rewritten. - Comments are indented with the lines around them. Blank lines are kept as separators, collapsed to one, and dropped directly after an opening tag or before a closing one.
- A directive continued onto the next line with a trailing backslash, common for long
LogFormatandHeadervalues, keeps its line breaks; the continuation is indented one extra level. If a quoted string itself spans the break, those lines are left exactly as written so the whitespace inside the quotes is not altered.
Checks before you upload
A broken .htaccess takes the whole directory down with a 500 Internal Server Error, so structure is checked before anything is printed. The formatter reports a section that is never closed, a closing tag with no opening partner, sections closed in the wrong order, and a section tag missing its >, each with the line number. It does not check directive names, arguments or whether the module behind an <IfModule> is loaded. apachectl configtest (or apache2ctl -t) remains the final word on a server you control.
Examples
.htaccess for a single-page app
Rewrite rules are indented inside their IfModule, and the FilesMatch section nests a level deeper with its quoted regex untouched.
# .htaccess for a single-page app
Options -MultiViews
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
</IfModule>
<IfModule mod_headers.c>
<FilesMatch "\.(css|js|woff2)$">
Header set Cache-Control "max-age=31536000, immutable"
</FilesMatch>
</IfModule>
# .htaccess for a single-page app
Options -MultiViews
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
</IfModule>
<IfModule mod_headers.c>
<FilesMatch "\.(css|js|woff2)$">
Header set Cache-Control "max-age=31536000, immutable"
</FilesMatch>
</IfModule>
HTTPS VirtualHost with column-aligned directives
Mixed tabs and spaces become a consistent indent, padded columns collapse to single spaces, and ${APACHE_LOG_DIR} is preserved.
<VirtualHost *:443>
ServerName shop.example.com
ServerAlias www.shop.example.com
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/shop.example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/shop.example.com/privkey.pem
ProxyPreserveHost On
ProxyPass /api http://127.0.0.1:8080/api
ProxyPassReverse /api http://127.0.0.1:8080/api
<Location /admin>
Require ip 10.0.0.0/8
</Location>
ErrorLog ${APACHE_LOG_DIR}/shop-error.log
</VirtualHost>
<VirtualHost *:443>
ServerName shop.example.com
ServerAlias www.shop.example.com
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/shop.example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/shop.example.com/privkey.pem
ProxyPreserveHost On
ProxyPass /api http://127.0.0.1:8080/api
ProxyPassReverse /api http://127.0.0.1:8080/api
<Location /admin>
Require ip 10.0.0.0/8
</Location>
ErrorLog ${APACHE_LOG_DIR}/shop-error.log
</VirtualHost>
Continued LogFormat and a lowercase closing tag, 4-space indent
The LogFormat keeps its backslash continuation, and </files> is printed as </Files> to match the opening tag.
LogFormat "%h %l %u %t \"%r\" %>s %b" \
common
<Files ".env">
Require all denied
</files>
LogFormat "%h %l %u %t \"%r\" %>s %b" \
common
<Files ".env">
Require all denied
</Files>
Common errors and how to fix them
| Error | Cause | Fix |
|---|---|---|
Section <VirtualHost> opened on line 1 is never closed | A container section has no closing tag, often because the paste stopped before the end of the file. | Add </VirtualHost> after the last directive that belongs inside it. |
Closing tag </Directory> on line 1 has no matching opening tag | A closing tag appears without its opening tag above it, typically after part of a block was deleted. | Remove the orphaned closing tag or restore the <Directory …> line it belongs to. |
Expected </Directory> (opened on line 1) but found </Files> on line 2 | Sections are closed in the wrong order, or the inner section was never closed before the outer one ends. | Close the innermost open section first; Apache requires sections to nest strictly. |
Section tag on line 1 is missing its closing '>' | An opening tag such as <Directory /var/www was not finished with >, so Apache cannot tell where its arguments end. | Add ‘>’ at the end of the tag. |
Malformed closing tag on line 3 | A closing tag contains extra text, as in </Directory /var/www>. Closing tags take no arguments. | Reduce it to the bare name, for example </Directory>. |
Frequently asked questions
Can I format a WordPress or Laravel .htaccess file?
Yes. The # BEGIN WordPress markers and other comments are kept, rewrite rules keep their exact patterns and flags, and only indentation and spacing change.
Will the formatter fix a 500 Internal Server Error?
It finds structural causes such as an unclosed <IfModule> or mismatched tags. Errors from a misspelt directive or a module that is not installed are only visible in the Apache error log.
Does it change RewriteRule patterns or flags?
No. Arguments are copied character for character; only the whitespace between them is reduced to single spaces.
Can I convert Apache config to nginx here?
No. The two formats work differently, especially for rewrites, so a conversion needs manual review. The nginx formatter can tidy the result once you have written it.