Next.js i18n op schaal: 30 talen, 91K pagina's, Vercel ISR
Vorig jaar leverden we een Next.js-project op dat me nog steeds een beetje zenuwachtig maakt als ik eraan denk. Dertig talen. Meer dan 91.000 statisch gegenereerde pagina's. Vercel ISR dat alles vers houdt. Het soort project waar één verkeerde architectuurkeuze betekent dat je naar 4 uur durende builds staart, rekeningen van $800/maand voor hosting, of – in het ergste geval – een website die gewoon niet werkt in het Koreaans.
Dit is het verhaal van hoe we het goed hebben gedaan (en de delen waar we in eerste instantie niet goed zaten). Als je een grootschalige internationaalvergrendelde Next.js-toepassing bouwt en je afvraagt of ISR dit in productie echt aankan, is dit artikel voor jou.

Inhoudsopgave
- Het probleem: waarom 91K pagina's anders is
- Architectuurkeuzes die we vroeg hebben gemaakt
- Next.js i18n instellen voor 30 locales
- De ISR-strategie die echt werkte
- Content pipeline en headless CMS-integratie
- Prestatieresultaten en Core Web Vitals
- Kostenanalyse op Vercel
- Fouten die we maakten en hoe we ze hebben opgelost
- Wanneer je deze stack wel of niet moet gebruiken
- Veelgestelde vragen
Het probleem: waarom 91K pagina's anders is
Laten we het toneel instellen. De klant was een onderneming in de e-commerce die uitbreidde naar 30 markten. Elke markt had nodig:
- Gelokaliseerde productpagina's (~2.800 producten × 30 locales = 84.000 pagina's)
- Categoriepagina's (~120 categorieën × 30 locales = 3.600 pagina's)
- CMS-gestuurde marketingpagina's (~120 × 30 = 3.600 pagina's)
- Totaal: ongeveer 91.200 unieke URLs
Met plain getStaticPaths en volledige statische generatie zou de initiële build ergens tussen 3 en 5 uur duren. Dat is geen typo. We hebben vroege prototypes benchmarkt en zagen het getal stijgen. Bij elke deploy zou downtime-risico voor uren bedragen, en het content-team wilde meerdere keren per dag updates publiceren.
SSR was geen optie. De verkeerspatronen van de klant toonden massale pieken tijdens verkoopgebeurtenissen – we hebben het over 50K gelijktijdige gebruikers. Het server-renderen van 91K mogelijke paginavarianten onder die belasting zou serieuze rekenkracht vereisen en latentie introduceren die conversietarieven vernietigt.
ISR was het antwoord. Maar ISR op deze schaal heeft zijn eigen set van uitdagingen die de Next.js-documentatie je niet echt voorbereidt.
Architectuurkeuzes die we vroeg hebben gemaakt
Voordat we een enkele regel i18n-code schreven, hebben we drie architectuurkeuzes gemaakt die ons later maanden ellende hebben bespaard.
Keuze 1: Subpath-routering, geen domeinen
Next.js ondersteunt twee i18n-strategieën: subpath-routering (/fr/products/...) en domeinroutering (fr.example.com). We kozen voor subpath-routering. Dit is waarom:
| Factor | Subpath-routering | Domeinroutering |
|---|---|---|
| DNS/SSL-complexiteit | Eén domein | 30 domeinen/subdomeinen om te beheren |
| Vercel-implementatie | Eén project | Eén project (maar domeinconfiguratieoverhead) |
| SEO-linkequity | Geconsolideerd op één domein | Verdeeld over domeinen |
| CDN-cacheefficiëntie | Beter (gedeelde edge-cache) | Gefragmenteerd |
| Analyticconfiguratie | Eenvoudiger | 30 eigenschappen of complexe filtering |
Voor de meeste projecten met minder dan 50 locales is subpath-routering de beste keuze. Domeinroutering heeft zin wanneer je landenspecifieke TLD's nodig hebt om juridische redenen of wanneer je markten fundamenteel verschillende content-architecturen hebben.
Keuze 2: next-intl boven next-i18next
We hebben beide bibliotheken uitgebreid geëvalueerd. In 2025 is next-intl (v4.x) de sterkere keuze voor App Router-projecten geworden, hoewel we Pages Router gebruikten voor deze build. Zelfs met Pages Router gaf next-intl ons:
- Betere TypeScript-ondersteuning met type-veilige berichtsleutels
- Kleinere client-bundel (ongeveer 2,1KB gzipped versus ~5KB voor next-i18next)
- Native ondersteuning voor ICU-berichtindeling (meervouden, geslacht, getalopmaak)
- Eenvoudigere configuratie voor ISR-pagina's
Keuze 3: Gedeeltelijke statische generatie + ISR
Dit was de grote. In plaats van te proberen alle 91K pagina's tijdens het bouwen statisch te genereren, hebben we alleen de hoogste-traffic-pagina's (ongeveer 8.000) vooraf gebouwd en ISR de rest laten afhandelen op aanvraag.
// pages/[locale]/products/[slug].tsx
export async function getStaticPaths() {
// Genereer slechts voorgaande top 100 producten × top 5 locales
const topProducts = await getTopProducts(100);
const primaryLocales = ['en', 'de', 'fr', 'es', 'ja'];
const paths = topProducts.flatMap(product =>
primaryLocales.map(locale => ({
params: { slug: product.slug, locale },
}))
);
return {
paths,
fallback: 'blocking', // ISR handelt alles anders af
};
}
Dit bracht onze bouwijd van 3+ uur terug naar ongeveer 12 minuten. De resterende 83.000 pagina's worden gegenereerd op het eerste verzoek en in de cache opgeslagen aan de rand.

Next.js i18n instellen voor 30 locales
De ingebouwde Next.js i18n-configuratie in next.config.js handelt localebepaling en routering af. Dit is wat onze configuratie eruit zag (afgekort):
// next.config.js
const nextConfig = {
i18n: {
locales: [
'en', 'de', 'fr', 'es', 'it', 'pt', 'nl', 'pl', 'cs', 'da',
'sv', 'fi', 'nb', 'hu', 'ro', 'bg', 'hr', 'sk', 'sl', 'el',
'tr', 'ja', 'ko', 'zh-CN', 'zh-TW', 'th', 'vi', 'id', 'ms', 'ar'
],
defaultLocale: 'en',
localeDetection: false, // We handelen dit zelf af
},
};
Een paar dingen om hier op te merken. We hebben localeDetection uitgeschakeld omdat de ingebouwde detectie (gebaseerd op Accept-Language-kopteksten) problemen veroorzaakte met ISR-caching. Wanneer Vercel's CDN een pagina in de cache opslaat, moet de locale deterministisch van de URL zijn, niet van kopteksten. Het laten automatisch omleiden van Next.js op basis van browserretaal betekende cache-misses en inconsistent gedrag.
In plaats daarvan hebben we een custom localebepaling-middleware gebouwd die alleen op het rootpad draait:
// middleware.ts
import { NextRequest, NextResponse } from 'next/server';
const SUPPORTED_LOCALES = ['en', 'de', 'fr', /* ... */];
const DEFAULT_LOCALE = 'en';
export function middleware(request: NextRequest) {
const { pathname } = request.nextUrl;
// Alleen op rootpad omleiden
if (pathname === '/') {
const acceptLanguage = request.headers.get('accept-language') || '';
const preferred = acceptLanguage.split(',')[0]?.split('-')[0] || DEFAULT_LOCALE;
const locale = SUPPORTED_LOCALES.includes(preferred) ? preferred : DEFAULT_LOCALE;
return NextResponse.redirect(new URL(`/${locale}`, request.url));
}
return NextResponse.next();
}
export const config = {
matcher: ['/'],
};
Vertaalbestand-structuur
Met 30 talen wordt beheer van vertaalbesten een echt probleem. We hebben vertalingen per naamruimte ingedeeld:
messages/
├── en/
│ ├── common.json
│ ├── product.json
│ ├── checkout.json
│ └── marketing.json
├── de/
│ ├── common.json
│ ├── product.json
│ └── ...
└── ar/
└── ...
Totale vertaallading over alle talen was ongeveer 4,2MB. Maar omdat we vertalingen per pagina laden met getStaticProps, laadt elke individuele pagina slechts 15-40KB vertaalgegevens voor zijn locale en naamruimte. Dit is kritiek – je wilt niet alle 30 locales naar de client sturen.
export async function getStaticProps({ locale }: GetStaticPropsContext) {
return {
props: {
messages: {
...(await import(`../../messages/${locale}/common.json`)).default,
...(await import(`../../messages/${locale}/product.json`)).default,
},
},
revalidate: 300, // ISR: opnieuw valideren elke 5 minuten
};
}
RTL-ondersteuning voor Arabisch
Arabisch was de enige RTL-taal in onze set. We hebben dit afgehandeld met een eenvoudige layoutwrapper:
const direction = locale === 'ar' ? 'rtl' : 'ltr';
return (
<html lang={locale} dir={direction}>
<body className={direction === 'rtl' ? 'font-arabic' : 'font-sans'}>
{children}
</body>
</html>
);
Plus Tailwind's rtl:-variant voor afstands- en layoutaanpassingen. Dit werkte verrassend goed – misschien 5% van onze CSS had RTL-specifieke overschrijvingen nodig.
De ISR-strategie die echt werkte
ISR (Incremental Static Regeneration) is de held van dit verhaal, maar om het goed op schaal te gebruiken, moet je begrijpen hoe Vercel's infrastructuur echt werkt.
Opnieuw validatietiming
We gebruikten verschillende opnieuw validatieperioden afhankelijk van inhoudstype:
| Paginatype | Opnieuw validatieperiode | Redenering |
|---|---|---|
| Productpagina's | 300s (5 min) | Prijzen/voorraad wijzigen vaak |
| Categoriepagina's | 900s (15 min) | Productlijsten worden minder vaak bijgewerkt |
| Marketing/CMS-pagina's | 3600s (1 uur) | Inhoudswijzigingen zijn gepland |
| Homepage per locale | 600s (10 min) | Balans tussen versheid en caching |
Opnieuw validatie op aanvraag
Voor kritieke updates (prijswijzigingen, voorraadtekorten) hebben we opnieuw validatie op aanvraag ingesteld via webhook van onze headless CMS:
// pages/api/revalidate.ts
import type { NextApiRequest, NextApiResponse } from 'next';
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const { secret, slug, locales } = req.body;
if (secret !== process.env.REVALIDATION_SECRET) {
return res.status(401).json({ message: 'Ongeldig geheim' });
}
try {
const targetLocales = locales || ['en']; // Standaard naar Engels als niet opgegeven
const revalidations = targetLocales.map((locale: string) =>
res.revalidate(`/${locale}/products/${slug}`)
);
await Promise.all(revalidations);
return res.json({ revalidated: true, paths: targetLocales.length });
} catch (err) {
return res.status(500).json({ message: 'Fout bij opnieuw valideren' });
}
}
Een voetangel: wanneer je een product opnieuw valideert dat in 30 locales bestaat, maak je 30 opnieuw validatieoproepen. Voor een bulkupdate van 100 producten zijn dat 3.000 opnieuw validatieaanvragen. We moesten snelheidsbeperking toevoegen en dit in de wachtrij plaatsen via een serverloze functie om Vercel's API-limieten niet te overschrijden.
Het Stale-While-Revalidate-patroon
De schoonheid van ISR is dat het verouderde inhoud serveert terwijl het op de achtergrond opnieuw genereert. Voor dit project betekende dit dat gebruikers altijd een snel antwoord kregen (HTML in cache van Vercel's edge), zelfs als de gegevens tot 5 minuten oud waren. Voor een e-commerce-site was dit een aanvaardbare afweging – de winkelwagen- en checkoutstroom raakten altijd live API's voor real-time voorraad/prijzen.
Content pipeline en headless CMS-integratie
De inhoud bevond zich in een headless CMS (Contentful, in dit geval, hoewel we vergelijkbare setupsen hebben gedaan met Sanity en Storyblok voor andere klanten – zie onze headless CMS-ontwikkelingsdiensten voor meer hierover).
Het lokalisatiemodel van Contentful werkte goed voor 30 locales. Elk invoeritem heeft localespecifieke veldwaarden, en hun API ondersteunt het opvragen per locale. Maar er is een prestatieoverweging: het ophalen van een product met alle 30 locales-gegevens is aanzienlijk groter dan het ophalen van één locale.
We hebben altijd voor een enkele locale in getStaticProps opgezocht:
const product = await contentfulClient.getEntry(productId, {
locale: mapToContentfulLocale(locale), // 'en-US', 'de-DE', enz.
include: 2, // Los 2 niveaus van gekoppelde invoeren op
});
Dit hield API-reactietijden onder 200ms, zelfs voor complexe productinvoeren met meerdere verwijzingen.
Vertaalbeheer
Voor UI-vertalingen (knoppen, labels, foutmeldingen) hebben we Crowdin gebruikt geïntegreerd met onze Git-repo. De workflow:
- Ontwikkelaars voegen nieuwe Engelse tekenreeksen toe aan
messages/en/*.json - Crowdin synchroniseert en brengt vertalers op de hoogte
- Vertalingen komen terug als PR's
- CI valideert JSON-structuur en volledigheid
- Ontbrekende vertalingen vallen terug op Engels
De terugvalstrategie is kritiek. Je wilt nooit een productiepagina zien met vertaalslujtels zoals product.add_to_cart. Onze terugvalketen was: aangevraagde locale → taalgezin (bijv. pt-BR → pt) → Engels.
Prestatieresultaten en Core Web Vitals
Na lancering hebben we het volgende gemeten over alle 30 locales:
| Metriek | Doel | Werkelijk (P75) | Opmerkingen |
|---|---|---|---|
| LCP | < 2,5s | 1,8s | ISR-cache hit |
| FID | < 100ms | 45ms | Minimale client-side JavaScript |
| CLS | < 0,1 | 0,03 | Font-laadstrategie hielp |
| TTFB | < 800ms | 120ms | Vercel edge, pagina's in cache |
| TTFB (cache miss) | < 2s | 1,4s | ISR genereert op eerste aanvraag |
| Bouwijd | < 20min | 11min 40s | Slechts 8K pagina's vooraf gegenereerd |
De TTFB-nummers zijn de ster hier. 120ms voor pagina's in cache betekent dat gebruikers in Tokio, São Paulo en Frankfurt allemaal snelle reacties krijgen van nabijgelegen edge-nodes. De 1,4s voor cache-misses is de ISR-generatietijd – aanvaardbaar omdat het slechts eenmaal per pagina per opnieuw validatieperiode gebeurt.
Fontladen voor 30 talen
Eén prestatieuitdaging specifiek voor meertalige sites: lettertypen. Je kunt niet één lettertypefamilie voor 30 talen gebruiken. We hadden nodig:
- Latijns/Cyrillisch: Inter (meeste Europese talen)
- Arabisch: Noto Sans Arabic
- CJK: Noto Sans JP/KR/SC/TC
- Thais: Noto Sans Thai
Het gebruik van next/font met per-locale fontladen voorkwam onnodige fontdownloads. Een gebruiker die de Japanse site bezoekt laadt alleen Noto Sans JP, niet de Arabische of Thaise lettertypen.
Kostenanalyse op Vercel
Laten we het over geld praten, omdat dit waar grote ISR-schaal interessant wordt. Hier is onze maandelijkse Vercel-factuuropsplitsing in 2025:
| Regelitem | Maandelijkse kosten | Opmerkingen |
|---|---|---|
| Vercel Pro-plan | $20/zetel × 4 | Basisteamplan |
| Bandbreedte (8TB/mo) | ~$320 | $40/TB na eerste 1TB |
| Serverloze functie-uitvoeringen | ~$180 | ISR-regeneratie + API-routes |
| Edge Middleware-uitvoeringen | ~$45 | Localebepaling |
| ISR-writes | ~$90 | Cache-schrijfbewerkingen |
| Totaal | ~$715/mo |
Voor een site met 2M+ paginaweergaven/maand over 30 locales is $715 extreem redelijk. Het alternatief – het uitvoeren van SSR op speciale infrastructuur – zou $2.000-4.000/maand hebben gekost voor gelijkwaardige prestaties en betrouwbaarheid.
Iets om in de gaten te houden: ISR-cachecorrigeeringskosten kunnen pieken als je massa opnieuw validatie triggert. We hadden een incident waarbij een CMS-bulkpublicatie opnieuw validatie voor 15.000 pagina's tegelijk triggerde. Dat ene evenement kostte ongeveer $40 in extra functie-uitvoeringen. We plaatsen opnieuw validatieoproepen nu in een wachtrij met een vertraging van 100ms ertussen.
Fouten die we maakten en hoe we ze hebben opgelost
Ik zou liegen als ik zei dat dit vanaf dag één soepel verliep. Hier zijn de grootste fouten:
Fout 1: Het genereren van alle locales tijdens het bouwen
Onze eerste benadering probeerde elke pagina in elke locale vooraf te genereren. De build liep 3 uur en 47 minuten. Toen mislukte het omdat Vercel's bouwtime-out (op Pro) 45 minuten is. Zelfs na het verplaatsen naar een aangepaste bouwserver was het implementatieproces ellendig.
Fix: Gedeeltelijke voorafgeneering met fallback: 'blocking'. Bouw alleen de pagina's die het meest belangrijk zijn, laat ISR de lange staart afhandelen.
Fout 2: `fallback` niet correct instellen
We gebruikten aanvankelijk fallback: true in plaats van fallback: 'blocking'. Het verschil is belangrijk: true serveert een skelet/laadstatus op eerste aanvraag, terwijl blocking wacht tot de pagina genereert. Met true kregen we hydratiefouten omdat onze productcomponenten gegevens verwachtten die nog niet aanwezig waren tijdens de fallback-render.
Fix: Overschakelen naar fallback: 'blocking'. De eerste bezoeker aan een pagina zonder cache wacht 1-2 seconden, maar iedereen daarna krijgt de versie in cache direct.
Fout 3: SEO-hreflang-tags waren fout
Dit is een gemakkelijke om te missen. Google heeft hreflang-tags nodig om de relatie tussen gelokaliseerde pagina's te begrijpen. Onze initiële implementatie miste het x-default-tag en had inconsistenties tussen de <link>-tags en de XML-sitemap.
// Juiste hreflang-implementatie
<Head>
{locales.map(loc => (
<link
key={loc}
rel="alternate"
hrefLang={loc}
href={`https://example.com/${loc}${path}`}
/>
))}
<link rel="alternate" hrefLang="x-default" href={`https://example.com/en${path}`} />
</Head>
Fout 4: Sitemap-generering
Met 91K URL's werkt een enkel XML-sitemapbestand niet (Google's limiet is 50.000 URL's per sitemap). We hadden een sitemap-index met meerdere onderliggende sitemaps nodig, verdeeld per locale:
<!-- sitemap-index.xml -->
<sitemapindex>
<sitemap><loc>https://example.com/sitemaps/en.xml</loc></sitemap>
<sitemap><loc>https://example.com/sitemaps/de.xml</loc></sitemap>
<!-- ... 28 meer -->
</sitemapindex>
We hebben deze gegenereerd met next-sitemap met aangepaste configuratie, en ze worden bij elke build opnieuw gegenereerd.
Wanneer je deze stack wel of niet moet gebruiken
Deze architectuur – Next.js + i18n + ISR op Vercel – is krachtig, maar het is niet de juiste keuze voor alles.
Gebruik dit wanneer:
- Je hebt 10+ locales met duizenden pagina's
- Content-updates zijn frequent maar niet real-time
- Prestaties en Core Web Vitals zijn belangrijk voor SEO
- Je team kent React/Next.js goed
Overweeg alternatieven wanneer:
- Je hebt minder dan 5 locales en minder dan 1.000 pagina's (plain SSG is misschien eenvoudiger)
- Inhoud is echt real-time (beurs, live scores) – gebruik SSR of client-side fetching
- Je bent beperkt in budget voor hosting – overweeg Astro voor zuiver statische meertalige sites met een fractie van de kosten
- Je team is klein en heeft geen React-interactiviteit nodig – een statische sitegenerator met i18n kan minder onderhoud vereisen
Voor teams die een project zoals dit overwegen, hebben we verschillende ondernemingsklanten geholpen architectureren en bouwen grote Next.js-toepassingen. De architectuurkeuzes in de eerste twee weken bepalen of het project slaagt of een nachtmerrie van onderhoud wordt. Als je je specifieke situatie wilt bespreken, neem contact op.
Veelgestelde vragen
Hoe werkt Next.js i18n-routering met ISR?
Next.js i18n-routering voegt locale-voorvoegsels toe aan URL's (zoals /fr/products/shoes). In combinatie met ISR wordt elke locale + pagina-combinatie onafhankelijk in de cache opgeslagen op Vercel's edge. Dus /en/products/shoes en /fr/products/shoes zijn afzonderlijke cacheinvoeren, elk met hun eigen opnieuw validatietimer. De getStaticProps-functie ontvangt de locale in zijn context, en je haalt de geschikte vertalingen en gelokaliseerde inhoud daar op.
Wat is het maximale aantal pagina's dat Next.js ISR op Vercel kan afhandelen? Er is geen harde technische limiet voor het aantal ISR-pagina's dat Vercel kan serveren. We hebben 91K+ pagina's succesvol uitvoerd, en ik heb gehoord van projecten met 500K+ pagina's. De praktische limieten zijn bouwijd (voor vooraf gegenereerde pagina's), opnieuw validatiedoorvoer en kosten. Vercel's edge-cache is ontworpen voor deze schaal – het is in wezen een CDN met intelligente invalidatie.
Beïnvloedt ISR SEO voor meertalige sites?
Nee, ISR-pagina's zijn volledige weergegeven HTML wanneer ze uit de cache worden bediend, wat is wat zoekmachine-crawlers zien. De belangrijkste SEO-overwegingen zijn juiste hreflang-tags, een goed gestructureerde sitemap-index met per-locale sitemaps, en ervoor zorgen dat je fallback: 'blocking'-instelling voorkomt dat crawlers onvolledige pagina's zien. Google heeft bevestigd dat ISR/pagina's in cache op dezelfde manier worden behandeld als traditionele statische HTML.
Hoe handelt je vertaalen updates af zonder opnieuw in te stellen? Voor CMS-beheerde inhoud (productbeschrijvingen, marketingtekst) worden vertalingen automatisch bijgewerkt via ISR-opnieuw validatie – hetzij op de timer of via opnieuw validatie-webhooks op aanvraag. Voor UI-stringvertalingen (knoplabels, formuliervalidatieberichten) zijn deze gebundeld tijdens de build, dus ze vereisen opnieuw instellen. We houden deze intentioneel gescheiden: inhoudswijzigingen moeten nooit opnieuw instellen vereisen, maar UI-stringwijzigingen gaan door codebeoordeling.
Wat is het kostenverschil tussen ISR en SSR voor meertalige sites op Vercel? SSR voert een serverloze functie uit bij elk enkel verzoek. Bij 2M paginaweergaven/maand zijn dat 2M functie-invocaties tegen ongeveer $0,40 per miljoen na de gratis laag – ongeveer $800/maand in functiekosten alleen, plus aanzienlijk hogere bandbreedte omdat er minder caching is. Onze ISR-setup kostte ongeveer $715/maand totaal, terwijl gelijkwaardige SSR $2.500-3.500/maand zou hebben gekost.
Hoe handelt je verschillende datum-, getal- en valutaformaten over 30 locales af?
We gebruiken de ingebouwde Intl-API van de browser via next-intl's opmaakprogramma's. Dit handelt datumopmaak (Intl.DateTimeFormat), getalopmaak (Intl.NumberFormat) en valutaweergave correct voor elke locale af. Met de ICU-berichtindeling kun je deze opmaakprogramma's rechtstreeks in vertaaltekenreeksen insluiten: "price": "From {amount, number, ::currency/EUR}". Dit werkt server-side tijdens ISR-generatie en client-side voor dynamische waarden.
Moet ik App Router of Pages Router gebruiken voor grote-schaal i18n?
Vanaf Next.js 15 (midden-2025) is het i18n-verhaal van App Router volwassen geworden, en next-intl v4 heeft uitstekende App Router-ondersteuning. Voor nieuwe projecten zou ik App Router aanbevelen. Het biedt betere streaming, React Server Components (die client-side JavaScript verminderen) en meer granulaire cachebesturingselementen. Ons project gebruikte Pages Router omdat het in 2024 werd gestart toen App Router i18n minder stabiel was, maar een greenfield-project vandaag zou App Router moeten gebruiken.
Wat gebeurt er als ISR-opnieuw validatie mislukt? Zien gebruikers een foutpagina?
Nee, en dit is een van ISR's beste functies. Als opnieuw validatie mislukt (misschien is de CMS-API niet beschikbaar, of is er een code-fout in getStaticProps), blijft Vercel de laatst succesvol gegenereerde versie van de pagina serveren. Gebruikers zien nooit een fout – ze zien gewoon iets oudere inhoud. De mislukte opnieuw validatie wordt geregistreerd, en de volgende opnieuw validatiepoging probeert opnieuw. Dit maakt ISR ongelooflijk veerkrachtig vergeleken met SSR, waarbij een API-storing onmiddellijk een gebruikersgerichte storing wordt.