Mundarija (36)
- Bu darsda
- 1. Nega bu kerak?
- 2. Maxsus fayllar ierarxiyasi
- 2.1 Qaysi fayl nimani o'raydi
- 2.2 notFound() — bu ham xato
- 3. not-found.tsx va 404 statusi
- 3.1 Kanondagi fayl
- 3.2 [slug] da notFound()
- 3.3 Biz topdik: noma'lum slug — birinchi so'rovda 200
- 4. error.tsx — segment uchun xato chegarasi
- 4.1 Kanondagi fayl
- 4.2 Nega "use client" majburiy?
- 4.3 Biz sinadik: prod'da xato matni yashiriladi
- 4.4 Status — 200
- 4.5 retry va reset
- 4.6 Natija oynasida: error.tsx modeli
- 5. global-error.tsx — root layout yiqilganda
- 6. loading.tsx — avtomatik Suspense
- 6.1 Kanondagi fayl
- 6.2 Qachon ko'rinadi?
- 6.3 Natija oynasida: loading.tsx = Suspense
- 7. Boshqa maxsus fayllar
- 7.1 forbidden.tsx va unauthorized.tsx
- 7.2 Qolganlari — xarita
- 8. Portfolio qadami: xato va topilmadi sahifalari
- 8.1 Fayllar
- 8.2 Kanon o'lchovi (holat 06)
- 9. Ko'p uchraydigan xatolar
- 10. Mashqlar
- 1-mashq (oson): qaysi fayl?
- 2-mashq (o'rta): ierarxiyani chizing
- 3-mashq (qiyin): notFound va xatoni ajratadigan xato chegarasi
- 4-mashq: Portfolio qadami
- 11. Real ishda
- Xulosa
- Manbalar
Next.js maxsus fayllari: loading.tsx, error.tsx, not-found.tsx va boshqalar
Qisqacha: Next.js'da ba'zi fayl nomlari maxsus: papkaga
loading.tsxqo'ysangiz — sahifa atrofida avtomatik<Suspense>,error.tsx— avtomatik xato chegarasi (error boundary),not-found.tsx— "topilmadi" sahifasi bo'ladi. Siz faqat komponent yozasiz, o'rash ishini Next.js o'zi qiladi.notFound()funksiyasi shu sahifani chaqiradi va 404 statusini qaytaradi.error.tsxdoim client komponent bo'ladi va production'da server xatosining matnini ko'rmaydi — faqatdigestkodini. Root layout'ning o'zi yiqilsa,global-error.tsxishlaydi.
Bu darsda
not-found.tsxyozasiz vanotFound()bilan/loyihalar/yoqga 404 qaytarasiz.error.tsxningerror,digestvaretryqismlarini haqiqiy prod va dev natijasi bilan tushuntirasiz.- Maxsus fayllar qaysi tartibda ichma-ich o'ralishini chizib bera olasiz.
loading.tsxqachon ko'rinishini va qachon ko'rinmasligini bilasiz.- Next 16.4 dagi halol topilmani ko'rasiz: noma'lum slug birinchi so'rovda baribir 200.
Oldin bilishingiz kerak: Layout va template, Error boundary, Suspense, Fayl-asosli routing.
1. Nega bu kerak?
Fayl-asosli routing darsida tashvishli bir qator qolgan edi: /loyihalar/yoq — mavjud bo'lmagan loyiha — 200 statusi bilan "Loyiha topilmadi" deydi. Odamga to'g'ri ko'rinadi, Google uchun esa bu oddiy sahifa (soft 404).
Yana ikki muammo bor. /yoq kabi umuman yo'q manzilda Next.js'ning standart inglizcha sahifasi chiqadi: "404: This page could not be found." Kanon tekshiruvida unda 3 ta axe buzilishi topilgan (main yo'q). Va agar sahifa ichida xato bo'lsa (masalan GitHub API javob bermasa), foydalanuvchi nima ko'radi? Hozircha — hech qanday rejamiz yo'q.
React'da bularning hammasini bilasiz. Error boundary — xatoni ushlab, o'rniga zaxira UI ko'rsatadigan komponent. Bu qismda uni o'zbekcha xato chegarasi deymiz. Ehtiyot bo'ling: keyingi darslarda yana bir "chegara" chiqadi — "use client" qo'yilgan client chegarasi. Ular boshqa-boshqa narsa. Suspense — kutish paytida fallback ko'rsatadi. 18-qismda ularni qo'lda yozib, kerakli joyga o'ragandingiz.
Next.js shu ishni fayl nomi bilan qiladi. Papkaga error.tsx qo'ydingizmi — shu papkadagi sahifa xato chegarasi bilan o'raladi. loading.tsx — Suspense bilan. Siz faqat "xato bo'lsa nima ko'rinsin" degan komponentni yozasiz.
Hayotiy o'xshatish: mehmonxona. Xonalar — sahifalar. Har qavatda navbatchi (xato chegarasi) bor: xonada muammo bo'lsa, butun mehmonxonani yopmaydi, faqat o'sha qavatda "ta'mirlanmoqda" belgisini qo'yadi. Qabulxonada esa "bunday xona yo'q" (not-found) va "xonangiz tayyorlanmoqda" (loading) javoblari tayyor turadi.
2. Maxsus fayllar ierarxiyasi
2.1 Qaysi fayl nimani o'raydi
Bitta papka (segment) ichidagi maxsus fayllar Next.js tomonidan doim bir xil tartibda ichma-ich qo'yiladi. Next.js hujjatidagi tartib:
flowchart TB
L["layout.tsx"] --> T["template.tsx"]
T --> E["error.tsx — xato chegarasi"]
E --> S["loading.tsx — Suspense"]
S --> N["not-found.tsx — 404 UI"]
N --> P["page.tsx yoki ichki layout"]JSX'da yozsak, app/loyihalar/[slug]/ segmenti taxminan shunday chiziladi:
<Layout>
<Template>
<ErrorBoundary fallback={<Error />}>
<Suspense fallback={<Loading />}>
<NotFoundBoundary fallback={<NotFound />}>
<Page />
</NotFoundBoundary>
</Suspense>
</ErrorBoundary>
</Template>
</Layout>Bu — soddalashtirilgan rasm, Next.js'ning haqiqiy kodi emas. Lekin g'oyasi aynan shu: siz yozgan oddiy komponentlar React'ning tanish o'rovchilariga (xato chegarasi, Suspense) fallback bo'lib tushadi.
Ikki muhim xulosa:
error.tsxo'z papkasidagilayout.tsxni ushlamaydi — layout xato chegarasidan tashqarida turibdi. Layout'dagi xatoni ota papkadagierror.tsxushlaydi. Root layout'ning esa otasi yo'q — ungaglobal-error.tsxkerak.- Ichma-ich papkalarda bu zanjir takrorlanadi: bola segmentning hamma fayllari ota segment
page.tsxturgan joyga tushadi. Xato eng yaqinerror.tsxda ushlanadi.
Tekshirib ko'ring:
app/loyihalar/layout.tsxichida xato chiqdi.app/loyihalar/error.tsxuni ushlaydimi?
Javob
Yo'q. error.tsx o'z segmentining layout'i ichida turadi, uni o'ramaydi. Xatoni ota segmentdagi (app/error.tsx) xato chegarasi ushlaydi.
2.2 notFound() — bu ham xato
notFound() funksiyasi next/navigation dan keladi. Chaqirilganda u xato tashlaydi, ya'ni funksiyaning qolgan qismi bajarilmaydi. Next.js bu xatoni ichidagi maxsus digest maydonidan taniydi va error.tsx ga emas, not-found.tsx ga yo'naltiradi.
Natija oynasidagi next/navigation — o'quv modeli (Fayl-asosli routing darsida aytilgan), lekin u xatoni Next.js'dagi matn bilan tashlaydi. Bosing va ichiga qarang:
import { notFound } from "next/navigation";
export default function App() {
function check() {
try {
notFound();
console.log("bu qator bajarilmaydi");
} catch (error) {
const e = error as Error & { digest?: string };
console.log("message:", e.message);
console.log("digest:", e.digest);
}
}
return <button onClick={check}>Tekshir</button>;
}Konsolda:
message: NEXT_HTTP_ERROR_FALLBACK;404
digest: NEXT_HTTP_ERROR_FALLBACK;404notFound() dan keyingi qator ishlamadi — throw dagidek. Ikkita xulosa:
notFound()dan keyinreturnyozish shart emas. Kanon kodidaif (!loyiha) notFound();— va pastdagi kodloyihani bemalol ishlatadi. TypeScript ham buni biladi:notFoundturineverqaytaradi.try/catchichida chaqirmang. O'zcatchingiz uni oddiy xato deb yutib yuboradi va Next.js 404 ni ko'rmaydi.redirect()ham xuddi shunday ishlaydi (Navigatsiya darsida).
3. not-found.tsx va 404 statusi
3.1 Kanondagi fayl
app/not-found.tsx — v1 dagi 404 sahifasi ning Next.js versiyasi: yo'l ko'rsatuvchi havolalar va «Orqaga» tugmasi.
import type { Metadata } from "next";
import Link from "next/link";
import { OrqagaTugmasi } from "@/komponentlar/OrqagaTugmasi";
export const metadata: Metadata = { title: "Sahifa topilmadi — Aziz Karimov" };
// v1 dagi 404.html (04/86): yo'l ko'rsatuvchi havolalar.
// 404 statusda Next `noindex` ni o'zi qo'shadi.
export default function TopilmadiSahifasi() {
return (
<main id="asosiy">
<h1>Sahifa topilmadi</h1>
<p>Manzil noto'g'ri yoki sahifa ko'chirilgan bo'lishi mumkin.</p>
<ul>
<li>
<Link href="/">Bosh sahifa</Link>
</li>
<li>
<Link href="/loyihalar">Loyihalar</Link>
</li>
<li>
<Link href="/aloqa">Aloqa</Link>
</li>
</ul>
<p>
<OrqagaTugmasi />
</p>
</main>
);
}Kanondagi uzun izoh telefonga sig'ishi uchun ikki qatorga bo'lindi. metadata qatori kanonda aynan shunday (70 belgidan uzun). OrqagaTugmasi — router.back() chaqiradigan kichik client komponent, uni keyingi darsda ochamiz.
app/not-found.tsx ikki holatda chiziladi:
| Holat | Misol |
|---|---|
| Hech bir papkaga mos kelmagan manzil | /yoq, /blog/eski |
Sahifa notFound() chaqirdi |
/loyihalar/yoq |
Birinchi holat faqat root darajadagi app/not-found.tsx bilan ishlaydi. Ichki papkadagi not-found.tsx (masalan app/loyihalar/not-found.tsx) faqat o'sha papka ichida notFound() chaqirilganda ko'rinadi.
3.2 [slug] da notFound()
Fayl-asosli routing darsidagi "Loyiha topilmadi" bloki endi bitta qator:
const { slug } = await params;
const loyiha = loyihaniTop(slug);
// notFound() — eng yaqin not-found.tsx ni ko'rsatadi
// va 404 qaytaradi (N-05)
if (!loyiha) notFound();
const cs = loyiha.caseStudy;Biz next build + next start bilan tekshirdik (curl -D -, faqat kerakli sarlavhalar):
== /yoq
HTTP/1.1 404 Not Found
<meta name="robots" content="noindex"/>404 statusi va noindex meta tegi — ikkalasi ham bor. noindex ni biz yozmadik: Next.js 404 sahifasiga uni o'zi qo'shadi. Google bunday sahifani indeksga olmaydi.
3.3 Biz topdik: noma'lum slug — birinchi so'rovda 200
Endi /loyihalar/yoq9 — [slug] papkasiga tushadigan, lekin ro'yxatda yo'q loyiha. Bir xil manzilni ikki marta so'radik:
== /loyihalar/yoq9
HTTP/1.1 200 OK
x-nextjs-postponed: 1
<meta name="robots" content="noindex"/>
== /loyihalar/yoq9
HTTP/1.1 404 Not Found
x-nextjs-cache: HIT
<meta name="robots" content="noindex"/>Birinchi so'rov — 200, ikkinchisi — 404. Kanon xuddi shuni topgan: har yangi noma'lum slug'ning birinchi so'rovi 200, keyingilari 404.
Nega? Fayl-asosli routing darsidagi build jadvalini eslang: ◐ /loyihalar/[slug] — PPR qobig'i (qisman prerender). Noma'lum slug kelganda Next.js avval tayyor qobiqni oqim (streaming) bilan yubora boshlaydi. HTTP statusi esa javobning eng boshida, sarlavhalar bilan ketadi. Sahifa notFound() ga yetganda status allaqachon 200 deb yuborilgan — uni qaytarib bo'lmaydi.
Next.js hujjati buni ochiq yozadi: oqim boshlangach status 200 qoladi, shuning uchun Next.js HTML ichiga noindex qo'yadi. Google sahifani indekslamaydi — bu yaxshi. Lekin status baribir 200, ba'zi botlar va analitika vositalari uni "soft 404" deb belgilaydi.
Next 15 dagi eski yechim — export const dynamicParams = false ("ro'yxatdan boshqa slug yo'q"). Kanon uni sinadi:
Error: Route segment config "dynamicParams" is not compatible with `nextConfig.cacheComponents`. Please remove it.Tarjimasi: "dynamicParams segment sozlamasi Cache Components bilan mos emas, olib tashlang". Kanon loading.tsx ni olib tashlab ham ko'rdi — natija o'zgarmadi: ◐ qobiq baribir oqim bilan ketadi.
Halol xulosa: hozircha Google uchun noindex yetarli, lekin status 200. Haqiqiy 404 ni oqim boshlanishidan oldin berish kerak — so'rov sahifaga yetmasdan. Buni proxy.ts darsida qilamiz.
Tekshirib ko'ring:
/loyihalar/yoqva/yoqning birinchi so'rovi qaysi statusni qaytaradi? Nega har xil?
Javob
/loyihalar/yoq — 200 (keyin 404), /yoq — darhol 404. /yoq hech qanday papkaga mos kelmaydi: Next.js oqim boshlamasdan 404 javobini beradi. /loyihalar/yoq esa [slug] qobig'iga tushadi, oqim boshlanadi, notFound() keyinroq chaqiriladi.
4. error.tsx — segment uchun xato chegarasi
4.1 Kanondagi fayl
"use client";
import { useEffect } from "react";
// Xato chegarasi faqat Client Component bo'la oladi (N-05).
// Prod'da server xatosining matni yashiriladi — faqat digest.
export default function XatoSahifasi({
error,
retry,
}: {
error: Error & { digest?: string };
retry: () => void;
}) {
useEffect(() => {
console.error(error);
}, [error]);
return (
<main id="asosiy">
<h1>Nimadir buzildi</h1>
<p>Sahifani ko'rsatib bo'lmadi. Qayta urinib ko'ring.</p>
{error.digest && <p className="ikkinchi">Xato kodi: {error.digest}</p>}
<button type="button" onClick={() => retry()}>
Qayta urinish
</button>
</main>
);
}Uchta qism:
| Qism | Nima |
|---|---|
"use client" |
Fayl brauzerda ham ishlaydigan komponent — majburiy |
error |
Ushlangan xato; digest — server xatosining kodi |
retry |
"Qayta urinib ko'r" funksiyasi |
4.2 Nega "use client" majburiy?
Error boundary darsidan eslang: React'da xato chegarasi — klass komponent, u getDerivedStateFromError bilan holat saqlaydi. Holat va onClick faqat brauzerda yashaydigan komponentda bo'ladi. Next.js'da sukut bo'yicha hamma komponent serverda ishlaydi, shuning uchun error.tsx ni brauzerga "ruxsat berish" kerak — "use client" qatori aynan shuni qiladi. To'liq ma'nosini Client Components darsida ochamiz.
Biz "use client" ni olib tashlab, build qildik (ranglar va kod parchasi olib tashlangan):
Error: Turbopack build failed with 2 errors:
./src/app/error.tsx:1:10
Error: You're importing a module that depends on `useEffect` into a React Server Component module. This API is only available in Client Components. To fix, mark the file (or its parent) with the `"use client"` directive.
./src/app/error.tsx:1:1
Error: src/app/error.tsx must be a Client Component. Add the "use client" directive the top of the file to resolve this issue.Ikkinchi xato aniqroq: "src/app/error.tsx Client Component bo'lishi shart. Fayl boshiga "use client" direktivasini qo'shing". Birinchisi — useEffect ning oqibati: hook'lar serverda ishlamaydi. useEffect bo'lmasa ham, ikkinchi xato baribir chiqadi.
4.3 Biz sinadik: prod'da xato matni yashiriladi
error.tsx qanday ishlashini ko'rish uchun tajriba sahifasi yasadik. Unda GitHub blokini taqlid qiladigan komponent xato tashlaydi, va xato matnida "maxfiy" ma'lumot bor:
async function GithubBlok() {
await connection(); // har so'rovda ishlasin (N-14)
if (Date.now() > 0) {
throw new Error("GitHub API javob bermadi (kalit: maxfiy-123)");
}
return <p>Profil</p>;
}connection() va Date.now() > 0 — tajriba uchun hiyla: birinchisi build vaqtida ishlamasligi uchun (Rendering strategiyalari darsida), ikkinchisi TypeScript "funksiya hech narsa qaytarmaydi" demasligi uchun.
next build + next start, keyin headless Chrome'da sahifani ochdik. Ekranda:
Nimadir buzildi | Sahifani ko'rsatib bo'lmadi. Qayta urinib ko'ring. | Xato kodi: 2204450643 | Qayta urinishBrauzer konsolida (useEffect dagi console.error):
Error: Minified React error #441; visit https://react.dev/errors/441 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.Serverning terminalida esa:
⨯ Error: GitHub API javob bermadi (kalit: maxfiy-123)
at e (C:\Users\…\.next\server\chunks\ssr\_0j0xk8vpm9llx._.js:30:15768) {
digest: '2204450643'
}Mana digest ning vazifasi. Brauzer xatoning asl matnini olmadi — HTML'da ham maxfiy-123 yo'q, faqat {"digest":"2204450643"}. Asl matn faqat server logida, va ikkalasini bir xil kod bog'laydi. Foydalanuvchi "Xato kodi: 2204450643" ni sizga yuborsa, siz logdan aynan shu xatoni topasiz.
#441 — React production build'idagi qisqartirilgan xato raqami. Havoladagi sahifa 2026-10 holatida ochilmaydi (404), shuning uchun to'liq matnni React manba kodidagi xato kodlari ro'yxatidan oldik (scripts/error-codes/codes.json): "An error occurred in the Server Components render. The specific message is omitted in production builds to avoid leaking sensitive details. A digest property is included on this error instance which may provide additional details about the nature of the error." — "Server Components renderida xato bo'ldi. Aniq matn production'da maxfiy ma'lumot sizib chiqmasligi uchun olib tashlangan. Xato obyektida digest xususiyati bor — u xato haqida qo'shimcha ma'lumot berishi mumkin".
next dev da esa o'sha sahifa brauzer konsoliga asl matnni chiqardi:
Error: GitHub API javob bermadi (kalit: maxfiy-123)Dev — siz uchun, prod — foydalanuvchi uchun. Shuning uchun error.tsx da error.message ni ekranga chiqarmang: dev'da ko'rinadi, prod'da baribir umumiy matn bo'ladi. Client komponentda (brauzerda) tashlangan xatoning matni esa prod'da ham saqlanadi — u allaqachon brauzerda.
4.4 Status — 200
Tajriba sahifasining statusi — 200. Xato oqim boshlangandan keyin, <Suspense> ichida chiqdi — «Noma'lum slug — birinchi so'rovda 200» bo'limidagi sabab bilan bir xil. Xato sahifasini Google indekslamasligi uchun muhim sahifalarda xatoni oqimdan oldin tekshirish kerak. Portfolio uchun bu kichik masala: GitHub bloki yiqilsa, sahifaning qolgan qismi baribir foydali.
4.5 retry va reset
Next 16.4 da error.tsx ikki funksiya oladi:
| Funksiya | Nima qiladi |
|---|---|
retry() |
Segmentni serverdan qayta oladi va qayta chizadi |
reset() |
Faqat xato holatini tozalaydi, serverga so'rov yo'q |
Hujjat ko'p hollarda retry() ni tavsiya qiladi. Xato vaqtinchalik bo'lsa (tarmoq uzildi, API band edi), yangi so'rov uni hal qilishi mumkin. reset() — eski kitob va maqolalardagi nom; u ma'lumotni qayta olmaydi, faqat xato chegarasini qayta chizadi. retry Next 16.2 da unstable_retry nomi bilan kirgan, 16.3 da barqaror bo'lgan (hujjatdagi versiyalar tarixi).
Bizning tajribada «Qayta urinish» bosilganda server yana xato tashladi, ekran o'zgarmadi — chunki xato doimiy edi. Haqiqiy vaqtinchalik xatoda ikkinchi urinish o'tishi mumkin.
4.6 Natija oynasida: error.tsx modeli
error.tsx ichida nima bo'layotganini oddiy React bilan qayta qurish mumkin — bu Error boundary darsidagi klass komponent. fallback o'rniga Next.js'dagidek funksiya beramiz: u error va retry ni oladi. retry holatni tozalaydi va bolani qayta chizadi.
import { Component, type ReactNode } from "react";
type Fallback = (p: {
error: Error;
retry: () => void;
}) => ReactNode;
class ErrorBoundary extends Component<
{ fallback: Fallback; children: ReactNode },
{ error: Error | null }
> {
state = { error: null as Error | null };
static getDerivedStateFromError(error: Error) {
return { error };
}
retry = () => this.setState({ error: null });
render() {
const { error } = this.state;
if (!error) return this.props.children;
return this.props.fallback({ error, retry: this.retry });
}
}
// "tarmoq": birinchi urinishda uzilgan, keyin tiklanadi
const network = { up: false };
function GithubBlock() {
if (!network.up) throw new Error("GitHub API javob bermadi");
return <p>Profil yuklandi</p>;
}
function ErrorPage({ error, retry }: Parameters<Fallback>[0]) {
return (
<>
<h1>Nimadir buzildi</h1>
<p>{error.message}</p>
<button
onClick={() => {
network.up = true; // tarmoq tiklandi
retry();
}}
>
Qayta urinish
</button>
</>
);
}
export default function App() {
return (
<ErrorBoundary fallback={(p) => <ErrorPage {...p} />}>
<GithubBlock />
</ErrorBoundary>
);
}Konsolda:
Error: GitHub API javob bermadi
The above error occurred in the <GithubBlock> component.
React will try to recreate this component tree from scratch using the error boundary you provided, ErrorBoundary.Ekranda:
Profil yuklandiBirinchi chizishda GithubBlock xato tashladi, xato chegarasi ErrorPage ni ko'rsatdi. Konsoldagi uch qator — React'ning o'zi: ushlangan xatoni ham dev rejimda konsolga yozadi va qaysi xato chegarasi ushlaganini aytadi ("React bu daraxtni siz bergan ErrorBoundary chegarasi yordamida noldan qayta yaratadi"). «Qayta urinish» bosilgach "tarmoq tiklandi", retry holatni tozaladi, GithubBlock qayta chizildi va endi o'tdi. Haqiqiy retry() bundan bir qadam ko'p ishlaydi — serverdan yangi ma'lumot ham so'raydi.
E'tibor bering: bu modelda error.message ekranga chiqdi, chunki xato brauzerda tashlandi. Server xatosida prod'da u yerda umumiy matn bo'lardi.
Tekshirib ko'ring: foydalanuvchi «Saqlash» tugmasini bosdi va
onClickichida xato chiqdi.error.tsxuni ushlaydimi?
Javob
Yo'q. Xato chegarasi faqat chizish (render) paytidagi xatolarni ushlaydi — Error boundary darsidagi qoida. Hodisa ichidagi xatoni try/catch bilan o'zingiz ushlaysiz va holat orqali ko'rsatasiz.
5. global-error.tsx — root layout yiqilganda
app/error.tsx root layout'ning ichida turadi (ierarxiya rasmini eslang). Root layout'ning o'zida xato bo'lsa, uni ushlaydigan hech kim yo'q. Shu holat uchun app/global-error.tsx:
"use client";
// Root layout'ning o'zi yiqilganda — o'z <html> va <body> si
// bilan (N-05). globals.css bu yerda yo'q, shuning uchun oddiy.
export default function GlobalXato({
retry,
}: {
error: Error & { digest?: string };
retry: () => void;
}) {
return (
<html lang="uz">
<body>
<main>
<h1>Sayt vaqtincha ishlamayapti</h1>
<button type="button" onClick={() => retry()}>
Qayta urinish
</button>
</main>
</body>
</html>
);
}Uch farq:
- O'z
<html>va<body>si. U root layout'ning o'rniga chiziladi — root layout yo'q, demak Layout va template darsidagi qoida bo'yicha bu teglarni kim yozadi? Faqat o'zi. globals.cssyo'q. Sayt stillari root layout'da ulangan, u esa yiqilgan. Kanon sahifani ataylab oddiy qoldirdi.metadataeksporti ishlamaydi — fayl client komponent. Sarlavha kerak bo'lsa,<title>tegini to'g'ridan JSX ichida yozish mumkin.
global-error.tsx kamdan-kam ko'rinadi. Lekin u bo'lmasa, root layout xatosida foydalanuvchi Next.js'ning inglizcha standart sahifasini ko'radi.
6. loading.tsx — avtomatik Suspense
6.1 Kanondagi fayl
// loading.tsx — sahifa atrofida avtomatik <Suspense> (N-05).
// Faqat build vaqtida yaratilmagan slug'da ko'rinadi.
export default function LoyihaYuklanmoqda() {
return (
<main id="asosiy" aria-busy="true">
<h1>Loyiha yuklanmoqda…</h1>
</main>
);
}aria-busy="true" — ekran o'quvchiga "bu qism hali tayyorlanmoqda" degan signal. loading.tsx — oddiy Server Component, "use client" shart emas.
6.2 Qachon ko'rinadi?
Kanon izohidagi gapga e'tibor bering: "faqat build vaqtida yaratilmagan slug'da". /loyihalar/vazifalar — ○ statik, HTML tayyor, kutadigan narsa yo'q. Suspense fallback'i bir lahza ham chiqmaydi.
/loyihalar/yoq9 kabi noma'lum slug'da esa sahifa ◐ qobiqdan chiziladi. Qobiqning bir qismi aynan shu loading.tsx: Next.js uni build vaqtida tayyorlab qo'yadi va so'rov kelganda darhol yuboradi. Sahifaning o'zi tayyor bo'lgach, fallback almashadi.
Navigatsiyada yana bir foyda bor. <Link> sahifani oldindan yuklaganda (prefetch, Navigatsiya darsida), dinamik sahifa uchun loading.tsx gacha bo'lgan qismni oladi. Bosish bilanoq ekran o'zgaradi — foydalanuvchi "bosdim, hech narsa bo'lmadi" deb qolmaydi.
6.3 Natija oynasida: loading.tsx = Suspense
loading.tsx ning ishi — Suspense darsidagi fallback. Promise'ni use() bilan o'qiydigan sahifa va uning atrofida Next.js qo'yadigan Suspense chegarasi:
import { Suspense, use } from "react";
type Project = { name: string };
const projectPromise = new Promise<Project>((resolve) =>
setTimeout(() => resolve({ name: "Vazifalar ilovasi" }), 400),
);
// app/loyihalar/[slug]/page.tsx o'rnida
function ProjectPage() {
const project = use(projectPromise);
return <h1>{project.name}</h1>;
}
// app/loyihalar/[slug]/loading.tsx o'rnida
function Loading() {
return <h1>Loyiha yuklanmoqda…</h1>;
}
export default function App() {
return (
<Suspense fallback={<Loading />}>
<ProjectPage />
</Suspense>
);
}Ekranda:
Vazifalar ilovasiekran("Loyiha yuklanmoqda") qadami oraliq holatni tekshiradi: avval fallback, 400 ms dan keyin sahifa. Next.js'da <Suspense> ni siz yozmaysiz — loading.tsx faylining o'zi shu.
Bir farq bor. Bu yerda promise brauzerda kutilyapti. Next.js'da sahifa serverda kutadi, fallback HTML'ning birinchi bo'lagida ketadi, sahifa esa keyingi bo'lakda keladi. Bu oqimni Streaming va Suspense darsida o'lchaymiz.
Tekshirib ko'ring:
app/loading.tsx(root'da) qo'ysangiz, u qaysi sahifalarga ta'sir qiladi?
Javob
Hammasiga: root segmentdagi Suspense butun app/ ni o'raydi. Lekin statik sahifalarda u baribir ko'rinmaydi — kutish yo'q. Odatda loading.tsx ni aniq sekin bo'lishi mumkin bo'lgan segmentga qo'yish yaxshiroq: shunda layout'ning qolgan qismi (menyu) darhol ko'rinadi.
7. Boshqa maxsus fayllar
7.1 forbidden.tsx va unauthorized.tsx
notFound() ning ikki aka-ukasi bor: forbidden() (403 — "ruxsat yo'q") va unauthorized() (401 — "avval kiring"). Ularning UI fayli — forbidden.tsx va unauthorized.tsx. Ular hali eksperimental: next.config.ts da experimental.authInterrupts: true yoqilishi kerak (hujjat, 2026-10-21). Kanonda kirish (login) yo'q, shuning uchun ular ishlatilmagan.
// next.config.ts: experimental: { authInterrupts: true }
import { forbidden } from "next/navigation";
export default async function AdminSahifasi() {
const foydalanuvchi = await joriyFoydalanuvchi(); // 28-qismda
if (foydalanuvchi.rol !== "admin") forbidden();
return <main>…</main>;
}Status qoidasi notFound() bilan bir xil: oqim boshlanmagan bo'lsa — 403/401, boshlangan bo'lsa — 200 + noindex. Haqiqiy kirish tizimi — 28-qismda; hozir faqat bunday fayllar borligini bilish yetarli.
7.2 Qolganlari — xarita
app/ da yana bir nechta maxsus nom bor. Hammasi keyingi darslarda:
| Fayl | Nima | Dars |
|---|---|---|
default.tsx |
Parallel slot uchun zaxira | Parallel routes |
route.ts |
Sahifa emas, API manzil | Route Handlers |
icon.svg, opengraph-image.tsx |
Favicon, ulashish rasmi | SEO fayllari |
sitemap.ts, robots.ts |
Qidiruv tizimlari uchun | SEO fayllari |
src/proxy.ts |
Har so'rov oldidan ishlaydi | proxy.ts |
src/instrumentation.ts |
Server ishga tushganda, xatolar logi | Xatolar va loglar |
icon.svg ni Layout va template darsida qo'shgandik — u ham maxsus fayl.
8. Portfolio qadami: xato va topilmadi sahifalari
Bu dars va keyingi dars portfolio ning bitta holatini (06) quradi. Commit hali qilmang — u keyingi darsda, navigatsiya bilan birga.
8.1 Fayllar
| Fayl | Nima |
|---|---|
app/not-found.tsx |
v1 404: havolalar, «Orqaga» tugmasi, main#asosiy |
app/error.tsx |
Client; «Nimadir buzildi», digest, retry() |
app/global-error.tsx |
O'z <html>/<body>, oddiy |
app/loyihalar/[slug]/loading.tsx |
aria-busy="true" |
app/loyihalar/[slug]/page.tsx |
"Loyiha topilmadi" bloki o'rniga notFound() |
8.2 Kanon o'lchovi (holat 06)
| Sahifa | Oldin (holat 04) | Keyin (holat 06) |
|---|---|---|
/yoq |
404, axe 3 | 404, axe 0 |
/loyihalar/yoq |
200, "Loyiha topilmadi" | 200 (1-so'rov), keyin 404, noindex |
| Build jadvali | — | o'zgarmadi |
axe 3 → 0: Next.js'ning standart 404 sahifasida main yo'q edi, bizniki — main#asosiy bilan. Lint, tip, format — 0, hydration ogohlantirishi — 0.
9. Ko'p uchraydigan xatolar
| Belgi | Sabab | Davosi |
|---|---|---|
… must be a Client Component |
error.tsx da "use client" yo'q |
Fayl boshiga "use client" |
| 404 o'rniga 500 yoki xato sahifasi | notFound() try/catch ichida |
try dan tashqarida chaqiring |
| Root layout xatosida inglizcha sahifa | global-error.tsx yo'q |
Uni yozing (o'z <html> bilan) |
global-error stilsiz |
globals.css root layout'da |
Kerakli stilni o'zida bering |
error.message prod'da umumiy matn |
Server xatosi yashiriladi | digest ni ko'rsating, logdan qidiring |
loading.tsx hech ko'rinmaydi |
Sahifa statik (○) |
Bu normal — kutish yo'q |
| Noma'lum slug 200 qaytaradi | Oqim boshlangach status o'zgarmaydi | noindex bor; to'liq yechim — proxy.ts |
dynamicParams … not compatible |
Next 15 usuli Cache Components bilan | Olib tashlang |
Ichki not-found.tsx /yoq da ishlamaydi |
Mos kelmagan manzil faqat root'dagisini oladi | app/not-found.tsx yozing |
10. Mashqlar
Mashqlar kurs/mashqlar/23/05-maxsus-fayllar/ da. Jonli yechimlarni «Ishga tushir» bilan sinang.
1-mashq (oson): qaysi fayl?
- Server xatosida "Nimadir buzildi" va «Qayta urinish» —
/blog/eski-maqola— bunday papka yo'q —- Root layout'dagi xato —
- Sekin sahifa ochilguncha skelet —
- Kirmagan foydalanuvchiga 401 —
Yechim
- error.tsx — segment uchun xato chegarasi.
- not-found.tsx — root'dagisi; mos kelmagan manzil uchun boshqa variant yo'q.
- global-error.tsx —
error.tsxroot layout ichida turadi, uni ushlay olmaydi. - loading.tsx — avtomatik Suspense fallback'i.
- unauthorized.tsx —
unauthorized()chaqirilganda (eksperimental,authInterrupts).
2-mashq (o'rta): ierarxiyani chizing
Funksiya yozing: wrapSegment(files) — segmentdagi fayllar ro'yxatini oladi (["page", "loading", "layout"] kabi, tartibsiz) va ular qanday o'ralishini satr qilib qaytaradi: "layout > loading > page". Tartib — «Qaysi fayl nimani o'raydi» bo'limidagi ierarxiya: layout, template, error, loading, not-found, page. Ro'yxatda yo'q fayl o'tkazib yuboriladi. Ishora: tartib massivini filter qiling va includes bilan tekshiring, keyin join(" > ").
Sinov: ["page", "loading", "layout"], ["error", "page", "template", "not-found"], ["page"].
Yechim
const ORDER = [
"layout",
"template",
"error",
"loading",
"not-found",
"page",
];
function wrapSegment(files) {
return ORDER.filter((name) => files.includes(name)).join(" > ");
}
console.log(wrapSegment(["page", "loading", "layout"]));
console.log(wrapSegment(["error", "page", "template", "not-found"]));
console.log(wrapSegment(["page"]));Konsolda:
layout > loading > page
template > error > not-found > page
pageKirish tartibi muhim emas — natijani ORDER belgilaydi. Next.js ham xuddi shunday: fayllarni qaysi tartibda yaratganingiz ahamiyatsiz, o'rash tartibi doim bir xil.
3-mashq (qiyin): notFound va xatoni ajratadigan xato chegarasi
«error.tsx modeli» blokini kengaytiring: RouteBoundary xatoning digest iga qarasin. digest === "NEXT_HTTP_ERROR_FALLBACK;404" bo'lsa — <h1>Sahifa topilmadi</h1>, aks holda — «Nimadir buzildi» va «Qayta urinish». Sahifa: ProjectPage({ slug }) — slug ro'yxatda (["vazifalar", "bahor"]) bo'lmasa notFound() chaqiradi (next/navigation dan). App da ikkita tugma: «bahor» va «yoq» — bosilganda slug o'zgaradi. Xato chegarasi yangi slug'da qaytadan boshlashi uchun unga key={slug} bering (key bilan reset).
Yechim
import { Component, useState, type ReactNode } from "react";
import { notFound } from "next/navigation";
const NOT_FOUND = "NEXT_HTTP_ERROR_FALLBACK;404";
type RouteError = Error & { digest?: string };
class RouteBoundary extends Component<
{ children: ReactNode },
{ error: RouteError | null }
> {
state = { error: null as RouteError | null };
static getDerivedStateFromError(error: RouteError) {
return { error };
}
render() {
const { error } = this.state;
if (!error) return this.props.children;
if (error.digest === NOT_FOUND) return <h1>Sahifa topilmadi</h1>;
return (
<>
<h1>Nimadir buzildi</h1>
<button onClick={() => this.setState({ error: null })}>
Qayta urinish
</button>
</>
);
}
}
const SLUGS = ["vazifalar", "bahor"];
function ProjectPage({ slug }: { slug: string }) {
if (!SLUGS.includes(slug)) notFound();
return <h1>Loyiha: {slug}</h1>;
}
export default function App() {
const [slug, setSlug] = useState("vazifalar");
return (
<>
<button onClick={() => setSlug("bahor")}>bahor</button>{" "}
<button onClick={() => setSlug("yoq")}>yoq</button>
<RouteBoundary key={slug}>
<ProjectPage slug={slug} />
</RouteBoundary>
</>
);
}Konsolda:
Error: NEXT_HTTP_ERROR_FALLBACK;404
The above error occurred in the <ProjectPage> component.
React will try to recreate this component tree from scratch using the error boundary you provided, RouteBoundary.Ekranda:
bahor yoq
Loyiha: bahor«yoq» bosilganda notFound() xato tashladi, xato chegarasi uning digest ini tanidi va "Sahifa topilmadi" ni ko'rsatdi (ekran(…) qadami tekshiradi). Konsoldagi qatorlar — React'ning ushlangan xato haqidagi yozuvi: xato ProjectPage da chiqdi, RouteBoundary ushladi. «bahor» bosilganda key o'zgardi — xato chegarasi yangidan yaratildi, xato holati yo'qoldi. Next.js ham ichida xatoni shu digest bo'yicha ajratadi: biri not-found.tsx ga, qolgani error.tsx ga.
4-mashq: Portfolio qadami
O'z portfolio ingizga not-found.tsx (v1 dagi 404 havolalari bilan), error.tsx, global-error.tsx va loyihalar/[slug]/loading.tsx qo'shing. [slug] sahifasida "topilmadi" blokini notFound() bilan almashtiring. Tekshiring: npm run build, npm start, keyin curl -I http://localhost:3000/yoq — 404. /loyihalar/yoq ni ikki marta so'rang va statuslarni solishtiring.
Yechim
Namuna — «Portfolio qadami» bo'limidagi fayllar jadvali. Kod — «not-found.tsx va 404 statusi» bo'limida. /loyihalar/yoq ning birinchi so'rovi 200, ikkinchisi 404 bo'lsa — bu siz xato qilgansiz degani emas, kanon ham shuni ko'rgan. curl chiqishida x-nextjs-postponed: 1 — oqim bilan ketgan javob belgisi. Commit hali qilmang: keyingi darsda navigatsiya bilan birga bo'ladi.
11. Real ishda
- Har Next.js loyihada kamida
not-found.tsxvaerror.tsxbo'ladi. Ular bo'lmasa, foydalanuvchi inglizcha standart sahifani ko'radi — mahalliy saytda bu darhol "chala ish" bo'lib ko'rinadi. digestva loglar. Katta loyihalarda xato kuzatish xizmati (Sentry kabi) server xatosinidigestbilan saqlaydi. Qo'llab-quvvatlash xodimi foydalanuvchidan kodni so'raydi — xuddi bankdagi "operatsiya raqami" kabi.- Soft 404 va SEO. Do'konda o'chirilgan mahsulot sahifasi 200 qaytarsa, Google Search Console'da "Soft 404" ogohlantirishi chiqadi. Next.js'dagi oqim va status munosabatini bilish shu muammoni tez topishga yordam beradi.
- Intervyu savoli: "
error.tsxnega client komponent?" va "root layout xatosini qaysi fayl ushlaydi?" — endi ikkalasiga javob bilasiz.
Xulosa
- Maxsus fayl nomlari React o'rovchilarini avtomatik qo'yadi:
error.tsx— xato chegarasi (error boundary),loading.tsx— Suspense,not-found.tsx— 404 UI. - Tartib: layout → template → error → loading → not-found → page;
error.tsxo'z segmentidagi layout'ni ushlamaydi. notFound()xato tashlaydi (digestbilan) —try/catchga o'ramang; 404 da Nextnoindexni o'zi qo'shadi.error.tsx— client komponent; prod'da server xatosi matni yashiriladi,digestserver logi bilan bog'laydi;retry()qayta oladi.global-error.tsxroot layout o'rniga, o'z<html>/<body>si bilan chiziladi.- Oqim boshlangach status o'zgarmaydi: noma'lum slug birinchi so'rovda 200 — yechim proxy.ts da.
Keyingi dars: Navigatsiya: Link, useRouter va URL hooklari — menyudagi joriy havola, URL'dagi teg filtri va «Orqaga» tugmasi.
Manbalar
- Next.js hujjati —
error.js,not-found.js,loading.js,forbidden.js(next 16.4.0 paketi ichidaginode_modules/next/dist/docs, 2026-10-21 da o'qildi): https://nextjs.org/docs/app/api-reference/file-conventions/error - React xato kodlari —
scripts/error-codes/codes.json, kod 441: https://github.com/facebook/react/blob/main/scripts/error-codes/codes.json (2026-10-21; react.dev/errors/441 — 404) - Next.js hujjati — Project structure, Component hierarchy: https://nextjs.org/docs/app/getting-started/project-structure
- Next.js hujjati —
loading.js, Status codes: https://nextjs.org/docs/app/api-reference/file-conventions/loading - Kanon o'lchovlari:
portfoliov2, holat 06; noma'lum slug vadynamicParamstajribasi (kanon). Xato sahifasi,"use client"siz build,/yoqva/loyihalar/yoq9statuslari — biz ishga tushirdik (next 16.4.0,next build+next start, Chrome 155).
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!