📁 บทที่ 2: File-based Routing

เรียนรู้ระบบการนำทางที่ใช้ไฟล์และโฟลเดอร์ในการสร้าง routes
30 นาที
เริ่มต้น
สำคัญ
วัตถุประสงค์การเรียนรู้

เข้าใจความแตกต่างระหว่าง Pages Router และ App Router

สามารถสร้าง Static Routes และ Dynamic Routes ได้

รู้จักการใช้ Route Groups และ Special Files

เข้าใจโครงสร้าง Nested Routes และ Catch-all Routes

🤔 File-based Routing คืออะไร?

File-based Routing เป็นระบบการสร้าง routes โดยใช้โครงสร้างไฟล์และโฟลเดอร์ แทนการเขียนการตั้งค่า routing แบบ manual ทำให้การจัดการ routes ง่ายและเป็นระเบียบมากขึ้น

🔄 Pages Router vs App Router
📂 Pages Router (Next.js 12 และเก่ากว่า)

ใช้โฟลเดอร์ `pages/` และไฟล์แต่ละไฟล์เป็น route

pages/
├── index.js        → /
├── about.js        → /about  
├── blog/
│   ├── index.js    → /blog
│   └── [slug].js   → /blog/:slug
└── api/
    └── users.js    → /api/users

🛣️ ประเภทของ Routes

หน้าแบบคงที่ สร้างโดยการใส่ไฟล์ page.tsx ในโฟลเดอร์ (จะมี Static Route Indicator ใน Next.js 15)

// app/about/page.tsx
export default function AboutPage() {
  return (
    <div>
      <h1>เกี่ยวกับเรา</h1>
      <p>ยินดีต้อนรับสู่เว็บไซต์ของเรา</p>
    </div>
  );
}

Route ที่รับพารามิเตอร์แบบไดนามิก ใน Next.js 15 params เป็น async

// app/blog/[slug]/page.tsx
interface Props {
  params: Promise<{ slug: string }>;
}

export default async function BlogPost({ params }: Props) {
  const { slug } = await params;
  
  return (
    <div>
      <h1>บทความ: {slug}</h1>
      <p>เนื้อหาบทความ...</p>
    </div>
  );
}

Route ที่ซ้อนกันหลายระดับ เหมาะสำหรับโครงสร้างที่ซับซ้อน (Next.js 15 async params)

// app/blog/category/[id]/page.tsx
interface Props {
  params: Promise<{ id: string }>;
}

export default async function CategoryPage({ params }: Props) {
  const { id } = await params;
  
  return (
    <div>
      <h1>หมวดหมู่: {id}</h1>
      <p>รายการบทความในหมวดหมู่นี้</p>
    </div>
  );
}

Route ที่จับพารามิเตอร์แบบหลายระดับ ใช้ [...slug] (Next.js 15 async params)

// app/docs/[...slug]/page.tsx
interface Props {
  params: Promise<{ slug: string[] }>;
}

export default async function DocsPage({ params }: Props) {
  const { slug } = await params;
  const path = slug.join('/');
  
  return (
    <div>
      <h1>เอกสาร: {path}</h1>
      <p>เนื้อหาเอกสาร...</p>
    </div>
  );
}

📦 Route Groups

Route Groups ช่วยให้เราจัดกลุ่ม routes โดยไม่ส่งผลต่อ URL structure โดยใช้วงเล็บ () ครอบชื่อโฟลเดอร์

(marketing)

กลุ่ม routes สำหรับหน้า marketing ไม่ส่งผลต่อ URL

app/(marketing)/about/page.tsx → /about

app/(marketing)/pricing/page.tsx → /pricing

app/(marketing)/contact/page.tsx → /contact

(auth)

กลุ่ม routes สำหรับระบบ authentication

app/(auth)/login/page.tsx → /login

app/(auth)/register/page.tsx → /register

app/(auth)/forgot-password/page.tsx → /forgot-password

(dashboard)

กลุ่ม routes สำหรับหน้า dashboard

app/(dashboard)/admin/page.tsx → /admin

app/(dashboard)/settings/page.tsx → /settings

app/(dashboard)/profile/page.tsx → /profile

📄 Special Files

App Router มีไฟล์พิเศษที่มีหน้าที่เฉพาะ ช่วยให้เราสร้าง UX ที่ดีขึ้น

layout.tsx

Layout ที่ใช้ร่วมกันสำหรับ routes ในโฟลเดอร์นั้นๆ

page.tsx

หน้าเว็บหลักของ route นั้นๆ

loading.tsx

UI ที่แสดงขณะกำลังโหลดข้อมูล

error.tsx

หน้าที่แสดงเมื่อเกิดข้อผิดพลาด

not-found.tsx

หน้าที่แสดงเมื่อไม่พบ route (404)

🛠️ ตัวอย่างการใช้งานจริง

มาลองสร้างโครงสร้าง routes สำหรับเว็บไซต์ e-commerce กัน

app/
├── (marketing)/
│   ├── layout.tsx        # Layout สำหรับ marketing pages
│   ├── page.tsx          # หน้าแรก (/)
│   ├── about/
│   │   └── page.tsx      # เกี่ยวกับเรา (/about)
│   └── contact/
│       └── page.tsx      # ติดต่อเรา (/contact)
├── (shop)/
│   ├── layout.tsx        # Layout สำหรับ shop pages  
│   ├── products/
│   │   ├── page.tsx      # รายการสินค้า (/products)
│   │   └── [id]/
│   │       ├── page.tsx  # รายละเอียดสินค้า (/products/123)
│   │       └── reviews/
│   │           └── page.tsx # รีวิวสินค้า (/products/123/reviews)
│   └── cart/
│       └── page.tsx      # ตะกร้าสินค้า (/cart)
├── (auth)/
│   ├── login/
│   │   └── page.tsx      # เข้าสู่ระบบ (/login)
│   └── register/
│       └── page.tsx      # สมัครสมาชิก (/register)
└── api/
    ├── products/
    │   └── route.ts      # API สำหรับสินค้า
    └── auth/
        └── route.ts      # API สำหรับ authentication
💡 ข้อดีของโครงสร้างนี้:

แยก layout ตามประเภทหน้า (marketing, shop, auth)

โครงสร้างชัดเจน เข้าใจง่าย

สามารถปรับแต่ง layout แต่ละกลุ่มได้อิสระ

รองรับ nested routes ที่ซับซ้อน

✋ ฝึกปฏิบัติ: สร้าง Routes

ลองทำตามขั้นตอนนี้เพื่อสร้าง routes ต่างๆ ในโปรเจค Next.js ของคุณ

สร้าง Static Route

สร้างหน้า About โดยการสร้างโฟลเดอร์และไฟล์ดังนี้:

$ mkdir -p app/about
$ touch app/about/page.tsx

// app/about/page.tsx
export default function AboutPage() {
  return (
    <div>
      <h1>เกี่ยวกับเรา</h1>
      <p>ยินดีต้อนรับสู่เว็บไซต์ของเรา</p>
    </div>
  );
}
สร้าง Dynamic Route
สร้าง Route Group
🎯 สรุปบทเรียน

ในบทนี้คุณได้เรียนรู้ File-based Routing ซึ่งเป็นหัวใจสำคัญของ Next.js ที่ทำให้การจัดการ routes ง่ายและมีระเบียบ