Skip to content
maksim zaytsev
Zápisky

15. ledna 2024 · 8 min

Poznámky k app routeru v Next.js 15

Přenesl jsem middle-size dashboard aplikaci z pages routeru na app router v Next.js 15 — trvalo to zhruba tři týdny, souběžně s běžnou prací na featurech. Tohle jsou poznámky, které bych si přál mít po ruce, než jsem začal.

Co se změnilo

Největší posun je v hlavě: routing je teď strom složek a každá složka může mít vlastní layout, loading stav a error boundary. getServerSideProps a getStaticProps zmizely — načítání dat probíhá přímo v server komponentách jako obyčejné async funkce. Route handlery nahradily API routes: jeden route.ts na segment místo jednoho souboru se switch na req.method.

Změnilo se i kešování. Fetche se ve výchozím stavu kešují, pokud to explicitně nevypneš — což je pohodlné, dokud nezapomeneš, že se to děje, a nestrávíš dvacet minut zíráním na zastaralá data. Teď u nových fetchů defaultně nastavuju { cache: 'no-store' } a kešování zapínám vědomě, ne naopak.

async function getInvoices(orgId: string) {
  const res = await fetch(`${API}/invoices?org=${orgId}`, {
    cache: 'no-store',
  });
  if (!res.ok) throw new Error('Nepodařilo se načíst faktury');
  return res.json();
}

Co mě překvapilo

Skládání server komponent s klientskými je hladší, než jsem čekal — data načtená na serveru posíláš dolů jako props a jen interaktivní list stromu se stává 'use client'. Míň příjemně mě překvapilo, jak snadno zbloudilá direktiva 'use client' na začátku sdíleného utility souboru stáhne půlku stromu do klientského bundlu. Tři takové případy jsem našel víceméně náhodou při pohledu do bundle analyzeru.

useSearchParams taky vynutí, aby se celá obklopující komponenta renderovala jen na klientovi — to je snadné přehlédnout, když refaktoruješ stránku, která dřív zadarmo četla router.query.

Co bych udělal jinak

Hranici mezi serverem a klientem bych nakreslil na papír dřív, než začnu psát kód, ne až potom. Taky bych zavedl route groups od prvního dne místo dodatečného zavádění — přeorganizovat složky ve chvíli, kdy jsou routy už ostré produkční URL, je nervóznější, než musí být. A soubory loading.tsx bych psal hned na začátku, ne jako dodatek — právě ony mění pocit z celé migrace, protože aplikace přestane vypadat rozbitá, zatímco se data streamují.

Shrnutí: dobrá změna, ale app router odměňuje ty, kdo si tvar rozdělení server/klient rozmyslí předem, ne uprostřed migrace.