ข้ามไปยังเนื้อหา

Framework Integrations

Astro ไม่มี client-side component runtime ของตัวเอง — แต่ให้คุณใช้ UI framework ที่คุณรู้จักอยู่แล้วกับส่วนที่ต้อง interactive แทน ทั้ง React, Vue, Svelte, Solid และ Preact ใช้เป็น island ได้หมด ผ่าน integration อย่างเป็นทางการ

เพิ่ม integration ด้วย CLI ซึ่งจะติดตั้ง package และตั้งค่า config ให้:

Terminal window
npx astro add react

คำสั่งนั้นอัปเดต astro.config.mjs ให้เอง:

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 ได้แล้ว

island เขียนด้วยสไตล์ปกติของ framework นั้น ส่วนไฟล์ .astro เป็นตัว import และตัดสินใจว่า hydrate เมื่อไหร่

// src/components/Counter.jsx — a plain React component
import { useState } from 'react';
export default function Counter({ start }) {
const [count, setCount] = useState(start);
return <button onClick={() => setCount(count + 1)}>Count: {count}</button>;
}
src/pages/index.astro
---
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 ของตัวเอง

เพราะแต่ละ 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"]
หน้าเดียว มี island จาก framework ต่างตัวกัน

เมื่อคุณส่ง 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, Date object ในบางกรณี และค่าที่ไม่ใช่ 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

จะเพิ่มการรองรับ component React ในโปรเจกต์ Astro อย่างไร?
ใช้ React island กับ Svelte island ในหน้าเดียวกันได้ไหม?
ทำไมส่ง function (เช่น event handler) เป็น prop ให้ island จากไฟล์ .astro ไม่ได้?
framework component ที่ import เข้ามาในไฟล์ .astro โดยไม่มี client directive จะ: