บทนำ: Astro สำหรับนักพัฒนา React
คุณสร้าง UI ด้วย React ได้อยู่แล้ว เข้าใจ component, hook, state, และ JSX ดีอยู่แล้ว Astro ไม่ได้มาแทนที่ความรู้เหล่านั้น — แต่เป็นวิธีส่งมอบที่แตกต่างออกไป ซึ่งนำ mental model ของ React มาใช้ในจุดที่ควรใช้ และถอยออกไปในจุดที่ไม่จำเป็น
การเปลี่ยนแปลงที่ใหญ่ที่สุด: React ส่ง JavaScript runtime ไปยัง browser และ render UI ที่นั่น ส่วน Astro render UI ที่ server (หรือขณะ build) แล้วส่ง HTML ออกมา JavaScript จะถึง browser เฉพาะส่วนที่ต้องการ interactivity จริงๆ เท่านั้น
สำหรับเว็บไซต์ที่เน้นเนื้อหา — docs, หน้า marketing, blog, landing page — ความแตกต่างนี้มีนัยสำคัญมาก: Time to First Contentful Paint ที่เร็วขึ้น, bundle ที่เล็กลง, และ Core Web Vitals ที่ดีขึ้นโดยไม่ต้องปรับแต่งเอง
ทำไมต้องใช้ Astro แทน Next.js?
หัวข้อที่มีชื่อว่า “ทำไมต้องใช้ Astro แทน Next.js?”Next.js เป็น full-stack React framework ที่ยอดเยี่ยม Astro เหมาะสมเมื่อ:
- เนื้อหาของคุณมีน้ำหนักมากกว่า interactivity หน้า static, blog, docs site, และ marketing site แทบไม่ส่ง JavaScript เลยกับ Astro ตามค่าเริ่มต้น
- คุณต้องการผสมหลาย framework Astro ให้คุณวาง React, Svelte, Vue, หรือ Preact component ไว้คู่กันได้ — หรือจะไม่ใช้เลยก็ได้
- คุณสนใจเรื่องขนาด bundle islands architecture ของ Astro ทำให้แต่ละ interactive widget ถูก hydrate แยกกัน ส่วนที่เหลือของหน้าเป็น HTML ล้วนๆ
- คุณต้องการ routing แบบ file-based โดยไม่มี client-side router ทุก
.astropage ในsrc/pages/กลายเป็น URL — ไม่มี Link component, ไม่มี router config, ไม่มี hydration overhead
สิ่งที่เปลี่ยนไปจาก React
หัวข้อที่มีชื่อว่า “สิ่งที่เปลี่ยนไปจาก React”| React / Next.js | เทียบเท่าใน Astro |
|---|---|
ไฟล์ component .jsx / .tsx | ไฟล์ component .astro |
| Function body | Frontmatter (บล็อก ---) |
return (<JSX />) | HTML template ด้านล่าง --- |
argument props | Astro.props |
prop children | <slot /> |
useEffect / useState | Framework island ที่มี directive client:* |
getServerSideProps | Frontmatter (fetch ขณะ build/request) |
| ไฟล์ Pages Router | src/pages/*.astro |
สิ่งที่ยังคงเดิม
หัวข้อที่มีชื่อว่า “สิ่งที่ยังคงเดิม”- syntax
{expr}แบบ JSX ใน template - การประกอบ component (
<Header />,<Footer />) - TypeScript ทุกที่ (
interface Props) - React component เดิมของคุณ — นำมาใส่เป็น island ได้เลย
- tooling
npm/pnpm, มี Vite อยู่เบื้องหลัง
คอร์สนี้ครอบคลุมอะไรบ้าง
หัวข้อที่มีชื่อว่า “คอร์สนี้ครอบคลุมอะไรบ้าง”| โมดูล | สิ่งที่คุณจะได้เรียน |
|---|---|
| Intro (โมดูลนี้) | ทำไมต้อง Astro, islands architecture, การตั้งค่า, โครงสร้างโปรเจกต์, หน้าแรก |
| Components | anatomy ของ .astro component, props, slots, expressions |
| Layouts | shared layout, nested layout, pattern ของ <slot /> |
| Routing | routing แบบ file-based, dynamic route, หน้า 404 |
| Data Fetching | fetch ใน frontmatter, getStaticPaths, content collection |
| Islands | การใช้ React/Svelte/Vue component กับ directive client:* |
หน้า .astro แรก
หัวข้อที่มีชื่อว่า “หน้า .astro แรก”นี่คือการเปรียบเทียบที่กระชับที่สุด: React component ที่ render ส่วน hero กับ Astro page ที่เทียบเท่ากัน
// src/app/page.tsx (Next.js App Router)export default function HeroPage() { return ( <html lang="en"> <head><title>My Site</title></head> <body> <h1>Hello from React</h1> <p>This page ships a full React runtime.</p> </body> </html> );}---// src/pages/index.astroconst title = "My Site";---<html lang="en"> <head><title>{title}</title></head> <body> <h1>Hello from Astro</h1> <p>This page ships zero JavaScript.</p> </body></html>หน้า Astro ด้านบนส่ง JavaScript ศูนย์ชิ้นไปยัง browser — ตัวแปร title ถูกประเมินครั้งเดียวขณะ build และฝังลงใน HTML เลย ไม่มี React runtime, ไม่มี hydration, ไม่มี virtual DOM
ตัวอย่างที่รันได้
หัวข้อที่มีชื่อว่า “ตัวอย่างที่รันได้”---
const framework = "Astro";
const audience = "React developer";
const year = new Date().getFullYear();
const features = ["Zero JS by default", "Islands architecture", "Use React components as islands", "File-based routing"];
---
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Welcome to {framework}</title>
<style>
body { font-family: sans-serif; max-width: 640px; margin: 2rem auto; padding: 0 1rem; }
ul { line-height: 2; }
li::marker { color: #6366f1; }
</style>
</head>
<body>
<h1>Welcome, {audience}!</h1>
<p>This is an Astro page rendered in {year}. Check the browser DevTools — no JS bundle.</p>
<h2>Why Astro?</h2>
<ul>
{features.map(f => <li>{f}</li>)}
</ul>
</body>
</html>