Mundarija (29)
- Bu darsda
- 1. Nega bu kerak?
- 2. generateStaticParams asoslari
- 2.1 Eng oddiy shakl
- 2.2 Natija oynasida: ro'yxatni yasash
- 2.3 Asinxron variant: blog postlari
- 3. Build jadvalini o'qish
- 3.1 ◐ va uning ostidagi ○
- 3.2 Ro'yxatda yo'q slug
- 4. Ichma-ich va catch-all segmentlar
- 4.1 Bir nechta dinamik segment
- 4.2 Natija oynasida: ota va bola
- 4.3 Catch-all segment
- 5. Cache Components bilan uchta haqiqiy xato
- 5.1 Ro'yxatsiz dinamik sahifa
- 5.2 Biz topdik: bo'sh massiv ham xato
- 5.3 Eski segment sozlamalari
- 6. Eski model: legacy kodni o'qish
- 6.1 Yangi sozlama: ensureStatic
- 7. Portfolio qadami: ro'yxatlarni tekshirish
- 8. Ko'p uchraydigan xatolar
- 9. Mashqlar
- 1-mashq (oson): kalit va qiymat
- 2-mashq (o'rta): faqat chop etilgan postlar
- 3-mashq (qiyin): ikki daraja
- 4-mashq: Portfolio qadami
- 10. Real ishda
- Xulosa
- Manbalar
Next.js generateStaticParams: dinamik sahifalarni build vaqtida yaratish
Qisqacha:
generateStaticParams— dinamik sahifa (app/loyihalar/[slug]/page.tsx) yonidagi funksiya: u "qaysisluglar bor" ro'yxatini qaytaradi ([{ slug: "vazifalar" }, { slug: "bahor" }]), va Next.js har biri uchun tayyor HTML'ni build vaqtida yaratadi. Next 16 da Cache Components yoqilgan loyihada bu funksiyasiz dinamik sahifa build'dan o'tmaydi, bo'sh massiv ham xato. Eski segment sozlamalari (export const dynamic,revalidate,fetchCache,dynamicParams) Cache Components bilan ishlamaydi — ularni faqat eski kodni o'qish uchun bilasiz.
Bu darsda
generateStaticParamsyozasiz: sinxron (massivdan) va asinxron (fayllardan) variantlarda.- Build jadvalidagi
◐ /loyihalar/[slug]va uning ostidagi○sahifalarni o'qiysiz. - Ichma-ich dinamik segmentlar va catch-all segment uchun parametrlarni qaytarasiz.
- Cache Components'dagi uchta haqiqiy build xatosini taniysiz: ro'yxatsiz, bo'sh ro'yxat va eski sozlama.
- Eski Next 14/15 kodidagi
dynamic,revalidate,dynamicParamsnimani bildirishini tushuntirasiz.
Oldin bilishingiz kerak: Rendering strategiyalari, Fayl-asosli routing, Streaming va Suspense, map: har elementni o'zgartirish.
1. Nega bu kerak?
portfolio da uchta loyiha sahifasi bor: /loyihalar/vazifalar, /loyihalar/bahor, /loyihalar/landing. Hammasi bitta faylda — [slug]/page.tsx. Next.js bu fayldan qachon HTML yasaydi?
Ikki yo'l bor. Birinchisi — har so'rovda: kimdir /loyihalar/bahor ni ochsa, server o'sha paytda sahifani chizadi. Ikkinchisi — build vaqtida: Next.js uchala sahifani oldindan tayyorlab qo'yadi, so'rov kelganda tayyor faylni beradi (TTFB bir necha millisekund).
Ikkinchisi tezroq. Lekin Next.js build vaqtida qaysi slug lar borligini bilmaydi — papka nomi [slug] hech narsa demaydi. Unga ro'yxatni siz berasiz. Bu xuddi bosmaxonaga o'xshaydi: taklifnoma shabloni bitta, lekin nechta va kimlarga chop etishni — mehmonlar ro'yxatini — siz berasiz.
Fayl-asosli routing darsida bu funksiyani bir marta ko'rgansiz: busiz build to'xtagan edi. Bugun uni to'liq o'rganamiz.
2. generateStaticParams asoslari
2.1 Eng oddiy shakl
Kanondagi loyihalar/[slug]/page.tsx boshi:
import { LOYIHALAR } from "@/malumot/loyihalar";
// Cache Components yoqilgan: params — "runtime data". Ro'yxat
// oldindan ma'lum bo'lsa, build vaqtida hammasi yaratiladi
// (N-17 da chuqurroq); aks holda build "uncached or runtime
// data during prerendering" bilan to'xtaydi.
export function generateStaticParams() {
return LOYIHALAR.map((l) => ({ slug: l.slug }));
}
export default async function LoyihaSahifasi({
params,
}: PageProps<"/loyihalar/[slug]">) {
const { slug } = await params;
// …
}Kanon izohi telefonga sig'ishi uchun to'rt qatorga bo'lindi.
Qoidalar:
| Qoida | Izoh |
|---|---|
Nomi aynan generateStaticParams |
Next.js shu nom bilan qidiradi |
export qilinadi |
page.tsx (yoki layout.tsx, route.ts) faylidan |
| Massiv qaytaradi | Har element — bitta sahifaning params i |
| Kalit — papka nomi | [slug] → { slug: "…" }; [id] bo'lsa → { id: "…" } |
| Qiymat — satr | Son emas: { id: "7" }, { id: 7 } emas |
2.2 Natija oynasida: ro'yxatni yasash
generateStaticParams — oddiy funksiya. Uning ichidagi mantiqni alohida sinash mumkin. Faraz qiling, loyihalarning bittasi hali qoralama — uni saytga chiqarmaymiz:
const PROJECTS = [
{ slug: "vazifalar", title: "Vazifalar", draft: false },
{ slug: "bahor", title: "«Bahor» oshxonasi", draft: false },
{ slug: "landing", title: "Landing sahifa", draft: false },
{ slug: "chat", title: "Chat (qoralama)", draft: true },
];
function generateStaticParams() {
return PROJECTS.filter((p) => !p.draft).map((p) => ({
slug: p.slug,
}));
}
console.log(generateStaticParams());Konsolda:
[ { slug: 'vazifalar' }, { slug: 'bahor' }, { slug: 'landing' } ]Qoralama ro'yxatga kirmadi — demak build uning HTML'ini yasamaydi. Bu ma'lumotni map va filter bilan qayta ishlashning oddiy misoli.
2.3 Asinxron variant: blog postlari
Blog postlari kodda emas, fayllarda (src/blog/*.md). Ro'yxatni olish uchun fayl tizimini o'qish kerak — demak funksiya async:
// app/(sayt)/blog/[slug]/page.tsx
export async function generateStaticParams() {
return (await postlar()).map((p) => ({ slug: p.slug }));
}postlar() — Server Components darsida yozilgan funksiya: papkadagi .md fayllarni o'qiydi. Build vaqtida u bir marta ishlaydi. Yangi post qo'shsangiz — yangi build kerak (postlar faqat deploy bilan o'zgaradi — bu kanonning ongli qarori).
generateStaticParams ichida fetch ham qilish mumkin — masalan, CMS'dan maqolalar ro'yxatini olish. Build vaqtidagi fetch natijalari Next.js ichida birlashtiriladi: sahifa ichida ham o'sha fetch bo'lsa, qayta so'ralmaydi (hujjat bo'yicha).
3. Build jadvalini o'qish
3.1 ◐ va uning ostidagi ○
Kanon build jadvalidan dinamik sahifalar qismi (xom natijalar/tajriba/19-build.txt):
├ /blog/[slug]
│ ├ ◐ /blog/[slug]
│ ├ ○ /blog/portfolio-v2 30d 1y
│ ├ ○ /blog/server-components 30d 1y
│ └ ○ /blog/vazifalar-testlari 30d 1y
├ /loyihalar/[slug]
│ ├ ◐ /loyihalar/[slug]
│ ├ ○ /loyihalar/vazifalar
│ ├ ○ /loyihalar/bahor
│ └ ○ /loyihalar/landingHar dinamik marshrut ostida ikki xil qator:
○ /loyihalar/vazifalar—generateStaticParamsbergan har slug uchun to'liq statik sahifa. Build vaqtida tayyor.◐ /loyihalar/[slug]— ro'yxatda yo'q slug uchun "qobiq" (Partial Prerender). Kimdir/loyihalar/yangini ochsa, Next.js tayyor qobiqni beradi va qolganini so'rov paytida chizadi.
Blog qatorlaridagi 30d 1y — keshning yangilanish va eskirish muddatlari. Ular postlar() ichidagi "use cache" dan keladi — Cache Components I darsida ochamiz.
flowchart LR
G["generateStaticParams()"] --> V["vazifalar"]
G --> B["bahor"]
G --> L["landing"]
V --> H1["○ HTML"]
B --> H2["○ HTML"]
L --> H3["○ HTML"]
S["ro'yxatda yo'q slug"] --> Q["◐ qobiq + so'rovda render"]Diagrammada chap tomondagi bitta funksiya uchta tayyor sahifa beradi. Pastdagi alohida yo'l — ro'yxatdan tashqari manzillar uchun.
3.2 Ro'yxatda yo'q slug
/loyihalar/yoq ochilsa nima bo'ladi? Sahifa notFound() chaqiradi (Maxsus fayllar). Lekin kanon bu yerda tuzoq topgan: qobiq oqim bilan ketgani uchun birinchi so'rov 200 status bilan keladi, keyingilari 404. Next 15 dagi davo — export const dynamicParams = false ("ro'yxatdan tashqari slug — darhol 404"). Kanon uni Next 16.4 da Cache Components bilan sinab ko'rdi — build to'xtadi (xom natijalar/tajriba/06-dynamicParams-xato.txt, ranglar olib tashlangan):
Error: Route segment config "dynamicParams" is not compatible with `nextConfig.cacheComponents`. Please remove it.Tarjimasi: "dynamicParams segment sozlamasi cacheComponents bilan mos emas. Uni olib tashlang". Kanon bu muammoni proxy.ts bilan yechdi — ro'yxatda yo'q slug proxy'da 404 oladi.
Tekshirib ko'ring: to'rtinchi loyiha (
chat) qo'shdingiz,LOYIHALARmassiviga yozdingiz, lekin build qilmadingiz. Production'da/loyihalar/chatochiladimi?
Javob
Ochiladi, lekin build vaqtida tayyorlangan statik sahifa sifatida emas. Production'dagi server eski build bilan ishlaydi: chat uning ro'yxatida yo'q, demak ◐ qobiq va so'rov paytidagi render ishga tushadi. Sahifa ma'lumotni kod ichidagi LOYIHALAR dan oladi — lekin bu ham eski build'ning kodi, unda chat yo'q. Natija: notFound(). Yangi loyiha saytda ko'rinishi uchun — yangi build va deploy.
4. Ichma-ich va catch-all segmentlar
4.1 Bir nechta dinamik segment
portfolio da loyihalar/[slug]/rasm/page.tsx bor (Parallel va intercepting routes). Uning yo'lida ham [slug] bor, demak unga ham ro'yxat kerak. Kanon har faylda o'z funksiyasini yozdi:
// app/(sayt)/loyihalar/[slug]/rasm/page.tsx
export function generateStaticParams() {
return LOYIHALAR.map((l) => ({ slug: l.slug }));
}Va xuddi shu funksiya modal variantida ham (@modal/(.)[slug]/rasm/page.tsx). Aks holda uchala sahifada ham Fayl-asosli routing darsidagi build xatosi chiqardi.
Yo'lda ikkita dinamik segment bo'lsa-chi? Masalan, app/dokon/[kategoriya]/[mahsulot]/page.tsx. Ikki usul bor (Next.js hujjati bo'yicha):
// 1-usul: bola sahifa ikkala qiymatni ham qaytaradi
export function generateStaticParams() {
return [
{ kategoriya: "kiyim", mahsulot: "chopon" },
{ kategoriya: "kiyim", mahsulot: "doppi" },
{ kategoriya: "idish", mahsulot: "choynak" },
];
}// 2-usul: ota layout kategoriyalarni beradi…
// app/dokon/[kategoriya]/layout.tsx
export function generateStaticParams() {
return [{ kategoriya: "kiyim" }, { kategoriya: "idish" }];
}
// …bola esa har kategoriya uchun alohida chaqiriladi
// app/dokon/[kategoriya]/[mahsulot]/page.tsx
export function generateStaticParams({
params,
}: {
params: { kategoriya: string };
}) {
return mahsulotlar(params.kategoriya).map((m) => ({
mahsulot: m.slug,
}));
}Ikkinchi usulda bola funksiya ota bergan har to'plam uchun bir marta chaqiriladi va params ni sinxron oladi (sahifadagidek Promise emas). U faqat o'z segmentini qaytaradi.
4.2 Natija oynasida: ota va bola
Next.js ota va bola ro'yxatini qanday birlashtirishini oddiy JS bilan takrorlaymiz:
const PRODUCTS = {
kiyim: ["chopon", "doppi"],
idish: ["choynak"],
};
// app/dokon/[kategoriya]/layout.tsx
function parentParams() {
return Object.keys(PRODUCTS).map((k) => ({ kategoriya: k }));
}
// app/dokon/[kategoriya]/[mahsulot]/page.tsx
function childParams({ params }) {
return PRODUCTS[params.kategoriya].map((m) => ({ mahsulot: m }));
}
// Next.js build vaqtida taxminan shunday birlashtiradi:
const pages = parentParams().flatMap((parent) =>
childParams({ params: parent }).map((child) => ({
...parent,
...child,
})),
);
for (const p of pages) {
console.log(`/dokon/${p.kategoriya}/${p.mahsulot}`);
}Konsolda:
/dokon/kiyim/chopon
/dokon/kiyim/doppi
/dokon/idish/choynakUchta sahifa: har kategoriya uchun bola funksiya alohida chaqirildi. Bu model — Next.js ichki kodi emas, faqat g'oyasi.
4.3 Catch-all segment
[...qism] papkasi uchun qiymat — massiv (Fayl-asosli routing darsidagi params bilan bir xil):
// app/hujjatlar/[...qism]/page.tsx
export function generateStaticParams() {
return [
{ qism: ["boshlash"] },
{ qism: ["boshlash", "ornatish"] },
{ qism: ["api", "link"] },
];
}Bu uchta sahifa beradi: /hujjatlar/boshlash, /hujjatlar/boshlash/ornatish, /hujjatlar/api/link.
5. Cache Components bilan uchta haqiqiy xato
Next 16 skeletida cacheComponents: true sukut bo'yicha yoqilgan (Loyiha yaratish). U generateStaticParams ni majburiy qiladi va eski sozlamalarni taqiqlaydi. Uchta haqiqiy xatoni bilsangiz, ko'p vaqt tejaysiz.
5.1 Ro'yxatsiz dinamik sahifa
Kanonning holat 04 dagi build xatosi (natijalar/tajriba/04-params-xato.txt dan):
Error: Route "/loyihalar/[slug]": Next.js encountered uncached or runtime data during prerendering.Tarjimasi: "Prerender paytida Next.js keshlanmagan yoki so'rov paytidagi ma'lumotga duch keldi". params — so'rov paytidagi ma'lumot. Ro'yxat bo'lmasa, Next.js build vaqtida params ni hech qanday qiymat bilan to'ldira olmaydi. Davosi — generateStaticParams.
5.2 Biz topdik: bo'sh massiv ham xato
Next 15 da generateStaticParams dan [] qaytarish mumkin edi — "build vaqtida hech narsa yaratma, har sahifani birinchi ochilganda yarat". Biz kanon nusxasida (holat 24) loyihalar ro'yxati o'rniga return []; yozib build qildik:
Error: When using Cache Components, all `generateStaticParams` functions must return at least one result. This is to ensure that we can perform build-time validation that there is no other dynamic accesses that would cause a runtime error.
Learn more: https://nextjs.org/docs/messages/empty-generate-static-params
at <unknown> (src\app\(sayt)\loyihalar\[slug]\page.tsx:12:10)
> Build error occurred
Error: Failed to collect page data for /loyihalar/[slug]Tarjimasi: "Cache Components ishlatilganda hamma generateStaticParams funksiyalari kamida bitta natija qaytarishi shart. Bu — build vaqtida runtime xatosiga olib keladigan boshqa dinamik murojaatlar yo'qligini tekshirish uchun". Ya'ni Next.js hech bo'lmasa bitta sahifani chizib ko'rib, unda cookies() kabi taqiqlangan narsa yo'qligiga ishonch hosil qilmoqchi.
5.3 Eski segment sozlamalari
Next 14/15 da sahifa xulqini faylning yuqorisidagi export const bilan sozlash odatiy edi. Kanon to'rttasini /haqimda sahifasida sinadi (natijalar/tajriba/17-segment-config.txt):
== export const revalidate = 3600;
Error: Route segment config "revalidate" is not compatible with `nextConfig.cacheComponents`. Please remove it.
== export const dynamic = "force-static";
Error: Route segment config "dynamic" is not compatible with `nextConfig.cacheComponents`. Please remove it.
== export const fetchCache = "force-cache";
Error: Route segment config "fetchCache" is not compatible with `nextConfig.cacheComponents`. Please remove it.
== export const runtime = "nodejs";
Error: Route segment config "runtime" is not compatible with `nextConfig.cacheComponents`. Please remove it.To'rttasi ham build xatosi. Oxirgisi qiziq: Next.js hujjatidagi jadvalda runtime hali "mavjud sozlama" sifatida turibdi, uning sukut qiymati esa aynan "nodejs". Lekin 16.4.0 da Cache Components bilan uni yozish — hatto sukut qiymatini — build'ni to'xtatadi. Hujjat va haqiqiy xulq farq qilganda, haqiqiy chiqish ustun.
6. Eski model: legacy kodni o'qish
Ishga kirganingizda ko'p loyihalar hali Next 14/15 da bo'ladi yoki cacheComponents ni yoqmagan bo'ladi. U yerda shu sozlamalarni uchratasiz:
| Sozlama | Ma'nosi (eski model) | Cache Components'da o'rniga |
|---|---|---|
dynamic = "force-dynamic" |
Har so'rovda render | Sukut bo'yicha dinamik |
dynamic = "force-static" |
Doim statik, so'rov API'lari bo'sh | "use cache" |
revalidate = 3600 |
Sahifani soatda bir yangilash (ISR) | cacheLife("hours") |
fetchCache = "force-cache" |
Hamma fetch keshlanadi |
"use cache" funksiyada |
dynamicParams = false |
Ro'yxatdan tashqari — 404 | Proxy yoki tekshiruv |
ISR (Incremental Static Regeneration — bosqichma-bosqich statik yangilash) — Next.js'ning eski atamasi: statik sahifa ma'lum vaqtdan keyin fonda qayta yaratiladi. G'oya o'lmagan — u endi cacheLife bilan ifodalanadi (Cache Components I).
Eski loyihada export const revalidate = 60 ni ko'rsangiz, uni shunday o'qing: "bu sahifa 60 soniya keshda turadi, keyin fonda yangilanadi". cacheComponents: true ga o'tishda esa uni o'chirib, kesh muddatini "use cache" funksiyasiga ko'chirasiz.
Cache Components'da ham ishlaydigan sozlamalar hujjatda bor: maxDuration (serverda bitta so'rovga ruxsat etilgan eng uzun vaqt, deploy platformasi uchun), preferredRegion (qaysi mintaqada ishlash). Kanon ularni ishlatmadi — lokal next start da ma'nosi yo'q.
6.1 Yangi sozlama: ensureStatic
Cache Components bilan yangi segment sozlamasi paydo bo'ldi — ensureStatic. U "bu sahifa albatta statik qolsin" degan va'da: keyinchalik kimdir sahifaga so'rov paytidagi ma'lumot qo'shsa, build to'xtaydi. Biz uni GitHub bloki hali dinamik bo'lgan holatda (connection() bilan, holat 16) «Men haqimda» ga qo'shib ko'rdik:
export const ensureStatic = "navigation";Build:
Error: Route "/haqimda": Next.js encountered uncached or runtime data on a route that must be fully static.
This route is configured to be fully static, but some data requires rendering at request time.
Ways to fix this:
- [cache] For uncached data (`fetch`, database calls): cache the access with `"use cache"` (does not apply to `connection()`)
- [remove] Remove the data access
- [client] Read the data on the clientTarjimasi: "/haqimda to'liq statik bo'lishi kerak, lekin unda so'rov paytida chiziladigan ma'lumot bor. Tuzatish yo'llari: "use cache" bilan keshlang, murojaatni olib tashlang yoki ma'lumotni brauzerda o'qing". Bu — jamoada foydali "qo'riqchi": muhim sahifaning tezligi tasodifan buzilmaydi. Kanon uni ishlatmadi (sayt kichik, build jadvali yetarli nazorat), shuning uchun bu bizning tajribamiz.
7. Portfolio qadami: ro'yxatlarni tekshirish
Bu dars, Cache Components I va Cache Components II portfolio ning bitta holatini quradi. Commit — uchinchisida. Hali commit qilmang.
Kanon bu bosqichda hamma dinamik sahifani tekshirdi:
| Sahifa | generateStaticParams |
Natija |
|---|---|---|
loyihalar/[slug] |
LOYIHALAR dan, sinxron |
◐ + 3 ○ |
loyihalar/[slug]/rasm |
xuddi shunday | ◐ + 3 ○ |
loyihalar/@modal/(.)[slug]/rasm |
xuddi shunday | ◐ + 3 ○ |
blog/[slug] |
postlar() dan, async |
◐ + 3 ○ (30d 1y) |
Sizdan:
- Har dinamik
page.tsxdagenerateStaticParamsborligini tekshiring. npm run build— jadvalda har dinamik marshrut ostida○sahifalar chiqishi kerak.- Tajriba:
haqimda/page.tsxgaexport const revalidate = 3600;yozib build qiling — «Eski segment sozlamalari» bo'limidagi xatoni o'z ko'zingiz bilan ko'ring. Keyin qatorni o'chiring.
8. Ko'p uchraydigan xatolar
| Belgi | Sabab | Davosi |
|---|---|---|
uncached or runtime data during prerendering dinamik sahifada |
generateStaticParams yo'q |
Ro'yxatni qaytaring |
must return at least one result |
Bo'sh massiv | Hech bo'lmasa bitta slug |
Route segment config "…" is not compatible |
Eski export const sozlama |
O'chiring; "use cache" / cacheLife |
Sahifa build'da yo'q, params noto'g'ri |
Kalit papka nomiga mos emas ({ id } vs [slug]) |
Kalit = papka nomi |
| Catch-all sahifa yaratilmadi | Qiymat satr, massiv emas | { qism: ["a", "b"] } |
| Yangi post saytda yo'q | Ro'yxat build vaqtida olingan | Qayta build va deploy |
| Rasm sahifasi build'da yiqildi | Ichki dinamik sahifada o'z ro'yxati yo'q | Har dinamik page.tsx ga |
9. Mashqlar
Mashqlar kurs/mashqlar/23/17-generate-static-params/ da. Jonli yechimlarni «Ishga tushir» bilan sinang.
1-mashq (oson): kalit va qiymat
app/kurs/[id]/page.tsxuchun to'g'ri element:{ : "7" }{ id: 7 }— qiymat turi noto'g'ri, kerak:app/hujjat/[...yol]/page.tsxuchun/hujjat/a/b—{ yol: ] }- Cache Components'da
return []— build
Yechim
- id — kalit papka nomidagi qavs ichidagi so'z.
- satr — URL segmenti doim matn;
params.idham"7"bo'ladi. - ["a", "b"] — catch-all segment massiv oladi.
- xato — Cache Components'da kamida bitta natija shart.
2-mashq (o'rta): faqat chop etilgan postlar
Postlar ro'yxati: { slug, date, published }. generateStaticParams faqat published: true va sanasi today dan oldin yoki teng bo'lgan postlarni qaytarsin (rejalashtirilgan postlar hali chiqmaydi). Sanalar "2026-10-21" shaklidagi satr — ularni to'g'ridan satr sifatida solishtirish mumkin (shu shaklda alifbo tartibi = sana tartibi). today ni parametr qilib bering.
Yechim
const POSTS = [
{ slug: "portfolio-v2", date: "2026-10-21", published: true },
{ slug: "server-components", date: "2026-10-14", published: true },
{ slug: "keyingi-reja", date: "2026-11-01", published: true },
{ slug: "qoralama", date: "2026-10-01", published: false },
];
function generateStaticParams(today) {
return POSTS.filter((p) => p.published && p.date <= today).map(
(p) => ({ slug: p.slug }),
);
}
console.log(generateStaticParams("2026-10-21"));Konsolda:
[ { slug: 'portfolio-v2' }, { slug: 'server-components' } ]keyingi-reja — kelajak sanasi, qoralama — chop etilmagan. Haqiqiy Next.js'da today ni funksiya ichida new Date() bilan olmang: Cache Components prerender paytida argumentsiz new Date() ni taqiqlaydi (Hydration darsidagi build xatosi). Build vaqtidagi sanani aniq berish — xavfsizroq.
3-mashq (qiyin): ikki daraja
Kurs platformasi: app/kurs/[kurs]/[dars]/page.tsx. Ma'lumot: { javascript: ["ozgaruvchilar", "funksiyalar"], python: ["kirish"] }. Ikkinchi usul (ota va bola funksiyalari) bilan hamma sahifalarni yarating, keyin har sahifa uchun /kurs/…/… manzilini chiqaring. Qo'shimcha: bola funksiya har chaqirilganda konsolga bola: <kurs> yozsin — u necha marta chaqirilishini ko'ring.
Yechim
const COURSES = {
javascript: ["ozgaruvchilar", "funksiyalar"],
python: ["kirish"],
};
function parentParams() {
return Object.keys(COURSES).map((kurs) => ({ kurs }));
}
function childParams({ params }) {
console.log(`bola: ${params.kurs}`);
return COURSES[params.kurs].map((dars) => ({ dars }));
}
const pages = parentParams().flatMap((parent) =>
childParams({ params: parent }).map((child) => ({
...parent,
...child,
})),
);
for (const p of pages) console.log(`/kurs/${p.kurs}/${p.dars}`);Konsolda:
bola: javascript
bola: python
/kurs/javascript/ozgaruvchilar
/kurs/javascript/funksiyalar
/kurs/python/kirishBola funksiya ikki marta chaqirildi — ota bergan har kurs uchun bir marta. Katta saytda (100 kurs × 50 dars) bu 5 000 sahifa: build vaqti ham shunga yarasha o'sadi. Shunday hollarda faqat eng mashhur sahifalarni ro'yxatga qo'yib, qolganini ◐ qobiqqa qoldirish odatiy yo'l.
4-mashq: Portfolio qadami
«Portfolio qadami» bo'limidagi uchta qadamni bajaring: har dinamik sahifada generateStaticParams, build jadvalini o'qish va revalidate tajribasi. Build jadvalidagi ○ sahifalar sonini sanang. Commit hali yo'q.
Yechim
Kanon holatida dinamik marshrutlar ostida 12 ta ○ sahifa: 3 loyiha, 3 + 3 rasm sahifasi (to'liq va modal), 3 blog posti. revalidate tajribasida build Route segment config "revalidate" is not compatible with nextConfig.cacheComponents bilan to'xtashi kerak — qatorni o'chirgach yana toza.
10. Real ishda
- Blog, hujjatlar sayti, e-commerce katalogi —
generateStaticParamsning asosiy joyi. Mashhur 1 000 mahsulot build'da, qolgani birinchi so'rovda. - Build vaqti — katta saytlarda haqiqiy muammo: 10 000 sahifa build'ni o'nlab daqiqaga cho'zadi. Jamoalar "qaysi sahifalar oldindan yaratiladi" ni ongli tanlaydi.
- Eski segment sozlamalari — Next 14/15 loyihalarida har qadamda. Migratsiyada (
cacheComponentsni yoqishda) ular birinchi bo'lib olib tashlanadi (Versiyalarni yangilash). - Intervyuda: "
generateStaticParamsnima qiladi?", "SSG va ISR farqi?" — klassik savollar.
Xulosa
generateStaticParamsdinamik sahifa uchun slug ro'yxatini qaytaradi; har biri build vaqtida○statik sahifa bo'ladi.- Ro'yxatda yo'q slug —
◐qobiq va so'rov paytidagi render. - Kalit = papka nomi, qiymat — satr; catch-all uchun massiv; ichma-ich segmentlarda bola ota bergan har to'plam uchun chaqiriladi.
- Cache Components'da: ro'yxatsiz va bo'sh ro'yxat — build xatosi.
dynamic,revalidate,fetchCache,dynamicParamsva hattoruntime— Cache Components bilan build xatosi; ular eski kodni o'qish uchun.
Keyingi dars: Cache Components I: "use cache" va PPR — GitHub blokini keshlaymiz va sahifa yana to'liq statik bo'ladi.
Manbalar
- Next.js hujjati —
generateStaticParams16.4-bob: https://nextjs.org/docs/app/api-reference/functions/generate-static-params (2026-10-21 da o'qildi) - Next.js hujjati — Route Segment Config: https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config
- Next.js hujjati —
ensureStatic: https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config/ensureStatic - Next.js xato sahifasi — Empty generateStaticParams: https://nextjs.org/docs/messages/empty-generate-static-params
- Kanon o'lchovlari:
portfoliov2, holat 19 (natijalar/tajriba/17-segment-config.txt,19-build.txt,04-params-xato.txt,06-dynamicParams-xato.txt); bo'sh ro'yxat vaensureStatic— biz ishga tushirdik (next 16.4.0, kanon holati nusxasi).
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!