فایل‌های ویژه‌ی App Router

تا اینجا با دو فایل قراردادی کار کردیم: page.tsx و layout.tsx. App Router فایل‌های ویژه‌ی دیگری هم دارد که هرکدام یک نقش مشخص دارند، مثل نمایش وضعیت انتظار، مدیریت خطا یا صفحه‌ی پیدا نشد. در این درس همه‌ی آن‌ها را در یک نقشه‌ی کلی می‌بینیم، می‌فهمیم چگونه درون هم قرار می‌گیرند و در پایان یکی از آن‌ها را عملی به پروژه اضافه می‌کنیم. جزئیات هر فایل در درس مربوط به خودش می‌آید.

پیش‌نیاز

  • درس «پوشه‌های خصوصی و ساختاردهی فایل‌ها»
  • درس «Nested Layoutها»

ایده‌ی کلی: نام فایل، نقش را مشخص می‌کند

در App Router، Next.js فایل‌ها را بر اساس نامشان می‌شناسد. اگر در یک پوشه‌ی مسیر فایلی با یکی از این نام‌ها بسازید، Next.js خودش آن را در جای درست به برنامه وصل می‌کند و نیازی به import یا پیکربندی دستی نیست. همین‌طور هر فایل ویژه فقط روی همان پوشه و زیرمجموعه‌های آن اثر می‌گذارد.

فهرست فایل‌های ویژه‌ی مسیر

فایل نقش Client Component است؟ جزئیات در
page.tsx رابط کاربری یک مسیر را تعریف می‌کند و آن را عمومی می‌کند خیر، پیش‌فرض Server درس «ساخت صفحات با page.tsx»
layout.tsx ساختار مشترک یک بخش و زیرمجموعه‌هایش خیر، پیش‌فرض Server درس‌های «Root Layout...» و «Nested Layoutها»
template.tsx شبیه Layout، اما با هر ناوبری دوباره ساخته می‌شود خیر، پیش‌فرض Server همین درس (معرفی کوتاه)
loading.tsx رابط کاربری انتظار تا آماده‌شدن محتوای مسیر خیر، پیش‌فرض Server درس «فایل loading.tsx»
error.tsx رابط کاربری خطاهای پیش‌بینی‌نشده‌ی یک بخش بله، باید Client Component باشد درس «error.tsx و Error Boundary»
global-error.tsx خطاهای Root Layout و خطای سراسری بله درس «global-error.tsx»
not-found.tsx رابط کاربری وقتی چیزی پیدا نشود (۴۰۴) خیر، پیش‌فرض Server درس «Redirect، not-found.tsx و notFound()»
route.ts تعریف API (Route Handler) به‌جای صفحه معنی ندارد؛ فقط سمت سرور درس «Route Handlers و فایل route.ts»
default.tsx جایگزین در Parallel Routes خیر خارج از محدوده‌ی اصلی این دوره

پسوند هر فایل می‌تواند .js، .jsx یا .tsx باشد. فایل route.ts کد سمت سرور است و JSX ندارد، پس پسوند .ts می‌گیرد.

ترتیب قرارگرفتن فایل‌ها درون هم

وقتی همه‌ی این فایل‌ها در یک پوشه وجود داشته باشند، Next.js آن‌ها را به شکل مشخصی به‌هم تو در تو می‌کند. از بیرون به درون:

  1. layout.tsx
  2. template.tsx
  3. error.tsx (به‌صورت Error Boundary)
  4. loading.tsx (به‌صورت مرز Suspense)
  5. not-found.tsx (به‌صورت Error Boundary برای خطای پیدا نشد)
  6. page.tsx یا Layout مسیر درونی‌تر

نتیجه‌ی این ترتیب مهم است:

  • loading.tsx داخل layout.tsx قرار دارد؛ پس هنگام انتظار، Layout از قبل نمایش داده می‌شود و فقط جای صفحه، رابط انتظار می‌آید.
  • error.tsx داخل layout.tsx قرار دارد؛ پس خطای صفحه Layout را خراب نمی‌کند، ولی خطایی که خودِ layout.tsx همان پوشه رخ بدهد را نمی‌گیرد و به error.tsx بالادستی می‌رسد. برای خطای Root Layout از global-error.tsx استفاده می‌شود.

layout یا template؟

template.tsx هم مثل Layout، children می‌گیرد. تفاوت در رفتار هنگام ناوبری است:

ویژگی layout.tsx template.tsx
هنگام ناوبری بین صفحات هم‌سطح حفظ می‌شود و دوباره ساخته نمی‌شود برای هر ناوبری، نمونه‌ی جدیدی ساخته می‌شود
State کامپوننت‌های کلاینتی داخل آن حفظ می‌شود ریست می‌شود
کاربرد معمول هدر، فوتر، منو انیمیشن ورود صفحه، ثبت بازدید در هر ناوبری

در بیشتر موارد Layout انتخاب درست است و ما در DevNotes هم از template.tsx استفاده نمی‌کنیم. فقط باید بدانید که وجود دارد.

فایل‌های ویژه‌ی دیگر، خارج از «مسیر»

چند فایل قراردادی دیگر هم هست که با مسیرها رابطه‌ی مستقیم ندارند:

فایل جای قرارگیری نقش جزئیات در
proxy.ts ریشه‌ی پروژه، هم‌سطح با app اجرای کد پیش از رسیدن درخواست به مسیر (جایگزین middleware.ts) درس «نقش proxy.ts در Next.js 16»
favicon.ico و فایل‌های آیکون و تصویر شبکه‌های اجتماعی داخل app تعریف خودکار آیکون و تصویر اشتراک‌گذاری درس «Metadata و اصول پایه‌ی SEO»
sitemap.ts و robots.ts داخل app تولید نقشه‌ی سایت و فایل ربات‌ها برای موتورهای جست‌وجو درس «sitemap.ts، robots.ts و بهینه‌سازی صفحات عمومی»

فایل favicon.ico را از ابتدا در پروژه داریم و Next.js آن را خودکار به آیکون تب مرورگر وصل کرده است؛ این هم نمونه‌ای از ساز‌وکار «نام فایل، نقش را مشخص می‌کند».

عملی: اضافه‌کردن not-found.tsx به DevNotes

الان اگر آدرسی مثل http://localhost:3000/xyz را باز کنید، صفحه‌ی ۴۰۴ پیش‌فرض و انگلیسی Next.js را می‌بینید. با ساخت یک فایل not-found.tsx در ریشه‌ی app، صفحه‌ی ۴۰۴ سراسری خودمان را می‌سازیم:

tsx
// app/not-found.tsx
export default function NotFound() {
  return (
    <main>
      <h1>صفحه پیدا نشد</h1>
      <p>آدرسی که وارد کرده‌اید وجود ندارد.</p>
    </main>
  );
}

اگر پوشه‌ی app بعد از آخرین تغییرات ساختارتان درست است، همین یک فایل کافی است و نیازی به import یا ثبت‌نام جایی نیست.

خروجی و رفتار مورد انتظار

  • آدرس‌های تعریف‌نشده مثل /xyz یا /contact حالا عنوان «صفحه پیدا نشد» را به فارسی نشان می‌دهند.
  • این صفحه فقط داخل Root Layout رندر می‌شود، پس چیدمان راست‌چین و تنظیمات سراسری را دارد، اما هدر و فوتر گروه (public) را ندارد، چون آن Layout فقط برای مسیرهای داخل گروه است.
  • پاسخ HTTP این آدرس‌ها کد وضعیت ۴۰۴ دارد.

در درس «Redirect، not-found.tsx و notFound()» می‌بینیم چطور این صفحه را به‌صورت دستی از داخل کد فراخوانی کنیم و برای یک بخش خاص صفحه‌ی ۴۰۴ اختصاصی بسازیم.

نکته‌های مهم

  • نام فایل‌ها دقیق و با حروف کوچک باشد. اگر نام را اشتباه بنویسید (مثلاً Loading.tsx یا not_found.tsx)، Next.js آن را فایل ویژه نمی‌شناسد و بی‌صدا نادیده می‌گیرد.
  • فایل‌های ویژه به پوشه‌ی خودشان محدودند. یک loading.tsx در app/posts فقط روی /posts و زیرمسیرهای آن اثر می‌گذارد؛ برای /about کاری نمی‌کند.
  • فایل ویژه، مسیر نمی‌سازد. فقط page.tsx و route.ts یک آدرس را عمومی می‌کنند؛ loading.tsx و error.tsx فقط پیرامون صفحه عمل می‌کنند.
  • رفتارها در حالت توسعه و Production ممکن است فرق کنند. مثلاً نمایش خطاها در dev با جزئیات کامل است ولی در Production پیام‌های ساده‌تری به کاربر داده می‌شود. این را در فصل «Loading، Error و Streaming» دقیق‌تر می‌بینیم.

ساختار پروژه پس از این درس

text
app/
├── layout.tsx
├── not-found.tsx          ← جدید
├── globals.css
├── (public)/
│   ├── layout.tsx
│   ├── page.tsx
│   ├── about/
│   ├── posts/
│   └── ...
└── (dashboard)/
    └── ...

جمع‌بندی

  • در App Router، نام فایل نقش آن را مشخص می‌کند؛ فایل‌های اصلی page، layout، template، loading، error، global-error، not-found و route هستند.
  • این فایل‌ها به‌ترتیب layout، template، error، loading، not-found و در نهایت page درون هم قرار می‌گیرند.
  • error.tsx و global-error.tsx حتماً Client Component هستند، ولی بقیه به‌صورت پیش‌فرض Server Component‌اند.
  • template.tsx برخلاف layout.tsx با هر ناوبری دوباره ساخته می‌شود؛ کاربرد آن محدودتر است.
  • فایل‌هایی مثل proxy.ts، آیکون‌ها، sitemap.ts و robots.ts هم قرارداد نام‌گذاری دارند و در فصل‌های بعد به آن‌ها می‌رسیم.
  • در DevNotes اکنون یک صفحه‌ی ۴۰۴ فارسی با app/not-found.tsx داریم.
  • در درس بعد، «ساخت اسکلت اولیه‌ی DevNotes»، همه‌ی آنچه در این فصل یاد گرفتیم را برای ساخت ساختار اولیه‌ی پروژه کنار هم می‌گذاریم.