# Što ćete naučiti#
Ovaj vodič daje korak-po-korak plan migracije na Next.js App Router s Pages Routera, uz praktičan kontrolni popis koji možete proći zajedno s timom.
Pokrit ćete routing, dohvat podataka, SEO metadatu, deployment razmatranja i rješavanje čestih produkcijskih problema poput iznenađenja s keširanjem, redirecta i dinamičkih ruta.
Ako vam treba osvježenje osnova, krenite s Uvod u Next.js. Ako je vaš tim nov u mentalnom modelu “server-first” UI-ja, pročitajte Vodič za React Server Components. Za SEO kontekst pogledajte Zašto Next.js za SEO.
# Kada migrirati, a kada ostati#
App Router je dugoročni smjer Next.js-a, ali “najnovije” nije uvijek “najbolje za sljedeći sprint”. Koristite ovu matricu odluke kako biste izbjegli polovične migracije koje zapnu na pola puta.
| Signal | Migrirajte na App Router sada | Za sada ostanite na Pages Routeru |
|---|---|---|
| Product roadmap | U sljedeća 3 do 6 mjeseci dodajete nove sekcije, dashboarde ili novu marketing stranicu | Planirano je samo manje održavanje i ispravci bugova |
| Ciljevi performansi | Treba vam brži TTFB, streaming, bolja kontrola cachea ili smanjenje client JS-a | Trenutne performanse su već prihvatljive i stabilne |
| Dohvat podataka | Želite server-first fetching, parallel routes i granularne cache politike | Jako se oslanjate na obrasce getServerSideProps koji su čvrsto vezani uz page props |
| Spremnost tima | Možete uložiti u smjernice za code review i testiranje granica server/client | Tim nije upoznat s RSC-om i nema vremena za onboarding |
| Infrastruktura | Deployate na Vercel ili Node runtime koji podržava potrebne značajke | Ovisite o custom server postavci ili edge ograničenjima koja kompliciraju paritet |
| Tolerancija na rizik | Možete isporučivati inkrementalno iza feature flagova i mjeriti | Imate compliance ili release ograničenja zbog kojih su regresije skupe |
🎯 Ključna poruka: Migrirajte kada imate poslovni razlog i kapacitet za testiranje i praćenje. App Router je moćan, ali “ship and pray” migracije kažnjava iznenađenjima oko keširanja i renderiranja.
# Plan migracije korak po korak (praktičan kontrolni popis)#
Korak 0: Baseline i inventura#
Prije nego dotaknete kod, zabilježite baseline kako biste mogli dokazati da je migracija pomogla.
Kontrolni popis
- Zabilježite trenutne Lighthouse rezultate za ključne predloške: homepage, listing, detail page, checkout ili signup.
- Ako je moguće, pratite Core Web Vitals kod stvarnih korisnika. Google navodi da CWV korelira s bounceom i konverzijom, a poboljšanja LCP-a su često mjerljiva nakon smanjenja client JS-a.
- Izvezite popis ruta i mapirajte ovisnosti:
- Statične rute
- Dinamičke rute i catch-all
- Redirecti i rewritovi
- API rute
- Identificirajte stranice koje koriste:
getInitialPropsgetServerSidePropsgetStaticPropsi ISRnext/headnext/router
- Odlučite hoćete li pristup “nove rute prvo u App Routeru” ili strogu migraciju stranicu-po-stranicu.
Isporuka: migracijska tablica koja navodi svaku rutu, njezinu data strategiju i SEO zahtjeve.
Korak 1: Sigurno nadogradite Next.js#
Nemojte istovremeno mijenjati router i raditi nadogradnju major verzije ako kasnite. Prvo nadogradite na modernu stabilnu verziju Next.js-a dok ste još na Pages Routeru, pa tek onda migrirajte.
Kontrolni popis
- Ažurirajte Next.js i React na podržane verzije za App Router.
- Uklonite deprecated konfiguraciju i provjerite build upozorenja.
- Potvrdite da su CI buildovi i produkcijski deploy stabilni.
- Provjerite da možete pokrenuti
next buildbez grešaka koje se pojavljuju samo u runtimeu.
⚠️ Upozorenje: Ako i dalje koristite
getInitialPropsu_app, vjerojatno ćete prenijeti legacy ograničenja u migraciju. Planirajte ga zamijeniti rano ili ga izolirajte na preostali Pages Router dio.
Korak 2: Napravite App Router “ljusku”#
Dodajte app direktorij uz zadržavanje pages funkcionalnosti. Ovo je kralježnica inkrementalnog usvajanja.
Kontrolni popis
- Kreirajte
app/layout.tsxkao globalni layout. - Kreirajte
app/page.tsxza root rutu ako želite rano migrirati homepage; inače ga ostavite upages. - Dodajte
app/not-found.tsxiapp/error.tsxza konzistentan UX grešaka. - Odlučite kako ćete riješiti globalne providere:
- Provideri koji se moraju izvršavati u pregledniku pripadaju u client component wrapper.
- Server-only logika ostaje u server komponentama.
Primjer kostura layouta:
// app/layout.tsx
export const metadata = {
title: "Your Site",
description: "Default description",
};
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>{children}</body>
</html>
);
}U početku držite layout minimalnim. Providere možete ponovno uvesti nakon što prva ruta radi end-to-end.
Korak 3: Migracija routinga (Pages → App Router)#
Routing u App Routeru je file-system based, ali se konvencije razlikuju.
| Pages Router | App Router |
|---|---|
pages/index.tsx | app/page.tsx |
pages/about.tsx | app/about/page.tsx |
pages/blog/[slug].tsx | app/blog/[slug]/page.tsx |
pages/blog/[...slug].tsx | app/blog/[...slug]/page.tsx |
_app.tsx | app/layout.tsx plus opcionalni client provider wrapper |
_document.tsx | u većini slučajeva rješava app/layout.tsx |
API rute u pages/api | ostavite kako jest ili premjestite u app/api/route.ts |
Kontrolni popis
- Migrirajte rute jednu po jednu, počevši od “low-risk” stranica.
- Za svaku rutu potvrdite:
- URL ostaje identičan
- redirecti se i dalje primjenjuju
- canonical URL-ovi ostaju ispravni
- analytics eventi se i dalje okidaju
💡 Savjet: Krenite s rutom koja ima minimalno podataka i nema auth. To vam daje provjeren predložak za layout, metadatu i navigaciju.
Korak 4: Navigacija i parametri#
U App Routeru:
next/routerzamjenjujenext/navigation.- Parametri rute dolaze kroz
paramsprop u page komponentama. - Query string se čita kroz
searchParams.
Primjer:
// app/products/[id]/page.tsx
export default function ProductPage({
params,
searchParams,
}: {
params: { id: string };
searchParams: Record<string, string | string[] | undefined>;
}) {
const id = params.id;
const ref = searchParams.ref;
return null;
}Kontrolni popis
- Zamijenite
useRouteriznext/routers:useRouter,usePathname,useSearchParamsiznext/navigationu client komponentama
- Izbjegavajte čitanje
window.locationu server komponentama. - Stanje navigacije držite u URL-u kada utječe na SEO ili dijeljenje.
Korak 5: Migracija dohvata podataka#
Ovdje odlazi najviše vremena i ovdje se pojavljuje najviše produkcijskih bugova.
Zamjena za getServerSideProps
Umjesto vraćanja propsa, fetchajte unutar server komponente. Po defaultu je fetch keširan u App Routeru, osim ako to ne isključite.
// app/users/page.tsx
export default async function UsersPage() {
const res = await fetch("https://api.example.com/users", { cache: "no-store" });
const users = await res.json();
return null;
}Koristite cache: "no-store" za stvarno dinamične stranice, slično SSR-u. Koristite next: { revalidate: seconds } za ISR-like ponašanje.
Zamjena za getStaticProps i ISR
// app/blog/page.tsx
export default async function BlogPage() {
const res = await fetch("https://api.example.com/posts", {
next: { revalidate: 300 },
});
const posts = await res.json();
return null;
}Zamjena za getStaticPaths
Koristite generateStaticParams:
// app/blog/[slug]/page.tsx
export async function generateStaticParams() {
const res = await fetch("https://api.example.com/slugs", {
next: { revalidate: 3600 },
});
const slugs: string[] = await res.json();
return slugs.map((slug) => ({ slug }));
}Kontrolni popis
- Za svaku migriranu rutu eksplicitno odlučite caching:
cache: "no-store"za podatke po requesturevalidateza ISR-style stranice- default caching samo kada su podaci zaista statični i sigurni
- Osigurajte da autentificirane stranice ne keširaju korisnički specifičan sadržaj.
- Dohvat podataka radite u server komponentama po defaultu, a client komponente uvodite samo kada je potrebno.
⚠️ Upozorenje: Najčešći produkcijski incident u App Routeru je slučajno keširanje personaliziranog sadržaja. Ako stranica čita cookies ili auth stanje, tretirajte je kao dinamičku i provjerite da se response ne dijeli između korisnika.
Korak 6: Granice između Client i Server komponenti#
Dobra migracija smanjuje client JS, ali morate kontrolirati gdje postoje client komponente.
Kontrolni popis
- Dodajte
"use client"samo kada trebate:- state
- effects
- browser-only API-je
- event handlere
- Dohvat podataka držite u server komponentama i prosljeđujte podatke prema dolje.
- Izbjegavajte uvoz velikih UI biblioteka u server komponente ako na kraju prisile client granice.
Jednostavan obrazac za globalne providere:
// app/providers.tsx
"use client";
export default function Providers({ children }: { children: React.ReactNode }) {
return children;
}Zatim to omotajte u app/layout.tsx gdje je potrebno.
Korak 7: SEO i migracija metadate#
App Router koristi Metadata API, koji je strukturiraniji od next/head i pomaže spriječiti dupliciranje tagova.
| SEO tema | Pages Router pristup | App Router pristup |
|---|---|---|
| Title i meta description | next/head u stranici | export const metadata ili generateMetadata |
| Dinamička metadata | izračun u komponenti | generateMetadata na temelju params |
| Canonical | ručni tag | metadata alternates.canonical |
| Open Graph | ručni meta tagovi | polje openGraph |
| Robots | ručni meta tag | polje robots |
Primjer dinamičke metadate:
// app/blog/[slug]/page.tsx
export async function generateMetadata({ params }: { params: { slug: string } }) {
const res = await fetch(`https://api.example.com/posts/${params.slug}`, {
next: { revalidate: 600 },
});
const post = await res.json();
return {
title: post.title,
description: post.excerpt,
alternates: {
canonical: `https://example.com/blog/${params.slug}`,
},
};
}Kontrolni popis
- Ponovno kreirajte sve kritične tagove:
- title
- meta description
- canonical
- robots pravila za noindex stranice
- Open Graph i Twitter kartice
- Potvrdite da paginacija i filteri pravilno koriste canonical.
- Osigurajte da structured data ostane prisutna ako koristite JSON-LD.
- Validirajte s Google Rich Results Test i Search Console URL Inspection.
Za dublje objašnjenje zašto je ovo važno, pogledajte Zašto Next.js za SEO.
ℹ️ Napomena:
generateMetadatamože fetchati podatke. Tretirajte ga kao dio data strategije rute i primijenite ista cache pravila, inače možete dobiti zastarjele naslove dok se sadržaj stranice ažurira.
Korak 8: Redirecti, rewritovi i Middleware#
Većina redirecta može ostati u next.config.js, ali migracije često uvedu promjene putanja i razlike u trailing slash ponašanju.
Kontrolni popis
- Izvezite i testirajte redirect pravila u stagingu.
- Validirajte da se stari URL-ovi i dalje ispravno rješavaju:
- marketing kampanje
- backlinkovi
- indeksirani URL-ovi
- Ako koristite Middleware:
- provjerite da ne forsira dinamičko ponašanje na inače statičnim rutama
- izbjegavajte skupe izračune u Middlewareu
Primjer redirect isječka:
// next.config.js
module.exports = {
async redirects() {
return [
{ source: "/old-blog/:slug", destination: "/blog/:slug", permanent: true },
];
},
};Korak 9: API rute i razmatranja oko Server Actions#
Možete zadržati pages/api dok migrirate UI rute. Prebacite na app/api tek kada to donosi vrijednost.
Kontrolni popis
- Zadržite stabilne API ugovore tijekom UI migracije.
- Ako uvodite server actions, potvrdite:
- CSRF razmatranja
- auth provjere su na serveru
- caching ne skriva rezultate mutacija
Ako tim još uči RSC i server-first obrasce, prvo se uskladite oko konvencija. Najbrže je imati kratki interni dokument i link na Vodič za React Server Components.
Korak 10: Deployment i observability#
App Router mijenja runtime ponašanje, posebno oko keširanja. Trebate vidljivost.
Kontrolni popis
- Provjerite podržava li hosting potrebne runtimove i streaming ponašanje.
- U stagingu testirajte:
- cold start performanse
- cache hit ratio ako je primjenjivo
- error stranice i 404 ponašanje
- Dodajte logiranje oko:
- fetch grešaka
- neočekivanih
notFoundslučajeva - auth edge caseova
- Pratite:
- distribuciju TTFB-a, ne samo prosjek
- stopu grešaka
- crawl greške u Search Console nakon lansiranja
💡 Savjet: Radite kontrolirani rollout: migrirajte jednu grupu ruta, deployajte i pratite metrike 24 do 48 sati prije širenja. Problemi App Routera su često ovisni o prometu i neće se vidjeti u lokalnom testiranju.
# Praktičan kontrolni popis migracije (kopirajte i koristite)#
Koristite ovo kao “definition of done” za svaku migriranu rutu.
| Područje | Provjera | Kriterij završetka |
|---|---|---|
| Routing | Paritet URL-a | Putanja rute se poklapa sa starom rutom i deep linkovi rade |
| Routing | Dinamički parametri | params i searchParams su točni i tipizirani |
| Dohvat podataka | Cache politika | Eksplicitno odabran no-store ili revalidate gdje treba |
| Dohvat podataka | Obrada grešaka | Pokriveni notFound, error.tsx i stanja kod API grešaka |
| RSC granica | Client komponente | Samo komponente kojima trebaju browser API-ji koriste "use client" |
| SEO | Paritet metadate | Title, description, canonical, OG tagovi odgovaraju starom ponašanju |
| SEO | Pravila indeksiranja | robots pravila očuvana za privatne ili “thin” stranice |
| Redirecti | Stari URL-ovi | Svi legacy URL-ovi redirectaju ili služe ekvivalentan sadržaj |
| Performanse | JS payload | Client bundle ne raste neočekivano |
| Deployment | Paritet okruženja | Env varovi postoje, runtime je kompatibilan, build prolazi |
| QA | Analytics | Page view i ključni eventi se i dalje okidaju ispravno |
| QA | Regresijski testovi | Barem smoke testovi za glavne user flowove |
# Rješavanje problema: česte zamke i popravci#
Iznenađenja s keširanjem#
Simptomi
- Korisnici vide zastario sadržaj nakon objave.
- Jedan korisnik vidi personalizirane podatke drugog korisnika.
- Stranica se ažurira tek nakon redeploya.
Uzroci
- Default fetch caching je nenamjerno korišten.
- Dijeljeni cache na autentificiranim rutama.
- Metadata se kešira drugačije od sadržaja stranice.
Kontrolni popis popravaka
- 1Za korisnički specifične stranice koristite
cache: "no-store"i izbjegavajte keširanje izvedenih podataka. - 2Ako se sadržaj treba osvježavati svakih N sekundi, postavite
next: { revalidate: N }na svim relevantnim fetch pozivima. - 3Provjerite da
generateMetadatakoristi istu caching strategiju kao stranica. - 4Auditirajte komponente koje čitaju cookies ili headere i potvrdite da se ruta tretira kao dinamička.
Redirecti i canonicali ruše SEO#
Simptomi
- Search Console pokazuje duplikate URL-ova ili “alternate page with proper canonical tag.”
- Organski promet padne nakon migracije.
- URL-ovi iz kampanja završavaju na neočekivanim stranicama.
Uzroci
- Nedostaju canonical tagovi nakon uklanjanja
next/head. - Promjene u trailing slash ponašanju.
- Redirect pravila nisu kopirana 1:1.
Kontrolni popis popravaka
- 1Rekreirajte canonical URL-ove kroz metadatu
alternates.canonical. - 2Provjerite da trailing slash ponašanje odgovara prethodnoj produkciji.
- 3Usporedite stare i nove popise redirecta i pokrenite automatizirane testove nad top 100 URL-ova.
- 4Validirajte HTTP status kodove. Koristite 301 za trajno, 302 za privremeno.
Dinamičke rute se ne poklapaju ili vraćaju 404#
Simptomi
- Dinamičke stranice rade lokalno, ali u produkciji vraćaju 404.
- Catch-all rute se ponašaju drugačije.
generateStaticParamsse builda, ali neke putanje nedostaju.
Uzroci
- Route file je premješten, ali je struktura foldera pogrešna.
generateStaticParamsne vraća sve potrebne putanje.- Miješanje
pagesiappstvara nejasna očekivanja oko routinga.
Kontrolni popis popravaka
- 1Potvrdite strukturu foldera:
app/segment/[param]/page.tsx. - 2Provjerite da
generateStaticParamsvraća objekte s ispravnim ključevima. - 3Ako su neke putanje zaista dinamičke, oslonite se na runtime renderiranje i postavite caching sukladno tome.
- 4Dodajte monitoring za neočekivane skokove 404 grešaka nakon releasea.
Napuhavanje client komponenti i regresija performansi#
Simptomi
- Lighthouse JS execution time raste.
- Bundleovi postanu veliki nakon migracije.
- Hydration upozorenja.
Uzroci
- Previše
"use client"datoteka. - Uvoz client-only ovisnosti u shared komponentu, što forsira client renderiranje.
- Nepotrebno premještanje globalnih providera u client scope.
Kontrolni popis popravaka
- 1Neka server komponente budu default. Dodajte
"use client"samo na leaf nodeovima. - 2Interaktivne widgete izdvojite u izolirane client komponente.
- 3Koristite dynamic imports za teški client-only UI.
- 4Usporedite veličine bundlea prije i poslije te pratite promjene po ruti.
Razlike u deploymentu između staginga i produkcije#
Simptomi
- Radi u previewu, pada u produkciji.
- Razlike u edge runtimeu.
- Build prolazi lokalno, ali pada u CI-ju.
Uzroci
- Nedostaju env varovi.
- Različite Node runtime verzije.
- Cache pravila platforme za hosting se razlikuju od lokalnih očekivanja.
Kontrolni popis popravaka
- 1Pinajte Node verziju u CI-ju i uskladite je s produkcijskim runtimeom.
- 2Osigurajte da su env varovi prisutni i za build i za runtime gdje je potrebno.
- 3Pokrećite
next buildu CI-ju s istim flagovima kao u produkciji. - 4Testirajte ponašanje na cold deployu, ne samo hot reload.
# Ključne poruke#
- Migrirajte inkrementalno tako da Pages Router i App Router rade paralelno, rutu po rutu, uz jasne “done” kriterije.
- Tretirajte caching kao zadatak prve klase: eksplicitno odaberite
no-storeilirevalidateza svaku rutu i svaki metadata fetch. - Ponovno izgradite SEO preko Metadata API-ja, uključujući canonicale, robots pravila i Open Graph, zatim validirajte u Search Console.
- Zamijenite
next/routersnext/navigationi oslonite se naparamsisearchParamsumjesto ručnog parsiranja URL-a. - Očekujte da će se većina problema u produkciji vrtjeti oko keširanja, redirecta i dinamičkih ruta, i pripremite automatizirane URL testove plus monitoring.
# Zaključak#
Uspješna migracija na Next.js App Router manje je pitanje premještanja datoteka, a više promišljanja dohvata podataka, keširanja i SEO-a kao namjernih odluka po ruti.
Ako želite da Samioda pregleda vaš plan migracije, auditira caching i SEO paritet ili odradi inkrementalni rollout uz minimalan rizik, kontaktirajte nas i pomoći ćemo vam isporučiti App Router nadogradnju uz mjerljiva poboljšanja performansi i stabilnosti.
FAQ
Više iz kategorije Web razvoj
Sve →Najbolje prakse za Tailwind CSS: izgradnja održivih korisničkih sučelja (production obrasci za 2026.)
Vodič usmjeren na produkciju o najboljim praksama za Tailwind CSS: obrasci komponenti, prilagođena konfiguracija, dark mode, responsive strategija i primjeri koje možete kopirati za održiva korisnička sučelja.
React Server Components (RSC): Što su i kako ih koristiti u Next.js App Routeru
Praktičan vodič za 2026. o React Server Components: što su, zašto su važni i kako ispravno koristiti server vs client komponente u Next.js App Routeru uz primjere koje možete copy-pasteati.
Tehnički SEO za developere (Next.js): Sve što trebate znati u 2026.
Praktičan vodič za tehnički SEO u Next.js-u fokusiran na developere: meta tagovi, strukturirani podaci, Core Web Vitals, sitemapovi, robots.txt, kanonski URL-ovi i primjeri spremni za produkciju.
Trebate pomoć s projektom?
Gradimo prilagođena rješenja koristeći tehnologije iz ovog članka. Senior tim, fiksne cijene.
Povezani članci
Zašto Je Next.js Najbolji Framework za SEO u 2026
Saznajte zašto Next.js dominira SEO performansama u 2026. Server-side rendering, Core Web Vitals, strukturirani podaci i stvarne usporedbe performansi.
React Server Components (RSC): Što su i kako ih koristiti u Next.js App Routeru
Praktičan vodič za 2026. o React Server Components: što su, zašto su važni i kako ispravno koristiti server vs client komponente u Next.js App Routeru uz primjere koje možete copy-pasteati.
Progresivne web aplikacije (PWA): Potpuni vodič za 2026.
Praktičan vodič za progressive web app (PWA) u 2026.: koncepti, poslovne prednosti u odnosu na nativne aplikacije i implementacija korak‑po‑korak u Next.js-u s manifestom i primjerima koda za service worker.