Het .htaccess-bestand is een van die dingen die elke WordPress-, Joomla- of OpenCart-eigenaar wel eens tegenkomt — vaak in een tutorial die zegt "voeg deze regel toe aan je .htaccess" — zonder verder uit te leggen wát je nu precies aan het doen bent. Resultaat: of het werkt (gefeliciteerd), of je site is offline en je weet niet waarom (welkom in de support-ticket).
In dit artikel: wat .htaccess precies is, welke dingen je er praktisch mee doet, en de klassieke fouten waar mensen hun site mee slopen. Geen pretentie van compleetheid — wel genoeg om de meeste tutorials te begrijpen en zelfstandig te beoordelen.
Wat is .htaccess eigenlijk?
Het is een configuratiebestand voor de Apache webserver (en LiteSpeed, dat compatible is). De naam betekent "hypertext access" en het bestand staat normaal in de root van je website (de map waar ook index.php of index.html staat).
De truc is dit: Apache laat je per directory server-instellingen overschrijven via een .htaccess-bestand in die map. Geen server-restart nodig, geen toegang tot de hoofdserverconfig — direct werkende wijzigingen. Dat maakt .htaccess razendsnel inzetbaar, en tegelijk dé plek waar mensen onbedoeld dingen kapotmaken.
Waar vind je .htaccess?
Standaard in de webroot — typisch /public_html/.htaccess of /www/.htaccess. Het bestand begint met een punt, wat betekent dat het in veel filemanagers verborgen is.
- In cPanel File Manager: zet "Show Hidden Files" aan via Settings
- In DirectAdmin File Manager: dezelfde optie zit in de instellingen
- Via FTP/SFTP: configureer je client (FileZilla: Server → Force showing hidden files)
- Via SSH:
ls -latoont alle bestanden inclusief verborgen
Bestaat het bestand niet? Dan kun je 'm zelf aanmaken — gewoon een tekstbestand zonder extensie, alleen met de naam .htaccess.
De basisstructuur
Een .htaccess-bestand is gewoon platte tekst. Elke regel doet één ding. Witregels en commentaarregels (die met # beginnen) worden genegeerd. Modules worden aangeroepen met <IfModule ...> blokken — handig om te voorkomen dat je site crasht als de hosting een bepaalde module mist.
# Dit is een commentaar — Apache negeert deze regel
# Modules altijd in IfModule wrappen
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^oude-pagina$ /nieuwe-pagina [R=301,L]
</IfModule>
Wat kun je er praktisch mee?
Hieronder de meest gebruikte toepassingen, in volgorde van hoe vaak je ze tegenkomt.
1. Redirects — van oude URL naar nieuwe
Als je een pagina verhuist of weghaalt, wil je dat bezoekers (en Google) op de juiste plek terechtkomen. Twee soorten redirects:
- 301: permanent verhuisd. Google haalt de oude URL uit de index en linkt z'n autoriteit naar de nieuwe
- 302: tijdelijk verhuisd. Google houdt beide URLs in de gaten
Eenvoudige 301 redirect:
Redirect 301 /oude-pagina.html /nieuwe-pagina.html
Of voor een hele map:
Redirect 301 /blog/ /artikelen/
Met patroonherkenning (regular expressions) via mod_rewrite:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^product/([0-9]+)$ /producten/$1 [R=301,L]
</IfModule>
Dit verandert /product/42 naar /producten/42 — handig na een herstructurering.
2. HTTPS forceren
Heb je een SSL-certificaat geïnstalleerd? Dwing dan af dat alle bezoekers via HTTPS komen — niet alleen voor security, maar ook omdat Google HTTPS sinds 2018 als rankingfactor gebruikt.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>
3. WWW of non-WWW kiezen
Een site moet maar één canonieke URL hebben. Kies of je jouwsite.nl of www.jouwsite.nl als hoofd-URL gebruikt en dwing de andere af.
Forceer non-www (mijn voorkeur — schoner):
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]
</IfModule>
Forceer www:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
</IfModule>
4. Eigen 404-pagina aanwijzen
Standaard krijgt iemand die op een dode link klikt een Apache-foutpagina. Veel mooier: een eigen pagina die past bij je site, met handige links erop.
ErrorDocument 404 /404.html
ErrorDocument 500 /server-error.html
5. IP-adressen blokkeren
Last van een specifiek IP dat je site bezoekt voor verkeerde redenen?
<RequireAll>
Require all granted
Require not ip 192.168.1.100
Require not ip 10.0.0.0/24
</RequireAll>
Of alleen jezelf binnenlaten (handig tijdens cleanup):
<RequireAll>
Require ip 123.45.67.89
</RequireAll>
6. Bepaalde bestanden afschermen
Sommige bestanden in je webroot zijn niet bedoeld voor het publiek. Bijvoorbeeld wp-config.php in WordPress of configuration.php in Joomla.
<Files wp-config.php>
Require all denied
</Files>
<Files .htaccess>
Require all denied
</Files>
<FilesMatch "\.(env|log|sql|bak)$">
Require all denied
</FilesMatch>
7. PHP-uitvoering blokkeren in /uploads/
Een van de belangrijkste hardeningsregels voor WordPress. Plaats dit in wp-content/uploads/.htaccess:
<Files *.php>
Require all denied
</Files>
Aanvallers die malware in uploads dumpen kunnen 'm hierdoor niet meer uitvoeren via een directe URL. Zie ook het WordPress hardening artikel waar dit één van de tien stappen is.
8. Hotlink protection
Voorkom dat anderen jouw afbeeldingen direct embedden in hun site (en jouw bandbreedte gebruiken).
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^https?://(www\.)?jouwsite\.nl [NC]
RewriteRule \.(jpg|jpeg|png|gif|webp)$ - [F]
</IfModule>
9. Compressie inschakelen (gzip)
Comprimeer HTML, CSS en JavaScript voor verzending — bezoekers laden sneller, jij gebruikt minder bandbreedte.
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/css text/javascript
AddOutputFilterByType DEFLATE application/javascript application/json
AddOutputFilterByType DEFLATE image/svg+xml
</IfModule>
10. Browser-caching
Vertel browsers hoe lang ze afbeeldingen, CSS en fonts mogen cachen. Snellere herhaalbezoekjes, lagere serverbelasting.
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/svg+xml "access plus 1 year"
ExpiresByType image/webp "access plus 1 year"
ExpiresByType font/woff2 "access plus 1 year"
</IfModule>
11. Directory listing uitschakelen
Als een map geen index.html of index.php heeft, toont Apache standaard een lijst van bestanden. Niet alleen lelijk — ook potentieel een security-issue.
Options -Indexes
12. Wachtwoord op een hele map
Voor een staging-omgeving of beheer-map is HTTP basic auth een snelle manier om iedereen buiten te houden:
AuthType Basic
AuthName "Beveiligde sectie"
AuthUserFile /pad/naar/.htpasswd
Require valid-user
Het bestand .htpasswd bevat de gehashte gebruikersnaam-wachtwoord-combinaties. Gebruik een online generator of de CLI htpasswd-tool om er een aan te maken.
De standaard WordPress .htaccess
Voor referentie — zo ziet de schone, standaard WordPress .htaccess eruit:
# 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
Dit is wat WordPress nodig heeft om "permalinks" te laten werken (mooie URLs in plaats van ?p=123). Verwijder deze blok niet — dan breken al je interne links.
Hoe sloop je je site? — De klassieke fouten
Een paar foutpatronen waar veel mensen tegenaan lopen:
Onbedoelde syntax-errors
Eén missende </IfModule>, een typefout, of een ontbrekende slash — en Apache geeft een 500 Internal Server Error voor de hele site. Heel het pad (https://jouwsite.nl/) werpt direct een fout, ook al is er verder niets aan de hand.
Module gebruiken die niet beschikbaar is
Schrijf je RewriteEngine On zonder <IfModule mod_rewrite.c> wrapper, en je hosting heeft mod_rewrite uitgeschakeld? Bam, 500-error. Daarom altijd in IfModule wrappen.
Redirect-loops
Verkeerde HTTPS-redirect die naar zichzelf wijst, of een RewriteCond die per ongeluk altijd matcht. Resultaat: browser meldt "Te veel redirects" en stopt.
Geen line-endings
Sommige editors slaan op met Windows-line-endings (CRLF) waar Apache LF verwacht. Sommige Apache-versies kunnen daarmee omgaan, andere niet. Werk bij voorkeur in een echte code-editor (VS Code, Sublime, Notepad++) en zet line endings op LF.
.htaccess in een submap die de root-config breekt
Plaats je per ongeluk een .htaccess met algemene regels in /wp-content/, dan worden de regels alleen voor die map toegepast — soms onverwacht in conflict met je root-htaccess.
Hoe test je veilig?
Drie regels om je site niet te slopen:
1. Maak altijd eerst een backup
Letterlijk: kopieer de huidige .htaccess naar .htaccess.backup voordat je iets wijzigt. Bij problemen: hernoem terug en je site is direct weer online.
2. Voeg één regel of blok tegelijk toe
Drop niet 50 regels uit een tutorial in één keer — voeg klein toe en test elke wijziging. Wanneer iets breekt, weet je precies welke regel.
3. Test in een private/incognito browser
Browsers cachen agressief, vooral redirects. Een 301 die je hebt teruggedraaid kan in je normale browser nog steeds doorsturen — incognito laadt vers.
# test 12345 toe (een commentaar). Schiet de site niet in een 500-error? Dan parsed Apache het bestand. Werpt 'ie wel een fout? Dan is er waarschijnlijk een syntax-fout boven die regel.
Wanneer schakel je hulp in?
- Site werpt 500-errors en je weet niet welke regel het veroorzaakt
- Je redirects vormen een loop die je niet ontrafelt
- Complexe rewrites met meerdere voorwaarden — als je de syntax van
RewriteCondenRewriteRuleniet doorgrond, kost trial-and-error meer tijd dan het waard is - Migratie van een grote site waarbij honderden URL's moeten redirecten naar nieuwe paden
- Performance-tuning waarbij compressie, caching, mod_pagespeed en HTTP/2 push allemaal samenkomen
- Beveiligingsincident waarbij verdachte regels in .htaccess zijn aangetroffen — die moeten weg, maar niet zomaar (zie het artikel over Chinese spam voor context)
Voor de basisingrepen — een redirect, HTTPS forceren, een 404-pagina — kun je heel ver komen met de voorbeelden in dit artikel. Maar zodra je vijf regex-patronen in elkaar gevlochten hebt en niet meer overziet wat ze doen, is dat het signaal om iemand erbij te halen.