404-fouten na het publiceren van je website of app oplossen
Als je app lokaal werkt maar pagina’s na het deployen een 404 geven, is de meest voorkomende oorzaak ontbrekende single-page app (SPA)-routing: de server zoekt naar een bestand genaamd /dashboard dat niet bestaat, omdat die route alleen in JavaScript bestaat. De oplossing is een fallbackregel die index.html serveert voor app-routes. Andere oorzaken zijn bestanden die ontbreken in de buildoutput, hoofdlettergevoelige paden, verschillen in slashes aan het eind, een verkeerd basispad, en API-routes die nooit zijn gedeployd.
Begin met precies noteren welke URL een 404 geeft en hoe je daar kwam. Het patroon wijst direct naar de oorzaak.
Stap 1: zoek het patroon
| Wat je ziet | Meest waarschijnlijke oorzaak | Ga naar |
|---|---|---|
| Startpagina werkt; klikken op links werkt; verversen of een directe link geeft 404 | Geen SPA-fallback | Stap 2 |
| Elke pagina geeft 404, ook de startpagina | Verkeerde map gepubliceerd, of de build is niet gedeployd | Stap 3 |
| Pagina’s laden, maar afbeeldingen, lettertypes of scripts geven 404 | Bestanden ontbreken in de build, of verkeerde paden | Stap 4 |
Werkt met /over/, faalt met /over (of andersom) | Afhandeling van slashes aan het eind | Stap 5 |
/Over faalt maar /over werkt | Hoofdlettergevoelige server | Stap 4 |
Pagina laadt, maar dataverzoeken naar /api/... geven 404 | API niet gedeployd of niet gerouteerd | Stap 6 |
| Oude URL’s van een vorige site geven 404 | Ontbrekende redirects | Stap 7 |
| Alleen op een eigen domein | DNS- of domeininstelling | Stap 8 |
Om de echte statuscode te zien, open je de ontwikkelaarstools (klik met rechts → Inspecteren), ga je naar het tabblad Netwerk, laad je opnieuw en kijk je naar de status van het eerste verzoek.
Stap 2: voeg de SPA-fallback toe
Dit is de klassieke. In een React-, Vue- of Svelte-single-page app heeft de server maar een handvol echte bestanden: index.html en wat JavaScript en CSS. Routes zoals /dashboard of /projects/42 worden afgehandeld door een router in de browser.
- Klikken op een link werkt: de router past de URL aan en tekent de nieuwe pagina zonder de server erbij te halen.
- Verversen of een link direct openen faalt: de browser vraagt de server om
/dashboard, de server heeft dat bestand niet en geeft 404.
De oplossing is een regel die zegt: als het verzoek niet overeenkomt met een echt bestand, serveer index.html met status 200 en laat de router het overnemen. Hoe je dat toevoegt hangt af van de host (controleer de actuele documentatie van je host, want details veranderen):
| Host | Gebruikelijke fallbackregel |
|---|---|
| Netlify | Een _redirects-bestand in de gepubliceerde map met /* /index.html 200 |
| Vercel | Een rewrite in vercel.json van alle paden naar /index.html (frameworkpresets regelen dit vaak al) |
| Cloudflare Pages | Serveert standaard een SPA-achtige fallback als er geen 404.html op het hoogste niveau staat |
| Nginx | try_files $uri $uri/ /index.html; in het location /-blok |
| Apache | Een rewrite-regel in .htaccess die niet-bestandsverzoeken naar index.html stuurt |
| GitHub Pages | Geen server-side rewrites; gangbare omweggen zijn hash-routing of een 404.html dat doorverwijst |
Zorg dat de regel echte bestanden niet opslokt: verzoeken naar /assets/app.js moeten nog steeds het JavaScript-bestand teruggeven. Als ze index.html teruggeven, krijg je een witte pagina met de fout “Failed to load module script”. Zie een witte lege pagina oplossen.
Geef de router ook een catch-all-route, zodat URL’s die op geen enkele pagina passen een vriendelijke “Pagina niet gevonden” tonen in plaats van niets.
Als je serverinstellingen niet kunt wijzigen, dan vermijdt hash-routing (URL’s zoals /#/dashboard) het probleem, omdat het deel na # nooit naar de server wordt gestuurd. Het is een omweg, geen eerste keuze: de URL’s zijn lelijker en minder vriendelijk voor zoekmachines.
Frameworks die pagina’s op de server renderen of op buildtijd genereren (Next.js, Astro en vergelijkbare) hebben meestal echte bestanden of serverroutes voor elke pagina, dus dit specifieke probleem komt daar minder vaak voor. Hun equivalent is een pagina die nooit op buildtijd is gegenereerd.
Stap 3: controleer wat er echt is gedeployd
Als alles 404 geeft, serveert de server waarschijnlijk niet je gebouwde app.
- De juiste map. De host moet de buildoutput publiceren (meestal
distvoor Vite,buildvoor Create React App,outvoor een statische Next.js-export), niet de hoofdmap van het project. - De build is gelukt. Lees het deploylog. Als de build mislukte, heeft de host misschien niets of een oude versie gedeployd.
index.htmlstaat op het hoogste niveau van de gepubliceerde map, niet in een submap.- Het basispad klopt. Als de app wordt geserveerd vanaf
voorbeeld.nl/app/, moet hij met dat basispad zijn gebouwd (Vite’sbase, React Routersbasename), anders missen alle routes en assets.
Stap 4: los ontbrekende bestanden en verkeerde paden op
Als pagina’s laden maar assets 404 geven:
- Hoofdlettergevoeligheid. macOS en Windows behandelen
Logo.pngenlogo.pngmeestal als hetzelfde bestand. De meeste Linux-servers niet. Zorg dat elke verwijzing de exacte bestandsnaam overneemt. - Bestanden buiten de build. In Vite worden bestanden in
public/ongewijzigd gekopieerd en verwijs je ernaar vanaf de root (/logo.png). Bestanden die in code worden geïmporteerd, worden meegebundeld. Een bestand ergens anders in het project wordt mogelijk helemaal niet gedeployd. - Relatieve paden.
images/foto.jpgwordt ten opzichte van de huidige URL opgelost, dus het breekt op/blog/post-1. Gebruik/images/foto.jpg. - Geüploade bestanden opgeslagen op de lokale schijf. Als uploads van gebruikers in de map van de server zijn geschreven, verdwijnen ze bij een nieuwe deployment. Gebruik echte bestandsopslag.
Stap 5: behandel slashes aan het eind consistent
/over en /over/ zijn verschillende URL’s. Hosts verschillen in of ze de slash toevoegen of verwijderen, en een mismatch met je links of je router kan 404’s of redirect-lussen veroorzaken. Kies één stijl, laat je links die gebruiken, en configureer de host om de andere vorm door te verwijzen. Consistentie helpt ook zoekmachines, die anders twee kopieën van elke pagina zien.
Stap 6: los API-routes op die 404 geven
Als de pagina laadt maar het tabblad Netwerk /api/...-verzoeken met 404 toont:
- De backend is niet gedeployd. Een statische host serveert alleen bestanden; een backend moet ergens draaien.
- Het pad wordt in productie anders gerouteerd. In ontwikkeling kan een proxy
/apinaar een aparte server hebben doorgestuurd. In productie heeft de host een gelijkwaardige rewrite nodig, of moet de frontend het echte adres van de API aanroepen. - De SPA-fallback heeft het opgevangen. Een API-verzoek dat
index.htmlteruggeeft met status 200 betekent dat de fallbackregel te breed is. Sluit/api/*ervan uit.
De gepubliceerde app krijgt 404 op de verzoeken naar /api/orders, maar ze werken in de preview. Controleer hoe /api wordt gerouteerd in de preview versus de gepubliceerde app, en zorg dat de gepubliceerde frontend de backend op dezelfde manier bereikt.
Stap 7: stuur oude URL’s door
Als je bent verhuisd van een andere site of de structuur hebt aangepast, geven oude URL’s die mensen en zoekmachines nog gebruiken een 404. Voeg een 301- (permanente) redirect toe van elke oude URL naar de nieuwe plek. Houd een lijst bij en test na de lancering een steekproef. Onze gids over het migreren van een WordPress-site beschrijft hoe je die lijst opstelt.
Stap 8: controleer het domein
Als de app werkt op het adres van de host maar een 404 geeft op je eigen domein, wijst het domein mogelijk naar het verkeerde project, of heeft de host het domein nog niet aan je site gekoppeld. Controleer de DNS-records en de domeininstellingen van de host. Zie hoe je een eigen domein koppelt.
Maak je echte 404-pagina nuttig
Sommige 404’s zijn correct: iemand heeft een URL verkeerd getypt. Maak die pagina dan behulpzaam:
- Een korte boodschap en een link naar de startpagina en belangrijke secties
- Een zoekveld, als de site zoekfunctie heeft
- Dezelfde header en navigatie als de rest van de site
Geef, waar je setup dat toestaat, een echte 404-status terug voor pagina’s die niet bestaan. Een “niet gevonden”-bericht met status 200 is wat zoekmachines een soft 404 noemen; het verspilt hun crawltijd en kan de indexering in de war sturen.
Veelgemaakte fouten
- Alleen testen door te klikken. Test altijd door diepe URL’s in een nieuw tabblad te plakken en te verversen.
- Een fallback die alles opvangt. Assets en API-routes geven
index.htmlterug, wat witte pagina’s en verwarrende API-fouten veroorzaakt. - Afwijkende hoofdletters die alleen op de server breken.
- De bronmap deployen in plaats van de buildoutput.
- URL’s herstructureren zonder redirects. Elke oude link wordt een 404.
404’s in Mythex
In Mythex publiceer je vanuit de werkruimte, en statische frontends worden als statische sites gedeployd. Als een gepubliceerde pagina een 404 geeft, geef de agent dan de exacte URL, of het gebeurt bij verversen of bij klikken, en wat het tabblad Netwerk toont, en vraag hem de routing te controleren. Publiceer opnieuw na de fix, want de live app is een momentopname tot je opnieuw publiceert. Als je het project recent hebt gewijzigd en de live site oud lijkt, publiceer dan opnieuw en ververs hard. Gebruik Repareren met AI in het publicatiedialoogvenster als de build mislukt. Zie Hoe publiceer je en Publicatie-problemen oplossen in de documentatie, en onze gids over het debuggen van een met AI gebouwde app.
404-checklist
- Exact genoteerd welke URL’s een 404 geven, en of bij klikken, verversen of allebei
- SPA-fallback serveert
index.htmlvoor app-routes, met status 200 - Fallback sluit echte bestanden en
/api/*uit - Router heeft een catch-all-route voor “niet gevonden”
- De buildoutputmap is wat wordt gepubliceerd, en de build is gelukt
- Basispad klopt met waar de app wordt geserveerd
- Hoofdlettergebruik van bestandsnamen klopt met elke verwijzing
- Asset-paden beginnen met
/ - Stijl van slashes aan het eind is consistent
- API-routes zijn gedeployd en in productie gerouteerd
- 301-redirects voor oude URL’s
- Diepe links getest door ze in een nieuw tabblad te plakken
Veelgestelde vragen
Waarom krijg ik een 404 als ik een pagina in mijn React-app ververs?
In een single-page app bestaan routes zoals /dashboard alleen in JavaScript. Klikken op een link werkt omdat de router dat in de browser afhandelt, maar bij verversen vraagt de browser de server om een /dashboard-bestand dat niet bestaat. De oplossing is een fallbackregel die index.html serveert voor app-routes.
Hoe voeg ik een SPA-fallback toe op Netlify, Vercel of Nginx?
Op Netlify voeg je een _redirects-bestand toe met /* /index.html 200. Op Vercel voeg je een rewrite toe in vercel.json die alle paden naar /index.html stuurt. Op Nginx gebruik je try_files $uri $uri/ /index.html; in het location-blok. Controleer de documentatie van je host, want regels veranderen.
Waarom geven mijn afbeeldingen of bestanden een 404 na het deployen?
Meestal staat het bestand niet in de buildoutput, komt de hoofdlettergebruik van het pad niet overeen (servers zijn vaak hoofdlettergevoelig waar je laptop dat niet is), of is het pad relatief terwijl het met een schuine streep moet beginnen.
Moet een ontbrekende pagina een echte 404-status teruggeven?
Ja. Toon een behulpzame pagina voor niet-gevonden, maar met een 404-status waar je setup dat toestaat. Zoekmachines zien een ‘niet gevonden’-bericht met status 200 als een soft 404, wat crawltijd verspilt en de indexering in de war kan sturen.