Framework Integrations
เอา framework ที่คุณถนัดมาใช้
หัวข้อที่มีชื่อว่า “เอา framework ที่คุณถนัดมาใช้”Astro ไม่มี client-side component runtime ของตัวเอง — แต่ให้คุณใช้ UI framework ที่คุณรู้จักอยู่แล้วกับส่วนที่ต้อง interactive แทน ทั้ง React, Vue, Svelte, Solid และ Preact ใช้เป็น island ได้หมด ผ่าน integration อย่างเป็นทางการ
เพิ่ม integration ด้วย CLI ซึ่งจะติดตั้ง package และตั้งค่า config ให้:
npx astro add reactคำสั่งนั้นอัปเดต astro.config.mjs ให้เอง:
import { defineConfig } from 'astro/config';import react from '@astrojs/react';
export default defineConfig({ integrations: [react()],});ตอนนี้ component .jsx สามารถ import เข้ามาในไฟล์ .astro และ hydrate ด้วย client directive ได้แล้ว
import framework component มาเป็น island
หัวข้อที่มีชื่อว่า “import framework component มาเป็น island”island เขียนด้วยสไตล์ปกติของ framework นั้น ส่วนไฟล์ .astro เป็นตัว import และตัดสินใจว่า hydrate เมื่อไหร่
// src/components/Counter.jsx — a plain React componentimport { useState } from 'react';
export default function Counter({ start }) { const [count, setCount] = useState(start); return <button onClick={() => setCount(count + 1)}>Count: {count}</button>;}---import Counter from '../components/Counter.jsx'; // 1. import the framework component---<h1>Welcome</h1><Counter start={0} client:visible /> <!-- 2. hydrate it as an island -->ถ้าไม่มี client:visible เจ้า Counter นั้นจะ render เป็น static HTML (มีปุ่ม แต่ onClick ไม่ทำงาน) directive คือสิ่งที่ส่ง JavaScript ของตัวเอง
ผสม framework หลายตัวในหน้าเดียว
หัวข้อที่มีชื่อว่า “ผสม framework หลายตัวในหน้าเดียว”เพราะแต่ละ island เป็นอิสระต่อกัน คุณจึงใช้ framework คนละตัวในหน้าเดียวกันได้ — widget React อยู่ข้าง ๆ widget Svelte — ขอแค่ติดตั้ง integration ทั้งสองไว้ อันนี้มีประโยชน์จริงตอน migrate ทีละส่วน หรือตอนหยิบ component ที่มีเฉพาะใน ecosystem เดียวมาใช้
flowchart TB page["Astro page (static HTML)"] page --> r["React island — client:load"] page --> s["Svelte island — client:visible"] page --> v["Vue island — client:idle"]
props ต้อง serializable
หัวข้อที่มีชื่อว่า “props ต้อง serializable”เมื่อคุณส่ง props จากไฟล์ .astro เข้าไปใน island จะถูก render บน server แล้ว serialize ลงใน HTML เพื่อให้ client rehydrate ด้วยค่าเดิมได้ นั่นตั้งกฎเหล็กไว้ข้อหนึ่ง: props ของ island ต้อง serializable — string, number, boolean, array, plain object สิ่งที่ ส่งไม่ได้:
- function (รวมถึง event handler) เพราะไม่มีทาง serialize function ข้ามเส้น server/client
- class instance,
Dateobject ในบางกรณี และค่าที่ไม่ใช่ plain value อื่น ๆ
---import Chart from '../components/Chart.jsx';const data = await getMetrics(); // fetched on the server---<Chart data={data} client:visible /> <!-- fine: data is a plain array/object --><!-- <Chart onPoint={(p) => ...} /> — NOT allowed: functions cannot be serialized -->ถ้าคุณต้องการ behavior แทนที่จะเป็นข้อมูล ให้เอา logic นั้นไปไว้ ข้างใน island หรือส่ง children ที่ render บน server เข้าไปผ่าน slot (บทหน้า) มุมมองที่ช่วยให้ไม่พลาด: ไฟล์ .astro ส่ง ข้อมูล ให้ island ไม่ใช่ callback