Mundarija (29)
- Bu darsda
- 1. Nega bu kerak?
- 2. Route groups: (guruh)
- 2.1 Qavs — URL'dan tashqarida
- 2.2 Guruhning o'z layout'i va template'i
- 2.3 Nega header va footer root layout'da qoldi?
- 2.4 Biz sinadik: ikki guruhda bir xil manzil
- 2.5 loading.tsx ni bitta sahifaga cheklash
- 3. Bir nechta root layout
- 3.1 Qachon kerak?
- 3.2 Narxi: to'liq qayta yuklash
- 4. Private papkalar: _papka
- 4.1 Pastki chiziq — routing'dan tashqari
- 4.2 Colocation'dan farqi nima?
- 4.3 Pastki chiziqli URL kerak bo'lsa
- 5. Modelda: papka yo'lidan URL
- 6. Loyihani tashkil qilish usullari
- 7. Portfolio qadami: (sayt) guruhi va _komponentlar
- 7.1 Ko'chirish
- 7.2 Natija
- 8. Ko'p uchraydigan xatolar
- 9. Mashqlar
- 1-mashq (oson): fayldan URL
- 2-mashq (o'rta): qaysi layout'lar o'raydi?
- 3-mashq (qiyin): to'qnashuvni toping
- 4-mashq: Portfolio qadami
- 10. Real ishda
- Xulosa
- Manbalar
Next.js route groups va private papkalar: (guruh), _papka va loyiha tashkili
Qisqacha: Qavs ichidagi papka — route group (
(sayt)) — URL'ga kirmaydi:app/(sayt)/haqimda/page.tsxbaribir/haqimda. U sahifalarni guruhlash va guruhga o'z layout'ini berish uchun kerak. Pastki chiziq bilan boshlangan papka — private papka (_komponentlar) — routing'dan butunlay chiqariladi: ichidagi hech bir fayl sahifa bo'lmaydi. Ikkalasi ham URL'ga tegmasdanapp/ni tartibga soladi. Ikki guruhda bir xil manzil bo'lsa — build xatosi.
Bu darsda
(guruh)papka yaratasiz va URL o'zgarmaganini build jadvali bilan tasdiqlaysiz.- Guruhga layout yoki template berib, uni faqat bir qism sahifalarga qo'llaysiz.
_papkava oddiy colocation farqini tushuntirasiz.- Bir nechta root layout qachon kerakligini va narxini bilasiz.
portfolioni kanondagi tuzilmaga keltirasiz:(sayt)guruhi valoyihalar/_komponentlar/.
Oldin bilishingiz kerak: Navigatsiya, Layout va template, Maxsus fayllar, Fayl-asosli routing.
1. Nega bu kerak?
Holat 06 dagi app/ papkasiga qarang:
src/app/
├── aloqa/page.tsx
├── haqimda/page.tsx
├── loyihalar/
│ ├── [slug]/loading.tsx
│ ├── [slug]/page.tsx
│ └── page.tsx
├── error.tsx
├── global-error.tsx
├── globals.css
├── icon.svg
├── layout.tsx
├── not-found.tsx
├── page.tsx
└── template.tsxIkki xil narsa aralashib ketgan: sahifalar (aloqa, haqimda, page.tsx) va butun ilovaga tegishli fayllar (not-found, global-error, icon.svg). Keyingi darslarda bu ro'yxatga sitemap.ts, robots.ts, opengraph-image.tsx qo'shiladi — tartib yanada buziladi.
Ikkinchi muammo — template.tsx. U Layout va template darsidagi kirish animatsiyasini beradi. Lekin root'da turgani uchun 404 sahifasi ham "uchib kiradi". Xato sahifasiga animatsiya kerakmi? Kanon "yo'q" dedi. Sayt sahifalariga — ha, xizmat sahifalariga — yo'q. Buning uchun sahifalarni bir guruhga ajratib, template'ni faqat o'sha guruhga berish kerak.
Uchinchisi — komponentlar. LoyihaKartasi va TegFiltri faqat «Loyihalar» bo'limida ishlatiladi, lekin umumiy src/komponentlar/ da yotibdi — header bilan yonma-yon.
Papka qo'shsak, URL o'zgaradi: app/sayt/haqimda/ — bu /sayt/haqimda. Bizga esa URL'ga tegmaydigan papka kerak.
Hayotiy o'xshatish: kitob javoni. Kitoblarni rangli qutilarga solib, "badiiy", "darslik" deb belgiladingiz. Kitobning nomi (URL) o'zgarmadi — faqat siz uni topishingiz osonlashdi. Qutining yorlig'i kitob muqovasiga yozilmaydi.
2. Route groups: (guruh)
2.1 Qavs — URL'dan tashqarida
Papka nomini qavsga olsangiz, Next.js uni URL'ga qo'shmaydi. Bu — route group (marshrut guruhi). Kanon sahifalarni app/(sayt)/ ga ko'chirdi:
flowchart LR
A["app/(sayt)/page.tsx"] --> U1["/"]
B["app/(sayt)/haqimda/page.tsx"] --> U2["/haqimda"]
C["app/(sayt)/loyihalar/page.tsx"] --> U3["/loyihalar"]
D["app/not-found.tsx"] --> U4["404 sahifasi"]URL'lar — avvalgidek. Kanon buni build jadvali bilan tasdiqladi: holat 06 va holat 08 jadvallarida /, /aloqa, /haqimda, /loyihalar qatorlari bir xil, (sayt) so'zi jadvalda umuman yo'q.
Biz ham tekshirdik — holat 08 ni next build + next start, keyin curl:
/haqimda -> 200 h1: Men haqimda
/(sayt)/haqimda -> 404 h1: Sahifa topilmadiGuruh nomi bilan manzil yozilsa — 404. Qavs URL'da hech qachon ko'rinmaydi.
2.2 Guruhning o'z layout'i va template'i
Guruh papkasiga ham layout.tsx yoki template.tsx qo'yish mumkin. U faqat shu guruhdagi sahifalarni o'raydi. Kanon template.tsx ni (sayt) ga ko'chirdi:
src/app/
├── (sayt)/
│ ├── template.tsx ← faqat sayt sahifalari
│ ├── page.tsx
│ ├── haqimda/ aloqa/ loyihalar/
├── layout.tsx ← hammasi
├── not-found.tsx ← template'siz
├── error.tsx
└── global-error.tsxEndi kirish animatsiyasi faqat sayt sahifalarida. not-found.tsx va error.tsx root darajada qoldi — ularni template o'ramaydi.
Bu naqshning nomi hujjatda: "opting segments into a layout" — ba'zi segmentlarni layout'ga "yozdirish", qolganlarini tashqarida qoldirish. Masalan, onlayn do'konda (dokon)/ dagi sahifalarda savatcha paneli bor, (kirish)/ dagi login sahifasida esa yo'q.
2.3 Nega header va footer root layout'da qoldi?
Mantiqan header va footer ham "sayt"ga tegishli — ularni (sayt)/layout.tsx ga ko'chirsa bo'lmaydimi? Kanon bunga yo'q dedi, sababi aniq.
Maxsus fayllar darsini eslang: hech bir papkaga mos kelmagan manzil (/yoq) uchun root app/not-found.tsx chiziladi. U root layout ichida chiziladi, lekin (sayt) guruhining layout'iga tushmaydi — /yoq guruh ichidagi hech bir sahifaga mos emas. Header (sayt)/layout.tsx da bo'lsa, 404 sahifasi menyusiz, footer'siz qoladi. Foydalanuvchi adashgan joyda unga eng kerakli narsa — menyu — yo'qoladi.
Qoida: hamma sahifada (404 ham) kerak bo'lgan narsa — root layout'da. Faqat bir guruhga kerak bo'lgani — guruh layout'ida.
Tekshirib ko'ring:
app/(sayt)/template.tsxbor./loyihalar/yoq(noma'lum slug,notFound()chaqiriladi) da animatsiya o'ynaydimi?
Javob
Ha. /loyihalar/yoq (sayt)/loyihalar/[slug]/ ga mos keladi — u guruh ichidagi marshrut, template uni o'raydi. notFound() ning UI'si shu marshrut ichida chiziladi. Template'siz qoladigani — hech bir papkaga mos kelmagan manzillar (/yoq) va root darajadagi xato sahifalari.
2.4 Biz sinadik: ikki guruhda bir xil manzil
Guruh URL'ga kirmagani uchun ikki guruhda bir xil yo'l yozish mumkin bo'lib qoladi: (a)/ikki/page.tsx va (b)/ikki/page.tsx — ikkalasi ham /ikki. Next.js qaysi birini ko'rsatsin? Build:
Error: Turbopack build failed with 1 error:
./src/app/(b)
Error: You cannot have two parallel pages that resolve to the same path. Please check /(a)/ikki and /(b).Tarjimasi: "Bitta manzilga olib keladigan ikkita sahifa bo'lishi mumkin emas. /(a)/ikki va /(b) ni tekshiring". Xabarning oxiri g'alati qisqargan (/(b) — to'liq yo'l emas), lekin yo'nalish aniq: ikkala guruhni qarang. Yechim — bittasini olib tashlash yoki nomini o'zgartirish.
2.5 loading.tsx ni bitta sahifaga cheklash
Route group'ning yana bir kam ma'lum ishlatilishi bor — Next.js hujjatida alohida misol sifatida keltirilgan. Maxsus fayllar darsidan bilasiz: loading.tsx o'z papkasidagi sahifani va hamma ichki papkalarni o'raydi. Faraz qiling, blog ro'yxati sekin ochiladi va unga skelet kerak:
app/blog/
├── loading.tsx ← skelet
├── page.tsx → /blog (sekin)
└── [slug]/page.tsx → /blog/salom (tez, statik)Muammo: loading.tsx endi /blog/salom ni ham o'raydi. Maqoladan maqolaga o'tganda ro'yxat skeleti chaqnab ketishi mumkin — maqolaga umuman o'xshamaydigan rasm.
Yechim — ro'yxat sahifasini va uning skeletini alohida guruhga olish:
app/blog/
├── (royxat)/
│ ├── loading.tsx ← faqat /blog uchun
│ └── page.tsx → /blog
└── [slug]/page.tsx → /blog/salom (skeletsiz)URL'lar o'zgarmadi: (royxat) qavsda. Lekin endi loading.tsx ning "hududi" faqat guruh ichi — [slug] unga kirmaydi. Bitta qoida yana ishladi: maxsus fayl o'z papkasini o'raydi, guruh esa papkani URL'ga ta'sir qilmasdan ajratadi.
portfolio da bunday holat yo'q: blog ro'yxati statik, skelet kerak emas. Lekin katta loyihalarda bu naqsh tez-tez uchraydi — ayniqsa dashboard'larda, bosh sahifa sekin, ichki sahifalar tez bo'lganda.
Tekshirib ko'ring:
app/(sayt)/vaapp/_sayt/— ikkalasi ham URL'ga kirmaydi. Farqi nima?
Javob
(sayt) ichidagi page.tsx lar sahifa bo'ladi — faqat guruh nomisiz URL bilan (/haqimda). _sayt ichidagi hech narsa sahifa bo'lmaydi: private papka butunlay routing'dan tashqarida. Birinchisi — sahifalarni guruhlash uchun, ikkinchisi — sahifa bo'lmagan kodni saqlash uchun.
3. Bir nechta root layout
3.1 Qachon kerak?
Ba'zan saytning ikki qismi butunlay boshqacha: ochiq sayt va admin panel. Har birining o'z <html>, shrifti va CSS'i bo'lishi kerak. Route groups bunga imkon beradi: har guruhda o'z root layout'i, app/layout.tsx esa umuman yo'q.
app/
├── (sayt)/
│ ├── layout.tsx ← <html lang="uz"> + sayt CSS
│ └── page.tsx → /
└── (admin)/
├── layout.tsx ← <html> + admin CSS
└── panel/page.tsx → /panel// app/(admin)/layout.tsx — o'zi root layout
export default function AdminLayout({ children }: LayoutProps<"/">) {
return (
<html lang="uz">
<body className="admin">{children}</body>
</html>
);
}Har ikkala layout <html> va <body> yozadi — ular endi root (Layout va template qoidasi). Bosh sahifa (/) guruhlardan birining ichida bo'lishi shart, aks holda / uchun root layout topilmaydi.
3.2 Narxi: to'liq qayta yuklash
Hujjatdagi muhim ogohlantirish: turli root layout'lar orasida o'tish sahifani to'liq qayta yuklaydi. / dan /panel ga <Link> bilan o'tsangiz ham, brauzer butun sahifani yangidan oladi — Navigatsiya darsidagi prefetch va qayta yuklashsiz o'tish yo'qoladi. Root layout — butun hujjat (<html>), uni almashtirishning boshqa yo'li yo'q.
Shuning uchun bir nechta root layout — kamdan-kam, ataylab tanlov. portfolio da bitta root layout yetarli, kanon uni ishlatmadi.
4. Private papkalar: _papka
4.1 Pastki chiziq — routing'dan tashqari
Papka nomi _ bilan boshlansa, Next.js uni va ichidagi hamma papkalarni routing'dan chiqaradi. Bu — private papka (yopiq papka). Ichida page.tsx bo'lsa ham, u sahifa bo'lmaydi.
Biz tajriba qildik: app/(sayt)/_qoralama/page.tsx yaratdik, build qildik:
/_qoralama -> 404 h1: Sahifa topilmadi
/qoralama -> 404 h1: Sahifa topilmadiBuild jadvalida _qoralama umuman yo'q. Oddiy papkada esa page.tsx darhol sahifa bo'lardi.
4.2 Colocation'dan farqi nima?
Fayl-asosli routing darsida ko'rgandik: page.tsx bo'lmagan papkadagi komponent baribir ochilmaydi (/sinov/Tugma — 404). Unda _ ga nima hojat?
| Oddiy papka (colocation) | _papka |
|
|---|---|---|
Tugma.tsx ochiladimi |
yo'q | yo'q |
Ichiga page.tsx tushib qolsa |
sahifa bo'ladi | sahifa bo'lmaydi |
| Kelajakdagi maxsus nomlar | to'qnashishi mumkin | to'qnashmaydi |
| Muharrirda saralash | aralash | _ lar birga turadi |
Hujjat to'rtta sabab keltiradi: routing va UI mantiqini ajratish, butun loyihada bir xil tartib, muharrirda saralash va kelajakdagi Next.js fayl nomlari bilan to'qnashmaslik. Masalan, komponentlar papkasida loading.tsx degan oddiy komponentingiz bo'lsa — oddiy papkada Next.js uni maxsus fayl deb oladi. _komponentlar/loading.tsx esa xavfsiz.
4.3 Pastki chiziqli URL kerak bo'lsa
Agar URL'ning o'zi _ bilan boshlanishi kerak bo'lsa (/_maxfiy), papka nomini %5Fmaxfiy deb yozasiz: %5F — pastki chiziqning foiz-kodlangan shakli. Kamdan-kam kerak bo'ladi, lekin "nega _ li papkam ochilmayapti?" degan savolga javob shu.
5. Modelda: papka yo'lidan URL
Next.js fayl yo'lidan URL'ni qanday chiqaradi? Soddalashtirilgan model (haqiqiy kod emas), lekin qoidalari yuqoridagi tajribalarga mos:
function fileToUrl(file) {
const parts = file.split("/").slice(1); // "app" ni tashlaymiz
if (parts.at(-1) !== "page.tsx") return null;
const segments = [];
for (const part of parts.slice(0, -1)) {
if (part.startsWith("_")) return null; // private papka
if (part.startsWith("(") && part.endsWith(")")) continue; // guruh
segments.push(part.replace(/^%5F/, "_"));
}
return "/" + segments.join("/");
}
const files = [
"app/(sayt)/page.tsx",
"app/(sayt)/haqimda/page.tsx",
"app/(sayt)/loyihalar/[slug]/page.tsx",
"app/(sayt)/_qoralama/page.tsx",
"app/(sayt)/loyihalar/_komponentlar/TegFiltri.tsx",
"app/%5Fmaxfiy/page.tsx",
];
for (const f of files) console.log(fileToUrl(f), "←", f);Konsolda:
/ ← app/(sayt)/page.tsx
/haqimda ← app/(sayt)/haqimda/page.tsx
/loyihalar/[slug] ← app/(sayt)/loyihalar/[slug]/page.tsx
null ← app/(sayt)/_qoralama/page.tsx
null ← app/(sayt)/loyihalar/_komponentlar/TegFiltri.tsx
/_maxfiy ← app/%5Fmaxfiy/page.tsxUch qoida bir funksiyada: guruh — o'tkazib yuboriladi (continue), private papka — butun yo'l bekor (null), %5F — pastki chiziqqa aylanadi. parts.at(-1) — massivning oxirgi elementi (manfiy indeks oxiridan sanaydi).
6. Loyihani tashkil qilish usullari
Next.js qat'iy tuzilma talab qilmaydi. Hujjat uchta strategiyani ko'rsatadi:
| Usul | Qanday | Qachon qulay |
|---|---|---|
app/ dan tashqarida |
app/ faqat marshrutlar; kod src/komponentlar, src/malumot da |
Kichik va o'rta loyiha |
app/ ichida yuqori papkalar |
app/_komponentlar, app/_lib |
Hammasi bir joyda bo'lsin |
| Bo'lim (feature) bo'yicha | Har bo'lim o'z komponentlari bilan: loyihalar/_komponentlar |
Katta loyiha, ko'p jamoa |
Kanon aralash yo'lni tanladi:
- Butun saytga umumiy narsalar —
src/komponentlar/(SaytSarlavhasi,NavHavola,OrqagaTugmasi) vasrc/malumot/(loyihalar.ts,sana.ts). - Faqat bir bo'limga tegishli — o'sha bo'lim ichida:
app/(sayt)/loyihalar/_komponentlar/(LoyihaKartasi,TegFiltri, keyingi darsdaRasmOynasi).
Qoida oddiy: komponent bitta joyda ishlatilsa — o'sha joyga yaqin; ikki va undan ko'p bo'limda — umumiy papkaga. Bu "feature folders" (bo'lim papkalari) g'oyasi: bo'limni o'chirsangiz, uning hamma kodi birga ketadi.
src/ papkasining o'zi ham ixtiyoriy (Loyiha yaratish darsida --src-dir bilan tanlagandik): u ildizdagi config fayllarni ilova kodidan ajratadi.
Tekshirib ko'ring:
NavHavolaniapp/(sayt)/_komponentlar/ga ko'chirsak bo'ladimi?
Javob
Texnik jihatdan — ha, lekin noto'g'ri joy. NavHavola ni root layout'dagi SaytSarlavhasi ishlatadi, u esa (sayt) guruhidan tashqarida. Root darajadagi fayl guruh ichidagi papkadan import qilsa, tuzilma chalkashadi: "guruhga tegishli" degan va'da buziladi. Umumiy komponent — umumiy papkada (src/komponentlar/).
7. Portfolio qadami: (sayt) guruhi va _komponentlar
Bu dars va keyingi dars portfolio ning holat 08 ini quradi. Commit hali qilmang — u keyingi darsda, modal bilan birga.
7.1 Ko'chirish
git mv bilan ko'chiring — Git o'zgarishni "ko'chirildi" deb taniydi va fayl tarixi uzilmaydi:
mkdir "src/app/(sayt)"
git mv src/app/page.tsx src/app/template.tsx "src/app/(sayt)/"
git mv src/app/haqimda src/app/aloqa src/app/loyihalar "src/app/(sayt)/"
mkdir "src/app/(sayt)/loyihalar/_komponentlar"
cd src/komponentlar
git mv LoyihaKartasi.tsx TegFiltri.tsx \
"../app/(sayt)/loyihalar/_komponentlar/"
cd ../..Qavsli yo'llar qo'shtirnoq ichida: terminalda ( va ) maxsus belgilar. Keyin loyihalar/page.tsx dagi importlar:
-import { LoyihaKartasi } from "@/komponentlar/LoyihaKartasi";
-import { TegFiltri } from "@/komponentlar/TegFiltri";
+import { LoyihaKartasi } from "./_komponentlar/LoyihaKartasi";
+import { TegFiltri } from "./_komponentlar/TegFiltri";Nisbiy import (./) — "bu komponent shu yerniki" degan signal. Umumiy komponentlar @/ bilan qoladi.
7.2 Natija
src/app/
├── (sayt)/
│ ├── loyihalar/
│ │ ├── _komponentlar/ LoyihaKartasi, TegFiltri
│ │ ├── [slug]/ page.tsx, loading.tsx
│ │ └── page.tsx
│ ├── aloqa/ haqimda/
│ ├── page.tsx
│ └── template.tsx
├── error.tsx global-error.tsx not-found.tsx
├── globals.css icon.svg
└── layout.tsxRoot'da faqat ilova darajasidagi fayllar qoldi. Keyingi darslarda sitemap.ts, robots.ts, opengraph-image.tsx ham shu yerga keladi.
npm run build — route jadvali holat 06 dagidek, bitta qator ham o'zgarmagan. Bu — ko'chirish to'g'ri bo'lganining isboti. Endi 404 sahifasini oching: animatsiya yo'q, menyu bor.
8. Ko'p uchraydigan xatolar
| Belgi | Sabab | Davosi |
|---|---|---|
You cannot have two parallel pages that resolve to the same path |
Ikki guruhda bir xil yo'l | Bittasini o'chiring yoki nomlang |
_papka/page.tsx ochilmaydi |
Private papka routing'dan tashqari | Bu kutilgan; URL'da _ kerak bo'lsa — %5F |
| 404 sahifasida menyu yo'q | Header guruh layout'ida | Hamma joyda kerak narsa — root layout'ga |
| Bo'limlar orasida sahifa to'liq qayta yuklanadi | Ikki xil root layout | Bitta root layout yoki bu narxni qabul qiling |
/ 404 qaytaradi |
Ko'p root layout, / hech bir guruhda yo'q |
page.tsx ni guruhlardan biriga |
Komponentlar papkasidagi loading.tsx sahifaga ta'sir qildi |
Oddiy papkada maxsus nom | _komponentlar/ ga oling |
Terminalda syntax error near unexpected token '(' |
Qavsli yo'l qo'shtirnoqsiz | "src/app/(sayt)" |
9. Mashqlar
Mashqlar kurs/mashqlar/23/07-route-groups/ da.
1-mashq (oson): fayldan URL
app/(dokon)/savat/page.tsx→app/(dokon)/(katalog)/kiyim/page.tsx→app/blog/_qismlar/Muallif.tsx→app/blog/(yangilar)/page.tsx→app/%5Fichki/page.tsx→
Yechim
- /savat — guruh URL'ga kirmaydi.
- /kiyim — ichma-ich ikki guruh ham kirmaydi.
- yo'q — private papka va
page.tsxemas. - /blog — guruh ichidagi
page.tsxota segmentning sahifasi bo'ldi. - /_ichki —
%5Fpastki chiziqqa aylanadi.
2-mashq (o'rta): qaysi layout'lar o'raydi?
Funksiya yozing: layoutsFor(page, layouts) — sahifa fayli va loyihadagi layout.tsx fayllari ro'yxatini oladi, sahifani o'raydigan layout'larni tashqaridan ichkariga qaytaradi. Qoida: layout'ning papkasi sahifa papkasining boshlanishi bo'lsa — o'raydi (Layout va template darsidagi "sahifadan ildizgacha" qoidasi). Guruh papkalari ham hisobga olinadi — URL emas, fayl yo'li muhim. Ishora: slice(0, -"layout.tsx".length) bilan papka yo'lini oling va startsWith bilan solishtiring.
Sinov: layouts = ["app/layout.tsx", "app/(sayt)/layout.tsx", "app/(admin)/layout.tsx", "app/(sayt)/loyihalar/layout.tsx"], sahifalar app/(sayt)/loyihalar/[slug]/page.tsx va app/(admin)/panel/page.tsx.
Yechim
function layoutsFor(page, layouts) {
const dir = page.slice(0, -"page.tsx".length);
return layouts
.filter((l) => dir.startsWith(l.slice(0, -"layout.tsx".length)))
.sort((a, b) => a.length - b.length);
}
const layouts = [
"app/layout.tsx",
"app/(sayt)/layout.tsx",
"app/(admin)/layout.tsx",
"app/(sayt)/loyihalar/layout.tsx",
];
const show = (page) =>
console.log(layoutsFor(page, layouts).join(" > "));
show("app/(sayt)/loyihalar/[slug]/page.tsx");
show("app/(admin)/panel/page.tsx");Konsolda:
app/layout.tsx > app/(sayt)/layout.tsx > app/(sayt)/loyihalar/layout.tsx
app/layout.tsx > app/(admin)/layout.tsxIkkala sahifaning URL'ida guruh yo'q (/loyihalar/…, /panel), lekin o'raydigan layout'lar har xil — chunki fayl yo'llari har xil. Route group'ning butun kuchi shu: URL bir xil tekislikda, layout'lar esa guruhga qarab. Saralash uzunlik bo'yicha: qisqa yo'l — tashqi layout.
3-mashq (qiyin): to'qnashuvni toping
Build xatosini o'zingiz yozing: findConflicts(files) — sahifa fayllari ro'yxatidan bir xil URLga tushadiganlarini topadi va "/ikki: app/(a)/ikki/page.tsx, app/(b)/ikki/page.tsx" ko'rinishidagi satrlar massivini qaytaradi. URL'ni «Modelda: papka yo'lidan URL» bo'limidagi fileToUrl hisoblaydi (null lar o'tkaziladi). Ishora: Map — kalit URL, qiymat fayllar massivi (Map).
Yechim
function fileToUrl(file) {
const parts = file.split("/").slice(1);
if (parts.at(-1) !== "page.tsx") return null;
const segments = [];
for (const part of parts.slice(0, -1)) {
if (part.startsWith("_")) return null;
if (part.startsWith("(") && part.endsWith(")")) continue;
segments.push(part.replace(/^%5F/, "_"));
}
return "/" + segments.join("/");
}
function findConflicts(files) {
const byUrl = new Map();
for (const file of files) {
const url = fileToUrl(file);
if (url === null) continue;
byUrl.set(url, [...(byUrl.get(url) ?? []), file]);
}
return [...byUrl]
.filter(([, list]) => list.length > 1)
.map(([url, list]) => `${url}: ${list.join(", ")}`);
}
console.log(
findConflicts([
"app/(a)/ikki/page.tsx",
"app/(b)/ikki/page.tsx",
"app/(sayt)/page.tsx",
"app/page.tsx",
"app/_eski/ikki/page.tsx",
"app/haqimda/page.tsx",
]),
);Konsolda:
[
'/ikki: app/(a)/ikki/page.tsx, app/(b)/ikki/page.tsx',
'/: app/(sayt)/page.tsx, app/page.tsx'
]Ikkinchi to'qnashuv kutilmagan bo'lishi mumkin: app/page.tsx va app/(sayt)/page.tsx — ikkalasi ham /. Sahifalarni guruhga ko'chirib, eski app/page.tsx ni o'chirishni unutish — aynan shunday xato beradi. _eski/ikki esa to'qnashmadi: private papka routing'da yo'q.
4-mashq: Portfolio qadami
O'z portfolio ingizda sahifalar va template.tsx ni (sayt) guruhiga, faqat «Loyihalar» bo'limida ishlatiladigan komponentlarni loyihalar/_komponentlar/ ga ko'chiring (git mv bilan). Importlarni tuzating. Tekshiring: npm run build jadvali avvalgidek bo'lishi kerak; /yoq da menyu bor, kirish animatsiyasi yo'q.
Yechim
Namuna — «Portfolio qadami» bo'limidagi buyruqlar va daraxt. Build jadvali o'zgargan bo'lsa (yangi yoki yo'qolgan qator) — biror sahifa noto'g'ri joyga tushgan yoki eski fayl qolgan: 3-mashqdagi kabi to'qnashuvni qidiring. git status da fayllar renamed: deb ko'rinishi kerak — bu git mv tarixni saqlaganini bildiradi. Commit hali qilmang: keyingi darsda modal bilan birga.
10. Real ishda
- Marketing va ilova — eng ko'p uchraydigan juftlik:
(marketing)/(bosh sahifa, narxlar, blog — SEO kerak) va(app)/(kirgan foydalanuvchi paneli). Har birining o'z layout'i, ba'zan o'z root layout'i. (auth)guruhi — kirish va ro'yxatdan o'tish sahifalari menyusiz, oddiy layout bilan. Sahifalar/login,/registerbo'lib qoladi.- Katta jamoalar guruhlarni jamoa bo'yicha ham bo'ladi:
(tolov)/,(profil)/— har jamoa o'z papkasida ishlaydi, URL'lar tekis qoladi. - Private papkalar — kod tekshiruvida (code review) "nega komponent
app/ichida?" degan savolga javob:_— "bu marshrut emas" degan aniq belgi.
Xulosa
(guruh)— URL'ga kirmaydi; sahifalarni guruhlab, guruhga o'z layout/template'ini berish uchun.- Hamma sahifaga (404 ham) kerak narsa — root layout'da; guruh layout'i mos kelmagan manzilni o'ramaydi.
- Ikki guruhda bir xil URL — build xatosi; har guruhda o'z root layout'i bo'lsa, ular orasida o'tish to'liq qayta yuklanadi.
_papka— butunlay routing'dan tashqari, ichidagipage.tsxham; URL'da_kerak bo'lsa —%5F.- Komponent bir bo'limniki bo'lsa — o'sha bo'lim yonida (
_komponentlar), umumiy bo'lsa —src/komponentlar.
Keyingi dars: Parallel va intercepting routes — @modal slot va (.) bilan loyiha rasmini URL'li modal oynada ochamiz.
Manbalar
- Next.js hujjati — Route Groups: https://nextjs.org/docs/app/api-reference/file-conventions/route-groups (next 16.4.0 paketi ichidagi hujjat, 2026-10-21 da o'qildi)
- Next.js hujjati — Project structure: Private folders, Organizing your project: https://nextjs.org/docs/app/getting-started/project-structure
- Kanon o'lchovlari:
portfoliov2, holat 06 → 08 (route jadvali bir xil). Guruhlar to'qnashuvi,_qoralamava/(sayt)/haqimdatajribasi — biz ishga tushirdik (next 16.4.0,next build+next start).
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!