ساخت صفحات با page.tsx

در درس قبل دیدیم که App Router مسیرها را از ساختار پوشه‌ها می‌سازد. حالا به‌صورت عملی اولین صفحات پروژه‌ی DevNotes را می‌سازیم. فایل page.tsx ساده‌ترین و مهم‌ترین فایل قراردادی App Router است و تقریباً هر قابلیت دیگری، مثل Layout، Loading و Error، حول همین فایل شکل می‌گیرد.

پیش‌نیاز

  • درس «مفهوم App Router و تفاوت آن با Pages Router»
  • پروژه‌ی devnotes که در درس «ساخت پروژه با create-next-app» ساختیم، با سرور توسعه‌ی در حال اجرا (npm run dev)

فایل page.tsx چیست؟

فایل page.tsx رابط کاربری یک مسیر را تعریف می‌کند و آن مسیر را در دسترس عموم قرار می‌دهد. قاعده‌ی کار ساده است:

  • یک پوشه داخل app یک بخش از آدرس را می‌سازد.
  • فقط وقتی داخل آن پوشه فایل page.tsx وجود داشته باشد، آن آدرس قابل مشاهده می‌شود.
  • فایل باید یک کامپوننت React را با export default صادر کند.

پسوند فایل می‌تواند .js، .jsx یا .tsx باشد. چون این دوره با TypeScript پیش می‌رود، از .tsx استفاده می‌کنیم.

رابطه‌ی فایل‌ها و آدرس‌ها

مسیر فایل آدرس در مرورگر
app/page.tsx /
app/about/page.tsx /about
app/posts/page.tsx /posts
app/posts/new/page.tsx /posts/new

اسم پوشه دقیقاً همان بخش آدرس است. پوشه‌ی تودرتو، آدرس تودرتو می‌سازد.

عملی: ساخت صفحه‌ی اصلی DevNotes

پروژه‌ی ساخته‌شده با create-next-app یک app/page.tsx نمونه دارد که صفحه‌ی خوش‌آمدگویی خود Next.js را نشان می‌دهد. محتوای آن را کاملاً با کد زیر جایگزین کنید:

tsx
// app/page.tsx
export default function HomePage() {
  return (
    <main>
      <h1>DevNotes</h1>
      <p>وب‌سایتی برای انتشار و مدیریت نوشته‌های فنی.</p>
    </main>
  );
}

مرورگر را در http://localhost:3000 باز کنید. به لطف Fast Refresh، پس از ذخیره‌ی فایل، صفحه خودکار تغییر می‌کند.

ممکن است متن را چپ‌چین و با ظاهر ساده ببینید. جهت راست‌چین را در درس «Root Layout، تنظیم lang="fa" و dir="rtl"» تنظیم می‌کنیم و ظاهر را در فصل «Styling و ابزارهای توسعه» زیباتر می‌کنیم. در این درس فقط روی ساختار تمرکز داریم.

عملی: ساخت صفحه‌ی «درباره‌ی ما»

داخل app پوشه‌ی about را بسازید و در آن فایل page.tsx را با این محتوا ایجاد کنید:

tsx
// app/about/page.tsx
export default function AboutPage() {
  return (
    <main>
      <h1>درباره‌ی DevNotes</h1>
      <p>DevNotes یک پروژه‌ی آموزشی برای یادگیری Next.js 16 است.</p>
    </main>
  );
}

حالا آدرس http://localhost:3000/about را باز کنید.

عملی: ساخت صفحه‌ی نوشته‌ها

همین کار را برای فهرست نوشته‌ها در مسیر /posts انجام می‌دهیم. فعلاً فقط یک صفحه‌ی ساده با متن ثابت می‌سازیم. داده‌ی واقعی را در فصل «Rendering و Data Fetching» اضافه می‌کنیم.

tsx
// app/posts/page.tsx
export default function PostsPage() {
  return (
    <main>
      <h1>نوشته‌ها</h1>
      <p>فهرست نوشته‌ها به‌زودی در اینجا نمایش داده می‌شود.</p>
    </main>
  );
}

توضیح کد

  • export default: Next.js صفحه را از همین صادرات پیش‌فرض می‌شناسد. نام تابع (مثلاً HomePage) دلخواه است، اما بهتر است گویا باشد و معمولاً با Page تمام شود.
  • کامپوننت‌ها props ندارند؛ در درس‌های بعد می‌بینیم که Next.js به صفحات پویا params و searchParams را به‌عنوان props می‌دهد.
  • تگ main محتوای اصلی صفحه را مشخص می‌کند و برای دسترس‌پذیری مناسب است. تگ‌های html و body را در این فایل‌ها نمی‌نویسیم، چون در layout.tsx قرار دارند.
  • هیچ "use client"ی نوشته نشده، پس این صفحات به‌صورت پیش‌فرض Server Component هستند و روی سرور اجرا می‌شوند. دلیل و تفاوت را در فصل «Server Components و Client Components» می‌بینیم.

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

text
app/
├── layout.tsx
├── page.tsx           ← /
├── globals.css
├── favicon.ico
├── about/
│   └── page.tsx       ← /about
└── posts/
    └── page.tsx       ← /posts

رفتار مورد انتظار

آدرس نتیجه
/ عنوان «DevNotes» و توضیح کوتاه پروژه
/about عنوان «درباره‌ی DevNotes»
/posts عنوان «نوشته‌ها» و پیام موقت
/contact (یا هر آدرس تعریف‌نشده) صفحه‌ی ۴۰۴ پیش‌فرض Next.js، چون پوشه‌ی مربوط یا page.tsx آن وجود ندارد

هنوز بین این صفحات لینک نساخته‌ایم؛ برای رفتن از یک صفحه به صفحه‌ی دیگر باید آدرس را در مرورگر تایپ کنید. لینک‌سازی درست با کامپوننت Link موضوع درس «لینک‌سازی با Link» در فصل «Routing و Navigation» است.

نکته‌های مهم درباره‌ی page.tsx

  • پوشه بدون page.tsx مسیر نیست. می‌توان در پوشه‌ی app/posts فایل‌های دیگری مثل کامپوننت یا تابع کمکی گذاشت و آن‌ها خودکار مسیر عمومی نمی‌شوند. فقط فایل‌های با نام قراردادی مثل page.tsx و route.ts عمومی می‌شوند. این ویژگی را «همجواری» (Colocation) می‌نامند و در درس «پوشه‌های خصوصی و ساختاردهی فایل‌ها» بیشتر استفاده می‌کنیم.
  • در هر مسیر فقط یک page.tsx. هر پوشه یک صفحه‌ی اصلی دارد. همچنین در همان پوشه نمی‌توان page.tsx و route.ts را کنار هم گذاشت، چون هر دو یک مسیر را تعریف می‌کنند.
  • صادرات پیش‌فرض الزامی است. اگر فایل page.tsx کامپوننتی را با export default صادر نکند، Next.js خطا نمایش می‌دهد و صفحه ساخته نمی‌شود.
  • صفحه می‌تواند async باشد. در Server Component مجاز است که تابع صفحه async باشد و داخلش await به کار برود. این الگو را در فصل «Rendering و Data Fetching» استفاده می‌کنیم.
  • عنوان تب مرورگر هنوز تنظیم نشده است. عنوان و توضیحات صفحه را با Metadata مدیریت می‌کنیم. جزئیات در درس «Metadata ثابت و پویا» می‌آید.

جمع‌بندی

  • فایل page.tsx رابط کاربری یک مسیر را تعریف می‌کند و آن مسیر را قابل دسترسی می‌کند.
  • نام پوشه‌ها بخش‌های آدرس را می‌سازند؛ app/page.tsx مسیر / و app/about/page.tsx مسیر /about است.
  • هر page.tsx باید یک کامپوننت را با export default صادر کند و پیش‌فرض یک Server Component است.
  • پوشه‌ای که page.tsx ندارد، مسیر عمومی نمی‌سازد و می‌تواند فقط محل فایل‌های کمکی باشد.
  • در پروژه‌ی DevNotes اکنون سه صفحه‌ی /، /about و /posts داریم.
  • در درس بعد، «Root Layout، تنظیم lang="fa" و dir="rtl"»، ساختار مشترک صفحات را بررسی می‌کنیم و جهت صفحه را برای فارسی راست‌چین می‌کنیم.