Statički izvezen Next.js sajt je samo HTML, CSS, JavaScript i resursi u jednom folderu. Taj folder možete da postavite na bilo koji statički hosting — Cloudflare Pages, GitHub Pages, S3, Netlify, Nginx server — bez Node.js servera koji treba pokretati, ažurirati ili plaćati. Ovaj sajt je napravljen upravo tako.
Vodič pokriva kako statički izvoz radi u App Routeru, čega se odričete i kako da zaobiđete svako ograničenje.
Uključivanje
Od Next.js 14, komanda next export ne postoji; statički izvoz je opcija u konfiguraciji:
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'export',
// Optional: /about → /about/index.html instead of /about.html
trailingSlash: true,
images: { unoptimized: true },
}
export default nextConfignext build sada upisuje sajt u out/. Pregledajte ga bilo kojim statičkim serverom:
npx serve outŠta radi
Više nego što ljudi očekuju:
- Server Components. Izvršavaju se jednom, tokom build-a. Preuzimajte podatke, čitajte fajlove, pozivajte API-je — rezultat se upisuje u HTML.
- Client Components, hookovi, context i sve klijentske biblioteke.
- Dinamičke rute, sve dok svaku putanju navedete u
generateStaticParams. - Route Handlers sa
GET, koji postaju statički fajlovi (zgodno zafeed.json,sitemap.xml,robots.txt). - Metadata API: naslovi, opisi, Open Graph, kanonski URL-ovi.
- Navigacija na klijentu sa
<Link>i unapred učitavanjem.
Šta ne radi i šta umesto toga
| Funkcija | Zašto ne radi | Rešenje |
|---|---|---|
| Podrazumevana optimizacija slika | Potreban je server | images.unoptimized: true, slike unapred u pravoj veličini ili custom loader (Cloudinary, imgix, Cloudflare Images) |
Dinamičke rute bez generateStaticParams |
Stranice moraju biti poznate tokom build-a | Navedite sve parametre; podesite dynamicParams = false |
cookies(), headers(), podaci iz zahteva |
Nema zahteva u toku rada | Čitajte ih na klijentu ili premestite logiku u API |
| Server Actions | Potreban je server | POST na serverless funkciju (Workers, Lambda) |
| Middleware | Potreban je server | Pravila na nivou hostinga: _redirects, _headers, edge funkcije |
redirects, rewrites, headers u konfiguraciji |
Primenjuje ih Next server | Isto: podesite ih na hostingu |
ISR / revalidate |
Nema servera koji regeneriše | Ponovni build pri promeni sadržaja (Git push ili webhook) |
| Ugrađeno i18n rutiranje | Funkcija Pages Routera | Segmenti za jezik: app/[lang]/... sa generateStaticParams |
Dinamičke rute, kako treba
Svaki dinamički segment mora da ima spisak svojih vrednosti tokom build-a:
import { getAllPosts, getPost } from '@/lib/blog'
import { notFound } from 'next/navigation'
export const dynamicParams = false // unknown slugs are a 404, not a runtime render
export async function generateStaticParams() {
const posts = await getAllPosts()
return posts.map((post) => ({ slug: post.slug }))
}
export default async function Page({ params }: { params: Promise<{ slug: string }> }) {
const { slug } = await params
const post = await getPost(slug)
if (!post) notFound()
return <article dangerouslySetInnerHTML={{ __html: post.html }} />
}Imajte na umu da je u Next.js 15 params Promise — koristite await.
Jedna zamka: ako generateStaticParams vrati prazan niz, build pada, jer ruta ne bi proizvela nijednu stranicu. Ako kolekcija može biti prazna (recimo, nov blog), vratite privremeni parametar i pustite da se prikaže 404.
Slike
Imate tri razumne opcije:
unoptimized: truei sami izvezite slike u pravoj veličini (WebP ili AVIF, 1–2× prikazane širine). Jednostavno i brzo, ako ste disciplinovani.- Custom loader koji pokazuje na CDN za slike i na zahtev vraća različite veličine:
export default function loader({ src, width, quality }) {
return `https://images.example.com/${src}?w=${width}&q=${quality || 75}`
}const nextConfig = {
output: 'export',
images: { loader: 'custom', loaderFile: './image-loader.js' },
}- Običan
<img>sasrcset,loading="lazy"i eksplicitnimwidth/heightda biste izbegli pomeranje rasporeda.
Forme i sve što zahteva server
Statički sajt i dalje može da ima forme, pretragu i prijavu — samo serverski deo živi negde drugde. Uobičajen obrazac je mala serverless funkcija koju stranica poziva preko fetch. Rešenje koje koristi ovaj sajt opisao sam u tekstu serverless kontakt forma sa Cloudflare Workers i D1.
Preusmerenja i zaglavlja
Podesite ih na hostingu. Na Cloudflare Pages i Netlify, fajl _redirects u public/ kopira se u out/:
/old-page /new-page 301
/blog/* /journal/:splat 301I _headers za keširanje i sigurnosna zaglavlja:
/_next/static/*
Cache-Control: public, max-age=31536000, immutableAžuriranje sadržaja bez servera
Pošto nema ISR-a, promene sadržaja zahtevaju novi build. To zvuči gore nego što jeste: povežite hosting sa Git repozitorijumom i svaki push se izgradi i objavi za minut-dva. Za sadržaj u CMS-u, usmerite webhook CMS-a na deploy hook hostinga. Za blog je čuvanje tekstova kao Markdown u repozitorijumu najjednostavnije rešenje — pogledajte Markdown blog u Next.js bez CMS-a.
Kada statički izvoz nije pravi izbor
- Stranice koje zavise od prijavljenog korisnika i renderuju se na serveru.
- Hiljade stranica koje se menjaju na svakih nekoliko minuta (vreme build-a raste sa brojem stranica).
- Sve što zaista zahteva renderovanje u trenutku zahteva, poput personalizovanih cena.
Za marketinške sajtove, portfolije, dokumentaciju, blogove i landing stranice, statički izvoz je obično najbrža, najjeftinija i najotpornija opcija.
Kontrolna lista
-
output: 'export'unext.config - Svaka dinamička ruta ima
generateStaticParamsidynamicParams = false - Slike rešene (unoptimized, custom loader ili
<img>) - Bez
cookies(),headers(), Server Actions i middleware-a - Preusmerenja i zaglavlja podešena na hostingu
- Objavljivanje pokreću Git push ili CMS webhookovi
-
out/pregledan lokalno pre prvog objavljivanja
Sledeći korak: pobrinite se da pretraživači razumeju stranice koje izvozite — tehnički SEO za Next.js App Router.

