Next.js คืออะไร และ App Router
ไอเดียหลักในหนึ่งประโยค
หัวข้อที่มีชื่อว่า “ไอเดียหลักในหนึ่งประโยค”Next.js คือ React framework ที่จัดการ routing, rendering, การ fetch data, bundling และ optimization ให้คุณ — และโมเดลปัจจุบันของตัวเองคือ App Router รัน component บน server โดย default
Next.js เป็น React framework ไม่ใช่แค่ router
หัวข้อที่มีชื่อว่า “Next.js เป็น React framework ไม่ใช่แค่ router”React เปล่า ๆ ให้แค่โมเดล component เท่านั้น ไม่มี routing ไม่มี server ไม่มี build pipeline Next.js เข้ามาเติมช่องว่างตรงนี้ เป็นชั้นที่ตัดสินว่า URL หนึ่งจะ map ไปที่โค้ดไหน โค้ดนั้นรันที่ไหน และผลลัพธ์เดินทางไปถึง browser ยังไง
พูดให้ชัด framework นี้ให้สิ่งเหล่านี้ —
- Routing — โฟลเดอร์ใต้
app/กลายเป็น URL segment ไม่ต้องมีไฟล์ config route ให้ดูแล - Rendering — render บน server ได้ทั้ง static และ dynamic, stream HTML และ hydrate เฉพาะส่วนที่ต้องการ interactivity
- การ fetch data — คุณ
awaitdata ตรง ๆ ในตัว component บน server ได้เลย ไม่ต้องวิ่งไป-กลับที่ client - Bundling — compile และ split โค้ดด้วย Turbopack แต่ละ route จึงส่งเฉพาะสิ่งที่ตัวเองต้องใช้
- Optimization — image, font, script และ metadata มี component กับ API ที่ built-in มาให้หมด
route ก็คือไฟล์ที่ default-export React component ออกมาเท่านั้น —
export default function HomePage() { return <h1>Hello from a Server Component</h1>;}App Router เทียบกับ Pages Router
หัวข้อที่มีชื่อว่า “App Router เทียบกับ Pages Router”Next.js มีระบบ routing สองแบบ App Router (โฟลเดอร์ app/) คือโมเดลปัจจุบันที่แนะนำ สร้างบน React Server Components ส่วน Pages Router (โฟลเดอร์ pages/) คือโมเดลเก่า ยังใช้งานได้และ support เต็มที่ แต่ feature ใหม่ ๆ ไม่ได้มาลงที่นี่
ความต่างเป็นเชิงโครงสร้าง ไม่ใช่แค่ผิวเผิน —
app/ pages/ layout.tsx _app.tsx page.tsx index.tsx blog/ blog/ page.tsx index.tsxใน App Router component เป็น Server Components โดย default และการ fetch data เกิดขึ้นในบรรทัดเดียวกับ async/await ส่วนใน Pages Router ทุก component เป็น Client Component และ data มาจากฟังก์ชันพิเศษอย่าง getServerSideProps คอร์สนี้เป็นแบบ App-Router-first — Pages Router จะโผล่มาเฉพาะตรงที่การ migrate app เดิมสำคัญ
create-next-app ให้อะไรคุณบ้าง
หัวข้อที่มีชื่อว่า “create-next-app ให้อะไรคุณบ้าง”คุณ scaffold โปรเจกต์ใหม่ด้วยคำสั่งเดียว —
npx create-next-app@latest my-apprecommended defaults จะเซ็ตให้คุณด้วย TypeScript, ESLint, Tailwind CSS, App Router และไฟล์ AGENTS.md ต้นไม้ที่ถูกสร้างขึ้นจะมี app/ เป็นศูนย์กลาง —
my-app/ app/ layout.tsx # root layout (required) page.tsx # the "/" route next.config.ts package.json tsconfig.jsonจากจุดนี้ npm run dev จะสตาร์ท development server แล้วคุณก็กำลังมอง App Router app ที่รันจริงอยู่
Request lifecycle ในหนึ่งย่อหน้า
หัวข้อที่มีชื่อว่า “Request lifecycle ในหนึ่งย่อหน้า”request ที่เข้ามาที่ App Router route ผ่านหลาย stage มากกว่าแค่ “รันฟังก์ชัน แล้วคืน HTML” เรียงลำดับ — มันผ่าน proxy.ts (ถ้ามี), Next.js match ไปที่ route segment, Server Components ของคุณ render ออกมาเป็น RSC payload (โดย cache layer ของ framework ตัดสินว่าอะไร fresh อะไรใช้ของเดิม), ผลลัพธ์ stream ไป browser เป็น HTML, browser hydrate Client Components ข้างในนั้น และทุกการ navigate หลังจากโหลดครั้งแรกจะ fetch RSC payload เพิ่มแทนที่จะโหลดทั้งหน้าใหม่ การเรียก Server Action ก็คือ POST request ที่กลับเข้า pipeline เดียวกันนี้ แต่ละ stage ถูกสอนแยกในบทของตัวเองที่อื่นในคอร์สนี้ The Request Lifecycle เดินเรื่องทั้งหมดแบบ end-to-end พร้อม header และ payload จริงที่พิสูจน์จาก app ที่รันอยู่จริง
flowchart LR Req[Browser request] --> Router[App Router] Router --> RSC[Server Components render on server] RSC --> HTML[Streamed HTML] Router --> Bundle[Minimal client bundle] HTML --> Page[Interactive page] Bundle --> Page
Mental Model
หัวข้อที่มีชื่อว่า “Mental Model”คิดว่า Next.js คือทุกอย่างที่ React จงใจไม่ทำให้ — มันคือชั้นที่ตัดสินว่าโค้ด component ของคุณรัน ที่ไหน (server กับ browser), รัน เมื่อไร (build time, request time หรือทั้งคู่), และผลลัพธ์เดินทางไปถึงผู้ใช้ ยังไง App Router ไม่ใช่ templating language ใหม่ที่แปะเข้ากับ React — มันคือคำตอบปัจจุบันของ Next.js สำหรับสามคำถามนั้น สร้างบน React Server Components แทนที่จะเป็น single-page app แบบ client-only
ข้อแลกเปลี่ยน
หัวข้อที่มีชื่อว่า “ข้อแลกเปลี่ยน”| ได้อะไร | ประโยชน์ | ต้นทุน |
|---|---|---|
| App Router (Server Components เป็น default) | fetch data บรรทัดเดียวกับ await, client JS น้อย, streaming | mental model ใหม่ถ้าคุณเรียน React แบบ client-only มาก่อน |
| Pages Router (เก็บไว้เพื่อ migrate) | โมเดล getServerSideProps/getStaticProps ที่คุ้นเคย, ecosystem เก่าใหญ่มาก | ทุก component เป็น Client Component ทั้งหมด ไม่มี feature ใหม่มาลงที่นี่ |
recommended defaults ของ create-next-app | เส้นทางที่เร็วที่สุดไปสู่โปรเจกต์ที่ config ถูกต้อง | ถ้าจะ customize ทีหลัง ต้องเข้าใจว่า default เลือกอะไรให้คุณไว้ |
| framework เป็นเจ้าของ routing/rendering/bundling | คุณเขียนโค้ด infrastructure น้อยลงมาก | ต้องเรียน convention ของ framework ไม่ใช่แค่ API ของ React |
ความเข้าใจผิดที่พบบ่อย
หัวข้อที่มีชื่อว่า “ความเข้าใจผิดที่พบบ่อย”- “Next.js เป็นแค่ router ให้ React” routing เป็นแค่หนึ่งในห้าอย่างที่มันเป็นเจ้าของ — มันยังตัดสิน rendering strategy, ergonomics ของการ fetch data, bundling และ optimization ในตัวสำหรับ image/font/script/metadata ด้วย
- “App Router กับ Pages Router เป็นสองวิธีเขียนของแบบเดียวกัน” ทั้งสองต่างกันเชิงโครงสร้าง — component ของ App Router เป็น Server Component โดย default และ fetch data ในบรรทัดเดียวกับ
async/await; component ของ Pages Router เป็น Client Component ทั้งหมด ป้อนข้อมูลด้วยฟังก์ชันแยกต่างหากอย่างgetServerSidePropsโค้ดย้ายข้ามกันแบบ 1:1 ไม่ได้ - “ทุก request แค่รันฟังก์ชัน page ของฉันแล้วคืน HTML” request หนึ่งผ่าน proxy, route matching, RSC rendering กับ cache layer หลายชั้น, streaming และ (ตอน navigate ครั้งถัดไป) การ fetch RSC ฝั่ง client — ดูภาพเต็มที่ The Request Lifecycle
อ่านโค้ดที่ AI เขียน
หัวข้อที่มีชื่อว่า “อ่านโค้ดที่ AI เขียน”เวลาโค้ดที่ generate มาอ้างว่าเป็น “Next.js page” เช็คสิ่งเหล่านี้ก่อนเชื่อ —
- มันอยู่ใต้
app/และ default-export component หรือเปล่า — หรือใช้ API เฉพาะ Pages Router (getServerSideProps,getStaticProps, ไฟล์pages/) ในโปรเจกต์ที่ควรเป็น App Router? - มันสมมติว่า component เป็น Client Component (ใช้
useState/useEffectโดยไม่มี"use client") ทั้งที่จริงมันเป็น Server Component โดย default หรือเปล่า? - มัน fetch data ผ่าน API call แยกจาก component ทั้งที่ async Server Component
awaitมันตรง ๆ ได้เลยหรือเปล่า? - มันเป็นคำแนะนำยุคก่อน App Router หรือเปล่า — เช่นถือว่า
pages/apiเป็นทางเดียวที่จะสร้าง endpoint ทั้งที่ Route Handlers (app/**/route.ts) คือของเทียบเท่าฝั่ง App Router?
🐛 หา bug ในโค้ดนี้
export async function getServerSideProps() {const res = await fetch('https://api.example.com/stats')return { props: { stats: await res.json() } }}
export default function Dashboard({ stats }: { stats: { views: number } }) {return <p>Views: {stats.views}</p>}เฉลย
getServerSideProps เป็น export เฉพาะ Pages Router — ในไฟล์ใต้ app/ มันไม่ทำอะไรเลย ใน App Router Dashboard เป็น Server Component โดย default อยู่แล้ว จึง await การ fetch ตรง ๆ ในตัวมันเองได้เลย ไม่ต้อง export ฟังก์ชันโหลด data แยก stats ตรงนี้จะเป็น undefined เพราะ Next.js ไม่เรียก getServerSideProps ให้ route ของ App Router เลย ทางแก้คือทำให้ Dashboard เป็น async แล้ว await fetch(...) ตรงในตัวมันเอง ตาม pattern ใน Server and Client Components