ข้ามไปเนื้อหาหลัก

Category: guide

Astro Server Islands — Dynamic Content ใน Static Site

Server Islands คือ Astro 5 feature ที่ช่วยฝัง dynamic server-rendered component ลงใน static page โดยไม่ต้อง sacrifice performance ของหน้าอื่น

· อ่านประมาณ 6 นาที

สารบัญ

Server Islands คืออะไร

Astro เริ่มต้นเป็น static site generator ที่ทุกอย่าง render ณ build time แต่บางส่วนของหน้าต้องการข้อมูล real-time เช่น จำนวน like, ข้อมูล user, ราคาสินค้า

Server Islands ช่วยให้ฝัง “เกาะ” ที่ render บน server แต่ละ request ลงในหน้า static ได้ โดยหน้าส่วนที่เหลือยังคง serve จาก CDN เร็วเหมือนเดิม


วิธีทำงาน

GET /product/123

CDN → HTML static (เร็วมาก)
       + placeholder สำหรับ Server Island
       ↓ (browser fetch แยก)
Server → render <PriceWidget server:defer /> → inject ลงหน้า

Setup

ต้องใช้ Astro Adapter (Node.js, Cloudflare, Netlify, etc.) เพราะต้องการ server:

# Node.js adapter
npm install @astrojs/node
// astro.config.mjs
import { defineConfig } from 'astro/config';
import node from '@astrojs/node';

export default defineConfig({
  output: 'static',    // หน้าส่วนใหญ่ยังคง static
  adapter: node({
    mode: 'standalone',
  }),
});

สร้าง Server Island Component

---
// src/components/UserGreeting.astro
import { getCurrentUser } from '../lib/auth';

const user = await getCurrentUser(Astro.request);
---

{user ? (
  <p>สวัสดี, {user.name}!</p>
) : (
  <a href="/login">เข้าสู่ระบบ</a>
)}

ใช้งานใน Static Page

---
// src/pages/product/[id].astro
import Layout from '../../layouts/Layout.astro';
import UserGreeting from '../../components/UserGreeting.astro';
import ProductInfo from '../../components/ProductInfo.astro';

const { id } = Astro.params;
---

<Layout title="Product">
  <!-- ส่วนนี้ render ที่ build time — fast -->
  <ProductInfo id={id} />

  <!-- server:defer = Server Island — render per request -->
  <UserGreeting server:defer>
    <!-- fallback แสดงขณะรอ server response -->
    <div slot="fallback">กำลังโหลด...</div>
  </UserGreeting>
</Layout>

server:defer Directive

server:defer คือ directive สำคัญที่ทำให้ component กลายเป็น Server Island:

  • หน้าหลัก render เร็วตามปกติ (static)
  • Browser fetch component นี้แยกจาก server
  • ใส่ slot="fallback" เพื่อแสดง skeleton/loading ขณะรอ

Use Cases

ใช้ Server Islandsใช้ Static
ข้อมูล user-specificProduct listing
ราคาแบบ real-timeBlog content
จำนวน like/viewNavigation
Shopping cart countHero section

เปรียบกับ Astro Islands (client-side)

Astro IslandsServer Islands
Render ที่Browser (client JS)Server (per request)
ข้อมูลจาก API callจาก server directly
CacheBrowser cacheServer/CDN cache
SEOJS requiredServer-rendered HTML
directiveclient:load, client:idleserver:defer

ข้อจำกัด

  • ต้องการ server adapter (ไม่ใช่ pure static build)
  • เพิ่ม latency ของ component นั้นๆ (network round-trip)
  • ซับซ้อนกว่า static page ในการ debug
  • ยังไม่รองรับ GitHub Pages, Netlify static deploy