Terug naar hoofdinhoud
.htaccess in Joomla
Op deze pagina
# Topics

.htaccess in Joomla

05 juli 2026

Eén klein tekstbestand in de hoofdmap van je Joomla, het .htaccess-bestand, bepaalt of je mooie URL’s werken, of veelvoorkomende aanvallen worden geblokkeerd en of je CSS en JavaScript gecomprimeerd worden geleverd. De meeste site-eigenaren openen het nooit, maar het wordt bij bijna elk verzoek aan een Apache-server uitgevoerd. Als het ontbreekt of onjuist is, geven pagina’s de foutmelding "404 Not Found" weer, ziet de site er kapot uit of blijft deze stilletjes minder veilig dan zou moeten.

In dit artikel wordt het Joomla .htaccess-bestand van begin tot eind uitgelegd. Het behandelt de basisprincipes voor site-eigenaren, het hernoemen en de SEF-configuratie voor beheerders, en de herschrijfregels, beveiligingsblokken en prestatietips die ontwikkelaars moeten begrijpen.

Het .htaccess-bestand is de poortwachter van een Apache Joomla-website: het bepaalt wat er binnenkomt, waar het naartoe gaat en hoe snel het aankomt.

Het doel is simpel: je helpen begrijpen wat elk blok in het meegeleverde bestand doet, zodat je het met vertrouwen kunt gebruiken en veilig kunt aanpassen.

1. De basis

1.1 Wat is het .htaccess-bestand?

Het .htaccess-bestand (de naam betekent "hypertext access") is een configuratiebestand per map voor de Apache-webserver. Hiermee verander je hoe de server zich gedraagt voor een map en alles daaronder, zonder de hoofdconfiguratie van de server aan te raken. De punt aan het begin maakt het op Linux een verborgen bestand, en daarom tonen veel bestandsbeheerders het standaard niet.

Joomla gebruikt het voor vier hoofdtaken:

  • Mooie SEF-URL's omzetten naar verzoeken die Joomla kan routeren.
  • Een aantal van de meest voorkomende aanvalspatronen in de URL blokkeren.
  • Een paar beveiligingsheaders en toegangsregels instellen.
  • Vooraf ingepakte CSS en JavaScript serveren als die bestaan.

1.2 Waarom het als htaccess.txt wordt meegeleverd

Joomla installeert geen actief .htaccess-bestand. In plaats daarvan levert het een kant-en-klaar sjabloon met de naam htaccess.txt in de hoofdmap. Daar zijn twee redenen voor. Ten eerste is een verborgen bestand makkelijk over het hoofd te zien bij een upload. Ten tweede kan een .htaccess-bestand met rewriteregels de hele site stukmaken op een server die ze niet ondersteunt. Door het als gewone .txt mee te leveren, blijft het inactief tot je het zelf wilt gebruiken.

Om het te activeren, hernoem je het bestand:

htaccess.txt   →   .htaccess

Deze ene hernoeming is de stap die de meeste beginners vergeten. De twee bestanden zijn byte voor byte identiek; alleen de naam verschilt.

1.3 Waar het staat

Het bestand staat in de Joomla-hoofdmap, naast index.php en configuration.php:

public_html/
   index.php
   configuration.php
   htaccess.txt        ← het meegeleverde sjabloon
   .htaccess           ← het actieve bestand na het hernoemen
   web.config.txt      ← het IIS-equivalent (alleen Windows)

Apache leest .htaccess alleen als dat is toegestaan (zie hoofdstuk 11). Op de meeste shared hosting is dat standaard toegestaan, en juist daarom is .htaccess daar zo populair.

Naar boven

2. Mooie URL's aanzetten

2.1 De twee Joomla-instellingen

Mooie URL's hangen af van twee opties in Systeem → Globale configuratie → Site, plus het bestand zelf:

  • Zoekmachinevriendelijke URL's maakt van index.php?option=com_content&view=article&id=42 de URL /nieuws/42-mijn-artikel. Dit werkt op elke webserver, met of zonder .htaccess.
  • URL-herschrijven gebruiken haalt index.php uit het pad, zodat de URL /nieuws/mijn-artikel wordt. Deze optie heeft de rewrite-engine van de webserver en het bijbehorende configuratiebestand nodig.

2.2 De volgorde die een kapotte site voorkomt

Doe de stappen in deze volgorde:

  1. Hernoem eerst htaccess.txt naar .htaccess.
  2. Zet daarna URL-herschrijven gebruiken = Ja in de globale configuratie.
  3. Open een paar interne links en controleer of ze laden.

Als je het herschrijven aanzet voordat het bestand bestaat, maakt Joomla URL's zonder index.php, maar weet Apache niet hoe het die moet routeren, en geeft elke pagina behalve de homepage een 404.

2.3 Wat elke instelling oplevert

SEFURL-herschrijvenVoorbeeld-URL
Uit Uit /index.php?option=com_content&view=article&id=42
Aan Uit /index.php/nieuws/42-mijn-artikel
Aan Aan /nieuws/mijn-artikel

Alleen de laatste rij heeft .htaccess nodig. De middelste rij is de veilige terugval als herschrijven niet beschikbaar is: index.php blijft in het pad, maar de URL is nog steeds leesbaar.

Naar boven

3. Het begin van het bestand: opties en headers

Voordat er iets wordt herschreven, stelt het meegeleverde bestand een paar serveropties en beveiligingsheaders in. Die draaien zelfs als mod_rewrite uitstaat.

Options +FollowSymlinks
Options -Indexes

+FollowSymlinks laat Apache symbolische links volgen, wat mod_rewrite nodig heeft. De opmerkingen in het bestand waarschuwen dat sommige hosts verbieden dit in .htaccess te zetten; geeft je site een foutmelding, zet dan de regel in commentaar. -Indexes voorkomt dat Apache een automatische bestandslijst toont als een map geen indexbestand heeft, zodat bezoekers niet door je mappen kunnen bladeren.

Een tweede blok versterkt dezelfde gedachte voor de autoindex-module:

<IfModule mod_autoindex.c>
    IndexIgnore *
</IfModule>

3.2 De nosniff-header

Het bestand stelt voor elke respons een beveiligingsheader in:

<IfModule mod_headers.c>
    Header always set X-Content-Type-Options "nosniff"
</IfModule>

Dit vertelt de browser het content-type van een bestand niet te raden ("sniffen"). Zonder dit kan een browser een geuploade afbeelding als JavaScript behandelen en uitvoeren. De <IfModule>-omhulling betekent dat de regel alleen geldt als Apache's mod_headers geladen is, zodat het bestand nooit een fout geeft op een server zonder die module.

3.3 SVG-bestanden vergrendelen

SVG-afbeeldingen zijn XML en kunnen scripts bevatten. Het meegeleverde bestand blokkeert dat wanneer een SVG direct wordt geopend:

<FilesMatch "\.svg$">
  <IfModule mod_headers.c>
    Header always set Content-Security-Policy "script-src 'none'"
  </IfModule>
</FilesMatch>

Dit voorkomt dat inline-JavaScript draait wanneer iemand een SVG-bestand rechtstreeks uit je mediamap opent of het met een <object>-tag insluit. Het is een kleine maar echte verdediging tegen een kwaadaardige upload.

3.4 Het uitgecommentarieerde CORP- en COEP-blok

Net boven de SVG-regel bevat het bestand twee cross-origin-headers die standaard in commentaar staan:

#<IfModule mod_headers.c>
#    Header always set Cross-Origin-Resource-Policy "same-origin"
#    Header always set Cross-Origin-Embedder-Policy "require-corp"
#</IfModule>

Ze staan uit omdat ze sites kunnen breken die terecht afbeeldingen, fonts of embeds van andere domeinen laden. Zet ze pas aan nadat je hebt getest dat elk extern bestand nog laadt. Ze zijn krachtig, maar niet veilig om blind aan te zetten.

Naar boven

4. De regels die exploits blokkeren

Zodra mod_rewrite aanstaat, opent het bestand met een korte lijst regels die de meest voorkomende Joomla-exploitpogingen in de URL-querystring blokkeren. Elke regel bekijkt %{QUERY_STRING} en geeft bij een match een 403 Forbidden terug.

RewriteEngine On

# Blokkeer elk script dat base64_encode-data in de URL probeert te zetten.
RewriteCond %{QUERY_STRING} base64_encode[^(]*\([^)]*\) [OR]
# Blokkeer elk script met een <script>-tag in de URL.
RewriteCond %{QUERY_STRING} (<|%3C)([^s]*s)+cript.*(>|%3E) [NC,OR]
# Blokkeer elk script dat een PHP GLOBALS-variabele via de URL probeert te zetten.
RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR]
# Blokkeer elk script dat een _REQUEST-variabele via de URL probeert te wijzigen.
RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2})
# Geef 403 Forbidden terug en toon de inhoud van de hoofdpagina.
RewriteRule .* index.php [F]

In gewone woorden vangen de vier voorwaarden:

  • base64_encode(...) in de URL, een klassieke manier om code binnen te smokkelen.
  • Een ingespoten <script>-tag, gewoon of URL-gecodeerd als %3C...%3E.
  • Pogingen om de GLOBALS-array van PHP te overschrijven.
  • Pogingen om met de _REQUEST-variabele te knoeien.

De [OR]-flag koppelt de voorwaarden zodat elke match het blok activeert. De laatste [F]-flag geeft 403 Forbidden terug. Deze regels zijn een nuttige basis, geen firewall: houd Joomla bijgewerkt en gebruik een echte Web Application Firewall voor serieuze bescherming. Struikelt een legitiem verzoek er ooit over, dan zeggen de opmerkingen dat je de betreffende regel uitzet met een # aan het begin.

Naar boven

5. Het gedeelte voor eigen redirects

Het bestand reserveert een duidelijk gemarkeerde ruimte voor je eigen redirectregels:

## Begin - Custom redirects
#
# If you need to redirect some pages, or set a canonical non-www to
# www redirect (or vice versa), place that code here. Ensure those
# redirects use the correct RewriteRule syntax and the [R=301,L] flags.
#
## End - Custom redirects

Dit blok is bewust leeg. Het is de juiste plek voor redirects op infrastructuurniveau die voordat PHP start moeten draaien. Een veelvoorkomend voorbeeld forceert een enkele canonieke host:

# Stuur www met een permanente 301 naar het kale domein
RewriteCond %{HTTP_HOST} ^www\.example\.test [NC]
RewriteRule (.*) https://example.test/$1 [R=301,L]

Zet het binnen dit gedeelte, zodat een Joomla-update die de SEF-regels vervangt je aanpassing niet per ongeluk wist. Voor redactionele redirects (een hernoemd artikel dat zijn oude link houdt) gebruik je liever Joomla's eigen Redirects-component, die redacteurvriendelijk is en een verhuizing van de site overleeft. Gebruik .htaccess voor regels op serverniveau, zoals HTTPS forceren of een canonieke host. Zie het Redirects-artikel voor het verschil.

Naar boven

6. RewriteBase en submappen

Net voor het kern-SEF-gedeelte heeft het bestand een uitgecommentarieerde regel:

# RewriteBase /

Die vertelt Apache het URL-pad waar de rewriteregels relatief aan zijn. Voor een site in de hoofdmap heb je hem bijna nooit nodig. Maar als Joomla in een submap staat, bijvoorbeeld https://example.test/blog/, of als de URL van de server niet direct overeenkomt met het fysieke bestandspad, haal je hem uit commentaar en stel je hem in:

RewriteBase /blog

Dit vergeten is een van de meest voorkomende rewriteproblemen bij installaties in een submap. De homepage werkt, maar interne links worden tegen de verkeerde basis opgelost en geven 404's. Stel de basis in op de map, gewoon / voor de hoofdmap.

Naar boven

7. Het kern-SEF-gedeelte

Dit is het hart van het bestand: de regels die mooie URL's daadwerkelijk naar Joomla routeren. Het bestaat uit drie delen.

7.1 De HTTP-Authorization-fix

RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

Sommige PHP-opstellingen (FastCGI) verwijderen de HTTP-header Authorization voordat PHP hem ziet. Joomla's Web Services API gebruikt die header om zijn bearer-token te lezen. Deze regel kopieert de header naar een omgevingsvariabele zodat de API hem toch vindt. Het doel - betekent "herschrijf de URL niet", alleen de variabele instellen.

7.2 De Web Services API routeren

RewriteCond %{REQUEST_URI} ^/api/
RewriteCond %{REQUEST_URI} !^/api/index\.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* api/index.php [L]

Als het pad met /api/ begint, nog niet api/index.php is en niet overeenkomt met een echt bestand of map, herschrijft Apache het naar het API-toegangspunt api/index.php. Zo bereikt een verzoek als /api/index.php/v1/content/articles de headless API van Joomla. De [L]-flag betekent "laatste regel, stop hier".

7.3 De frontend routeren

RewriteCond %{REQUEST_URI} !^/index\.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php [L]

Dit is de regel die mooie URL's laat werken. De twee belangrijke voorwaarden zijn !-f ("geen echt bestand") en !-d ("geen echte map"). Samen zeggen ze:

Wijst het verzoek naar een echt bestand of map, serveer het dan direct. Anders, geef het door aan index.php en laat Joomla de route bepalen.

Daarom bereikt /over-ons Joomla en wordt het een pagina, terwijl /images/logo.png rechtstreeks van schijf wordt geserveerd en PHP nooit raakt.

7.4 Herschrijven versus redirecten

De SEF-regels hierboven zijn rewrites, en een rewrite is niet hetzelfde als een redirect. Het verschil telt zodra je je eigen regels toevoegt.

  • Een rewrite is intern en onzichtbaar. De browser vraagt /over-ons, Apache serveert stilletjes index.php, en de adresbalk verandert niet. Zo bereiken mooie URL's Joomla.
  • Een redirect is extern en zichtbaar. Apache vertelt de browser "ga in plaats daarvan naar deze andere URL", de browser doet een tweede verzoek, en de adresbalk verandert. Zo stuur je een oude URL naar een nieuwe.

Gebruik een rewrite als je wilt dat Joomla een vriendelijke URL afhandelt. Gebruik een redirect als een URL echt is verhuisd, en stuur de juiste statuscode: 301 voor een permanente verhuizing, 302 voor een tijdelijke.

7.5 Veelgebruikte rewrite-flags

De vierkante haken aan het eind van een RewriteRule of RewriteCond zijn flags die veranderen wat de regel doet. Het meegeleverde bestand gebruikt er meerdere; dit zijn de moeite waard om te kennen:

FlagBetekenis
L Laatste regel: stop met verdere rewriteregels in deze ronde.
END Stop alle rewriteverwerking volledig, zonder verdere rondes.
NC No case: hoofdletterongevoelig matchen.
QSA Query String Append: behoud de oorspronkelijke querystring en voeg toe.
R=301 Redirect de browser met een 301 (permanent); gebruik R=302 voor tijdelijk.
F Forbidden: geef 403 terug en stop. Gebruikt door de exploit-blokkerende regels.
G Gone: geef 410 terug, zo vertel je crawlers dat de URL permanent weg is.
OR Bij een RewriteCond combineren met de volgende voorwaarde als "of/of".

De flags lezen is de snelste manier om een onbekende regel te begrijpen. [R=301,L] betekent bijvoorbeeld "redirect permanent en stop", het standaardpaar voor een canonieke of HTTPS-redirect.

Naar boven

8. De terugval zonder rewrite

Wat gebeurt er als mod_rewrite helemaal niet beschikbaar is? Het bestand heeft een kleine terugval die alleen in dat geval draait:

<IfModule !mod_rewrite.c>
    <IfModule mod_alias.c>
        RedirectMatch 302 ^/$ /index.php/
    </IfModule>
</IfModule>

De voorwaarde !mod_rewrite.c betekent "alleen als mod_rewrite niet geladen is". In dat geval wordt een bezoeker van het kale domein met een tijdelijke 302-redirect naar /index.php/ gestuurd, zodat de frontcontroller toch draait en de gegenereerde links (die index.php bevatten) blijven werken. Het is een vangnet, geen functie waarop je leunt: zonder mod_rewrite kun je het mooie URL-formaat niet gebruiken.

Naar boven

9. Compressie en caching

9.1 Vooraf ingepakte bestanden serveren (GZIP en Brotli)

Het laatste blok in het bestand is een prestatietruc. Als er een vooraf ingepakte .gz-kopie van een CSS- of JavaScript-bestand bestaat en de browser gzip accepteert, serveert Apache het kleinere bestand in plaats van het ter plekke in te pakken.

<IfModule mod_headers.c>
    # Serveer een met gzip ingepakt CSS-bestand als het bestaat en de client gzip accepteert.
    RewriteCond "%{HTTP:Accept-encoding}" "gzip"
    RewriteCond "%{REQUEST_FILENAME}\.gz" -s
    RewriteRule "^(.*)\.css" "$1\.css\.gz" [QSA]

    # Hetzelfde voor JavaScript.
    RewriteCond "%{HTTP:Accept-encoding}" "gzip"
    RewriteCond "%{REQUEST_FILENAME}\.gz" -s
    RewriteRule "^(.*)\.js" "$1\.js\.gz" [QSA]

    # Stuur het juiste content-type en voorkom dubbele compressie.
    RewriteRule "\.css\.gz$" "-" [T=text/css,E=no-gzip:1,E=no-brotli:1]
    RewriteRule "\.js\.gz$" "-" [T=text/javascript,E=no-gzip:1,E=no-brotli:1]
</IfModule>

Twee details zijn belangrijk. De flags no-gzip en no-brotli voorkomen dat Apache een al ingepakt bestand een tweede keer inpakt, wat het zou beschadigen. Een FilesMatch-blok stelt vervolgens Content-Encoding: gzip in en voegt Vary: Accept-Encoding toe, zodat proxy's de ingepakte en niet-ingepakte versies apart cachen.

De opmerking in het bestand waarschuwt dat als je host CSS en JS al inpakt, dit blok een fout met dubbele compressie geeft (ERR_CONTENT_DECODING_FAILED in de browserconsole). Zie je dat, zet dan het GZIP-gedeelte in commentaar. Dit blok helpt alleen als je daadwerkelijk .css.gz- en .js.gz-bestanden genereert; zonder die doet het simpelweg niets.

9.2 Browsercaching met mod_expires

Vooraf inpakken maakt de eerste download kleiner; browsercaching voorkomt de download bij het volgende bezoek helemaal. Met mod_expires vertel je browsers hoe lang ze statische bestanden moeten bewaren. Dit zit niet in het meegeleverde bestand, dus voeg je het toe in je eigen blok:

<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 font/woff2            "access plus 1 year"
    ExpiresByType text/css              "access plus 1 month"
    ExpiresByType application/javascript "access plus 1 month"
</IfModule>

Gangbare duren zijn een jaar voor afbeeldingen en fonts, die zelden veranderen, en een maand voor CSS en JavaScript. Lange vervaltijd werkt het best als je bestandsnamen geversioneerd zijn (bijvoorbeeld style.4f2a.css): een gewijzigd bestand krijgt een nieuwe naam, zodat de browser het nieuwe ophaalt in plaats van een verouderde kopie uit de cache te serveren. Joomla's eigen mediaversionering helpt hierbij door een versie-query aan zijn bestanden toe te voegen.

Naar boven

10. De .htaccess op andere webservers

Het .htaccess-bestand is een Apache-functie. Andere servers pakken dezelfde taken anders aan.

ServerLeest .htaccess?Hoe SEF wordt ingesteld
Apache Ja Hernoem htaccess.txt naar .htaccess.
LiteSpeed (commercieel) Ja Leest de Apache-.htaccess rechtstreeks.
OpenLiteSpeed Alleen indien aangezet Zet "Auto Load from .htaccess" aan, of gebruik de eigen rewrite-instellingen.
Nginx Nee Voeg een try_files-regel toe aan de serverconfiguratie.
IIS (Windows) Nee Hernoem web.config.txt naar web.config en installeer URL Rewrite.

De meest voorkomende migratiefout is een Apache-.htaccess in een Nginx-opstelling kopieren en verwachten dat het werkt. Nginx negeert het bestand volledig. Dezelfde routeringslogica bestaat, maar moet in de serverconfiguratie in Nginx' eigen syntax worden geschreven. Zie het Webservers-artikel voor de equivalenten per server.

Naar boven

11. Onder de motorkap (ontwikkelaarsblik)

11.1 Wanneer Apache het bestand leest

Apache controleert bij elk verzoek op .htaccess, en leest niet alleen het bestand in de doelmap maar ook dat in elke bovenliggende map tot aan de documenthoofdmap. Dit is flexibel: je kunt zonder servertoegang regels in elke map zetten. Het is ook de prijs: die bestandslezingen gebeuren bij elk afzonderlijk verzoek.

11.2 AllowOverride bepaalt alles

Of Apache .htaccess uberhaupt leest, hangt af van de AllowOverride-directive in de hoofdconfiguratie:

<Directory /var/www/html>
    AllowOverride All      # lees .htaccess en pas de directives toe
</Directory>

Staat AllowOverride op None, dan negeert Apache het bestand volledig, en doen je rewriteregels niets, hoe correct ze ook zijn. Op een server die je zelf beheert is het snellere patroon om AllowOverride None te zetten en de regels naar de virtuele host te verplaatsen, zodat Apache niet meer naar het bestand zoekt:

# Dezelfde Joomla-regels, maar in de <VirtualHost> in plaats van .htaccess
<Directory /var/www/html>
    Options +FollowSymlinks -Indexes
    AllowOverride None
    # ... plak hier de RewriteRule-blokken ...
</Directory>

Dit haalt de bestandslezingen per verzoek weg en is op schaal meetbaar sneller. Op shared hosting heb je deze keuze zelden, dus daar blijft .htaccess.

11.3 Hoe de server doorgeeft aan Joomla

Na het herschrijven leest Joomla het verzoek uit de $_SERVER-superglobal die Apache vult. Een paar waarden bepalen hoe Joomla URL's bouwt en HTTPS detecteert:

VariabeleWaar Joomla het voor gebruikt
REQUEST_URI Het gevraagde pad, om de pagina te routeren.
HTTP_HOST Het domein, om absolute links te bouwen.
HTTP_AUTHORIZATION Het API-bearer-token (ingesteld door de fix in hoofdstuk 7.1).
HTTPS Om te bepalen of de verbinding veilig is.

11.4 De API-route testen

Omdat het bestand /api/ naar api/index.php routeert en de Authorization-header behoudt, kun je met een enkel verzoek bevestigen dat de Web Services API werkt:

curl -H "X-Joomla-Token: <jouw-token>" \
     https://example.test/api/index.php/v1/content/articles

Een JSON-lijst met artikelen betekent dat zowel de rewrite als de Authorization-fix werken. Een 404 op diezelfde aanroep betekent meestal dat .htaccess niet actief is of dat AllowOverride uitstaat.

11.5 Achter een reverse proxy of CDN

Veel Joomla-sites staan achter een CDN of reverse proxy zoals Cloudflare. Het .htaccess-bestand draait nog steeds op de oorsprongsserver, maar het verzoek is eerst door een andere laag gegaan, en dat verandert twee dingen.

Ten eerste beeindigt de proxy vaak HTTPS en praat daarna met je server over gewoon HTTP. Apache ziet HTTPS als uit, dus een kale "Forceer HTTPS"-rewrite kan eindeloos blijven hangen: de bezoeker komt via HTTPS bij de proxy, je server ziet HTTP en redirect naar HTTPS, de proxy stuurt het weer als HTTP door. De oplossing is de doorgestuurde header te controleren in plaats van HTTPS:

RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

Ten tweede zet je Achter loadbalancer = Ja in Globale configuratie → Server, zodat Joomla het doorgestuurde protocol vertrouwt en https://-links correct bouwt. Zonder dit krijg je mixed-content-waarschuwingen of redirectlussen, zelfs als de .htaccess-regel zelf klopt.

Naar boven

12. Beveiliging voorbij de meegeleverde regels

Het meegeleverde bestand is een basis. Op een server waar je .htaccess vrij kunt bewerken, maken een paar extra regels de site verder veilig. Voeg ze toe in je eigen blok, niet in het Joomla-SEF-gedeelte.

12.1 HTTPS forceren

RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

Ondersteun het met Globale configuratie → Server → Forceer HTTPS = Volledige site, zodat Joomla het ook afdwingt.

12.2 Gevoelige bestanden blokkeren

Sommige bestanden mogen nooit te downloaden zijn. Het belangrijkste is configuration.php, dat je databasewachtwoord bevat. Je kunt directe toegang tot risicovolle paden weigeren:

<FilesMatch "^(configuration\.php|\.env|.*\.(bak|old|log))$">
    Require all denied
</FilesMatch>

# Blokkeer de .git-map
RedirectMatch 404 /\.git

Merk op dat moderne Joomla veel van zijn code al buiten de hoofdmap plaatst en kernmappen beschermt, maar back-upkopieen zoals configuration.php.bak zijn een veelvoorkomend lek dat deze regels dichten.

12.3 Houd headers consistent

Joomla levert een Systeem - HTTP Headers-plugin die de meeste beveiligingsheaders vanuit de backend instelt. Het .htaccess-bestand stelt X-Content-Type-Options: nosniff op de server in. Stellen beide dezelfde header met verschillende waarden in, dan wint degene die als laatste draait, meestal de server of een proxy. Beslis waar elke header thuishoort en houd de twee lagen gelijk.

12.4 Optionele hardening

De regels hieronder zitten niet in het meegeleverde bestand en zijn niet vereist, maar ze dichten veelvoorkomende gaten. Voeg alleen de regels toe die je begrijpt, test na elke, en houd ze in je eigen blok, nooit in het Joomla-SEF-gedeelte.

Voorkom dat PHP draait in uploadmappen. Een aanvaller die een script weet te uploaden, dropt het vaak in een mediamap zoals images/. Plaats een klein tweede .htaccess-bestand in die map om PHP-uitvoering te weigeren. Je beperkt het zo per locatie, omdat de <Directory>-directive niet is toegestaan in een .htaccess-bestand:

# images/.htaccess
<FilesMatch "\.php$">
    Require all denied
</FilesMatch>

Schakel de TRACE-methode uit. De HTTP-methode TRACE is bijna nooit nodig en kan requestheaders terugkaatsen. Weiger hem:

RewriteCond %{REQUEST_METHOD} ^TRACE
RewriteRule .* - [F]

Weiger meer gevoelige bestanden. Breid het blok uit hoofdstuk 12.2 uit met afhankelijkheidsmanifesten en databasedumps, die soms in de hoofdmap achterblijven:

<FilesMatch "^(composer\.(json|lock)|.*\.sql)$">
    Require all denied
</FilesMatch>

Voeg sterkere responsheaders toe. Naast nosniff verbeteren deze headers de beveiliging, maar ze hebben tests nodig, want een strikt beleid kan externe fonts, scripts of embeds blokkeren:

<IfModule mod_headers.c>
    # Forceer HTTPS voor twee jaar, inclusief subdomeinen. Voeg pas toe als HTTPS stabiel is.
    Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"
    # Stuur alleen de origin als referrer naar andere sites.
    Header always set Referrer-Policy "strict-origin-when-cross-origin"
    # Zet browserfuncties uit die de site niet gebruikt.
    Header always set Permissions-Policy "geolocation=(), camera=(), microphone=()"
</IfModule>

Joomla's Systeem - HTTP Headers-plugin kan de meeste hiervan in plaats daarvan vanuit de backend instellen. Kies een plek, de plugin of het bestand, en houd het consistent (zie hoofdstuk 12.3). Voeg HSTS pas toe als elke pagina betrouwbaar over HTTPS laadt, want zodra een browser de header ziet, weigert hij gewoon HTTP voor de hele max-age, ook als je HTTPS later uitzet.

Eigen foutpagina's. Apache's standaard foutmeldingen lijken in niets op je site. Stuur ze via Joomla zodat de bezoeker op een pagina in jouw huisstijl blijft:

ErrorDocument 404 /index.php
ErrorDocument 403 /index.php

Joomla toont dan zijn eigen foutpagina, die je kunt opmaken door templates/jouw_template/error.php te overschrijven. Houd het doel op /index.php zodat het pad blijft werken als de site naar een submap of nieuw domein verhuist.

Naar boven

13. SEO en metadata

Het .htaccess-bestand vormt SEO al voordat een extensie dat doet. Zoekmachines belonen sites die snel, veilig en consistent zijn, en alle drie beginnen hier:

  • Mooie URL's: met het bestand actief en URL-herschrijven aan zijn paden kort en leesbaar, wat zowel gebruikers als crawlers prettiger vinden.
  • Een canonieke host: gebruik het eigen-redirectsblok om HTTPS te forceren en kies www of het kale domein, en redirect daarna de ander met een 301. Dezelfde pagina op twee hosts serveren splitst de rankingsignalen.
  • Juiste statuscodes: een permanente verhuizing moet 301 teruggeven, geen 302. De flags [R=301,L] zijn belangrijk om linkwaarde door te geven.
  • Snelheid: het GZIP-blok en lange cacheheaders verbeteren Core Web Vitals, die Google's ranking voeden.

Niets hiervan heeft een SEO-extensie nodig. Het is configuratie die je eenmaal in het bestand en in de globale configuratie instelt, en die op elke pagina rendeert.

Naar boven

14. Veelgemaakte fouten en valkuilen

14.1 De hernoeming vergeten

Symptoom: de homepage werkt, maar elke andere pagina geeft een 404 nadat je URL-herschrijven aanzet.

Oplossing: hernoem htaccess.txt naar .htaccess. Het bestand moet actief zijn voordat je herschrijven aanzet.

14.2 Het verborgen bestand dat je niet ziet

Symptoom: je hebt het bestand hernoemd, maar je FTP-client of bestandsbeheerder toont het niet, dus je weet niet zeker of het bestaat.

Oplossing: zet "verborgen bestanden tonen" aan in je client (of ls -a op de commandoregel). Bestanden die met een punt beginnen zijn standaard verborgen.

14.3 AllowOverride staat uit

Symptoom: het bestand bestaat, heeft de juiste naam, maar herschrijven doet nog steeds niets.

Oplossing: de server heeft AllowOverride None. Vraag je host om overrides toe te staan, of verplaats de regels naar de virtuele host (zie hoofdstuk 11.2).

14.4 De RewriteBase voor submappen

Symptoom: herschrijven werkt in de hoofdmap maar breekt als Joomla in een submap staat.

Oplossing: haal RewriteBase /submap uit commentaar en stel het in op het installatiepad.

14.5 Dubbele compressie

Symptoom: CSS en JavaScript laden niet en de console toont ERR_CONTENT_DECODING_FAILED.

Oplossing: je host pakt bestanden al in. Zet het GZIP-blok onderaan het bestand in commentaar.

14.6 Aanpassingen weg na een update

Symptoom: je eigen regels verdwijnen na een Joomla-update of een verse upload.

Oplossing: een grote update kan een nieuwe htaccess.txt meeleveren; hernoem je die opnieuw, dan zijn je aanpassingen weg. Houd je regels alleen in het "Custom redirects"-blok, en bewaar een back-up van je actieve .htaccess.

14.7 Jezelf blokkeren met de exploitregels

Symptoom: een legitieme URL met een ongewone querystring geeft 403 Forbidden.

Oplossing: een van de exploit-blokkerende voorwaarden matchte per ongeluk. Zet de betreffende RewriteCond-regel in commentaar met een # aan het begin, zoals de opmerkingen in het bestand aanraden.

Naar boven

15. Beste praktijken

Als je maar een paar dingen uit dit artikel onthoudt, onthoud dan deze:

  • Hernoem htaccess.txt naar .htaccess voordat je URL-herschrijven aanzet.
  • Zet je eigen regels alleen in het "Custom redirects"-blok, zodat updates ze niet wissen.
  • Bewaar een back-up van je actieve .htaccess voordat je het bewerkt.
  • Stel bij een installatie in een submap RewriteBase in op het mappad.
  • Forceer HTTPS en een canonieke host met [R=301,L], en stem het af met Joomla's Forceer HTTPS.
  • Pakt de host bestanden al in, zet dan het GZIP-blok in commentaar.
  • Verplaats op een server die je zelf beheert de regels naar de virtuele host en zet AllowOverride None voor snelheid.
  • Blokkeer back-ups van configuration.php, .env en .git voor het web.
  • Gebruik Joomla's Redirects-component voor redactionele redirects; gebruik .htaccess voor regels op serverniveau.
  • Behandel de exploit-blokkerende regels als een basis, geen vervanging voor updates en een echte firewall.
Naar boven

16. In het kort

ACTIVEREN    Hernoem htaccess.txt → .htaccess
SEF-OPTIES   Systeem → Globale configuratie → Site
             SEF-URL's = Ja, URL-herschrijven gebruiken = Ja
SUBMAP       Haal RewriteBase /submap uit commentaar
FRONTEND     RewriteRule .* index.php [L]  (na !-f en !-d)
API-ROUTE    RewriteRule .* api/index.php [L]  (paden onder /api/)
AUTH-FIX     E=HTTP_AUTHORIZATION  houdt het API-token in leven
EXPLOIT      Blokkeert base64_encode, <script>, GLOBALS, _REQUEST [F]
FLAGS        [L] stop  [F] 403  [R=301,L] redirect  [QSA] query behouden
NOSNIFF      Header always set X-Content-Type-Options "nosniff"
GZIP         Serveert .css.gz / .js.gz indien aanwezig; uit bij dubbele compressie
CACHING      mod_expires: afbeeldingen/fonts 1jr, CSS/JS 1mnd
TERUGVAL     Geen mod_rewrite -> RedirectMatch 302 ^/$ /index.php/
ALLOWOVERRIDE Moet All zijn (of regels in vhost), anders wordt .htaccess genegeerd
CANONIEK     Eigen redirects-blok + [R=301,L]
PROXY        Controleer X-Forwarded-Proto; Achter loadbalancer = Ja
HARDEN       Optioneel: geen PHP in uploads, TRACE uit, HSTS, ErrorDocument
ANDERE SERVERS LiteSpeed leest het; Nginx en IIS niet
Naar boven

17. Samenvatting

Het .htaccess-bestand is het invloedrijkste tekstbestand in een Apache-Joomla-site, en toch verbergt het zich achter een punt en wordt het bewust inactief geleverd. Zodra je weet wat elk blok doet, is het niet langer mysterieus:

  • Activeren: hernoem htaccess.txt naar .htaccess en zet daarna URL-herschrijven aan.
  • Routeren: het SEF-gedeelte stuurt alles wat geen echt bestand of map is naar index.php, en /api/-verzoeken naar api/index.php.
  • Verdediging: het blokkeert veelvoorkomende URL-exploits, stelt de nosniff-header in en vergrendelt SVG-scripts.
  • Snelheid: het kan vooraf ingepakte bestanden serveren en laat je cache- en HTTPS-regels toevoegen.
  • Overdraagbaarheid: het is een Apache-functie; LiteSpeed leest het, maar Nginx en IIS hebben hun eigen configuratie nodig.

Geeft je Joomla-site 404's nadat je mooie URL's aanzet, breekt de CSS na een upload, of verlies je je eigen regels na een update, dan ligt de oorzaak bijna altijd in dit ene bestand. Een zorgvuldige blik op de rewriteregels, de RewriteBase en de AllowOverride-instelling vindt het probleem meestal snel. Het is precies het soort stille fundamentwerk dat een Joomla-site jarenlang snel, veilig en betrouwbaar houdt, en het loont om het een keer goed te doen in plaats van er op elke pagina mee te vechten.

Naar boven
.htaccess in Joomla
Peter Martin
Peter Martin
Joomla Specialist

Peter is Joomla specialist en Linux admin voor snelle, veilige en schaalbare websites.

Veelgestelde vragen

Waarvoor wordt het .htaccess-bestand van Joomla gebruikt?

Het .htaccess-bestand van Joomla regelt het herschrijven van URL’s, omleidingen, beveiligingsinstellingen en caching. Het helpt bij het verbeteren van SEO, de prestaties van de website en de bescherming tegen veelvoorkomende aanvallen.

Hoe schakel ik SEO-vriendelijke URL’s in Joomla in?

Hernoem htaccess.txt naar .htaccess en schakel ‘Zoekmachinevriendelijke URL’s’ in via de algemene configuratie van Joomla. Zorg ervoor dat je server Apache’s mod_rewrite ondersteunt.

Kan ik oude URL’s omleiden met het .htaccess-bestand van Joomla?

Ja. Je kunt permanente (301) omleidingen aanmaken in het .htaccess-bestand om de SEO-waarde te behouden en bezoekers automatisch naar de juiste pagina’s te sturen.

Is het veilig om het .htaccess-bestand van Joomla te bewerken?

Ja, mits je eerst een back-up maakt. Een kleine syntaxfout kan ervoor zorgen dat je website tijdelijk ontoegankelijk wordt, dus test wijzigingen altijd na het opslaan.

Kan ik HTTPS afdwingen via het .htaccess-bestand van Joomla?

Ja. Je kunt al het HTTP-verkeer omleiden naar HTTPS met een eenvoudige regel in het .htaccess-bestand, waardoor veilige verbindingen worden gegarandeerd en de SEO wordt verbeterd.

Wat zijn de handigste beveiligingsinstellingen voor het .htaccess-bestand van Joomla?

Veelgebruikte instellingen zijn onder meer het blokkeren van het doorbladeren van mappen, het voorkomen van toegang tot gevoelige bestanden, het uitschakelen van het uitvoeren van scripts in uploadmappen en het beschermen tegen veelvoorkomende exploits.

Kan ik .htaccess gebruiken op Nginx-, IIS- of LiteSpeed-webservers?

Het .htaccess bestand werkt op Apache-, LiteSpeed- en OpenLiteSpeed-webservers, omdat deze compatibel zijn met het configuratieformaat van Apache. Nginx ondersteunt .htaccess niet, dus de regels moeten worden omgezet naar de Nginx-configuratie. Op IIS wordt vergelijkbare functionaliteit geconfigureerd in het web.config bestand.