Astro 5 Server Islands & Content Layer API: Apa yang Baru

Foto oleh Simon Spring on Unsplash
Server Islands adalah komponen yang Anda tandai dengan direktif server:defer agar dirender di server per permintaan sementara sisa halaman tetap di-cache dan statis. Kerangka statis disajikan seketika, lalu island yang ditunda mengambil kontennya sendiri dan masuk ke tempatnya. Ini membuat bagian personalisasi seperti avatar dan keranjang belanja bisa hidup berdampingan dengan caching seluruh halaman.
Content Layer API, yang stabil di Astro 5, membuat koleksi konten mendeklarasikan loader alih-alih terikat pada folder tetap, sehingga bisa menarik dari berkas, satu berkas JSON/YAML/TOML, CMS, atau API apa pun. Ia memakai loader bawaan seperti glob() dan file() dengan skema Zod untuk keamanan tipe. Astro melaporkan situs padat Markdown build hingga 5x lebih cepat, MDX hingga 2x lebih cepat, dan pemakaian memori turun 25 hingga 50 persen.
astro:env menggantikan akses longgar ke process.env dengan skema bertipe yang Anda deklarasikan di astro.config memakai envField. Setiap variabel menyatakan konteksnya (client atau server), tingkat akses (public atau secret), dan tipe (string, number, boolean, atau enum). Anda mengimpor dari astro:env/client atau astro:env/server, dan rahasia tidak pernah dibundel ke kode klien — variabel client rahasia mustahil diungkapkan.
Arsitektur islands Astro merender setiap halaman menjadi HTML statis saat build dan hanya menghidrasi komponen yang secara eksplisit Anda tandai dengan direktif seperti client:load atau client:visible. Selebihnya dikirim tanpa JavaScript klien sama sekali. Itulah alasan halaman Astro cenderung mendapat skor bagus di Core Web Vitals tanpa banyak penyetelan — cukup karena skrip yang harus diurai dan dijalankan lebih sedikit.
Ya. Server Islands dirender on-demand, jadi Anda perlu adapter untuk rendering on-demand, dan prop island harus dapat diserialisasi (tidak boleh fungsi). Prop berjalan sebagai query string terenkripsi pada permintaan GET, tetapi browser membatasi URL sekitar 2048 byte, sehingga prop terlalu besar beralih ke POST yang tidak bisa di-cache. Untuk deployment bergulir, setel ASTRO_KEY agar prop terenkripsi tetap bisa didekode di seluruh instans.

Foto oleh Simon Spring on Unsplash
Ringkasan Utama
Astro 5, dirilis Desember 2024, mempertahankan arsitektur islands tanpa JavaScript secara default sambil menambahkan tiga fitur utama: Server Islands menggabungkan HTML statis yang di-cache dengan komponen dinamis per permintaan, Content Layer API yang stabil memuat koleksi dari sumber mana pun dengan build lebih cepat, dan astro:env memberi variabel lingkungan bertipe yang sadar konteks.
Astro membangun reputasinya di atas satu gagasan: kirim HTML, bukan runtime framework. Arsitektur islands-nya merender setiap halaman menjadi markup statis saat build dan hanya menghidrasi komponen interaktif yang secara eksplisit Anda tandai, sehingga halaman konten biasa sampai ke browser tanpa JavaScript sama sekali. Itu kontras yang disengaja dengan framework single-page yang menghidrasi seluruh pohon komponen entah widget membutuhkannya atau tidak.
Ketegangan dengan model itu selalu soal data dinamis. Jika halaman sepenuhnya statis, dari mana avatar pengguna yang login atau keranjang belanja langsung muncul? Astro 5, yang dirilis pada 3 Desember 2024, menjawabnya dengan Server Islands, dan memasangkannya dengan Content Layer API yang stabil serta variabel lingkungan bertipe. Saya sudah menjalankannya di produksi sejak upgrade, dan ketiga fitur inilah yang mengubah cara saya menyusun proyek.
Model mentalnya perlu diulang karena semua di Astro 5 dibangun di atasnya. Sebuah halaman adalah lautan HTML statis dengan pulau-pulau kecil interaktivitas yang mengambang di dalamnya. Setiap island independen: ia menghidrasi sesuai jadwalnya sendiri, dan sisa halaman tidak pernah mengirim JavaScript klien sama sekali. Anda mengaktifkan komponen ke sisi klien dengan direktif seperti client:load atau client:visible, dan tidak ada yang lain membayar beban hidrasi.
Inilah alasan halaman Astro cenderung mendapat skor bagus di Core Web Vitals tanpa banyak penyetelan. Cukup sederhana karena JavaScript yang harus diurai dan dijalankan lebih sedikit. Output default framework tetap statis, yang ditegaskan kembali oleh catatan rilis — perilaku dinamis adalah sesuatu yang Anda tambahkan per rute dengan adapter, bukan baseline yang harus Anda lawan.
Server Islands memperluas gagasan islands ke server. Anda menjaga seluruh halaman tetap di-cache dan statis, tetapi menandai komponen tertentu dengan direktif server:defer agar dirender di server per permintaan. Kerangka statis disajikan seketika dari cache; island yang ditunda mengambil kontennya sendiri setelahnya lalu masuk ke tempatnya. Bagian yang dipersonalisasi seperti avatar, keranjang, dan rekomendasi berhenti memaksa seluruh halaman tidak bisa di-cache.
---
// src/pages/index.astro
import Avatar from "../components/Avatar.astro";
import GenericAvatar from "../components/GenericAvatar.astro";
---
<html>
<body>
<!-- Cached, static shell renders instantly -->
<h1>Welcome back</h1>
<!-- Dynamic island: deferred, rendered per-request on the server -->
<Avatar server:defer>
<GenericAvatar slot="fallback" />
</Avatar>
</body>
</html>Island yang ditunda merender konten cadangan terlebih dahulu, memakai slot fallback bernama, sehingga pembaca langsung melihat placeholder alih-alih lubang di tata letak. Di balik layar Astro menukar komponen yang ditandai dengan skrip kecil saat build, lalu memuat komponen aslinya lewat rute khusus. Prop dikirim sebagai query string terenkripsi pada permintaan GET, yang berarti respons island bisa di-cache dengan header Cache-Control biasa.
Server Islands membutuhkan adapter untuk rendering on-demand, dan prop harus dapat diserialisasi — tidak boleh fungsi. Jika deployment bergulir bisa menukar server di tengah permintaan, setel ASTRO_KEY agar kunci enkripsi tetap stabil di seluruh instans dan prop terenkripsi tetap bisa didekode.
Prop terenkripsi berjalan di dalam URL, dan browser membatasi URL sekitar 2048 byte. Prop yang terlalu besar memaksa Astro beralih ke permintaan POST, yang tidak di-cache browser — jadi jaga prop island tetap kecil bila Anda ingin manfaat caching. Kirim sebuah id lalu ambil ulang datanya, bukan mengirim seluruh objek.
Content Layer API menjadi stabil di Astro 5, dan ini benar-benar memikirkan ulang koleksi konten. Alih-alih terikat pada berkas di direktori tetap, sebuah koleksi kini mendeklarasikan sebuah loader. Loader bawaan mencakup kasus umum: glob() membaca banyak berkas yang cocok dengan pola dari direktori dasar mana pun, dan file() membaca entri dari satu berkas JSON, YAML, atau TOML. Loader kustom bisa menarik dari CMS atau API apa pun.
// src/content.config.ts
import { defineCollection } from "astro:content";
import { glob } from "astro/loaders";
import { z } from "astro/zod";
const blog = defineCollection({
// Load Markdown from anywhere on disk with the glob() loader
loader: glob({ pattern: "**/*.md", base: "./src/data/blog" }),
schema: z.object({
title: z.string(),
description: z.string(),
pubDate: z.coerce.date(),
}),
});
export const collections = { blog };Skema tetap gagasan yang sama seperti sebelumnya — objek Zod yang memvalidasi frontmatter atau data setiap entri, memberi Anda hasil bertipe dan galat saat build ketika konten menyimpang dari bentuk yang Anda deklarasikan. Anda mendefinisikan koleksi di src/content.config.ts dan mengekspornya di bawah objek collections.
---
// Query the collection anywhere — fully typed
import { getCollection } from "astro:content";
const posts = await getCollection("blog");
---
<ul>
{posts.map((post) => <li>{post.data.title}</li>)}
</ul>Kueri tetap sama secara semangat: getCollection mengembalikan array yang sepenuhnya bertipe, sehingga post.data.title diperiksa terhadap skema Anda di editor. Hasil dari penulisan ulang ini adalah kecepatan dan memori. Rilis melaporkan situs padat Markdown build hingga 5x lebih cepat dan MDX hingga 2x lebih cepat, dengan pemakaian memori turun 25 hingga 50 persen — angka nyata pada jenis situs konten yang jadi sasaran Astro.
Akses longgar ke process.env adalah sumber klasik kejutan saat runtime: salah ketik, rahasia tak sengaja terbundel ke klien, string padahal seharusnya angka. astro:env menggantinya dengan skema yang Anda deklarasikan di astro.config memakai helper envField. Setiap variabel menyatakan konteksnya — client atau server — dan tingkat aksesnya — public atau secret — plus tipe: string, number, boolean, atau enum.
// astro.config.mjs
import { defineConfig, envField } from "astro/config";
export default defineConfig({
env: {
schema: {
API_URL: envField.string({ context: "client", access: "public" }),
PORT: envField.number({ context: "server", access: "public", default: 4321 }),
API_SECRET: envField.string({ context: "server", access: "secret" }),
},
},
});Anda lalu mengimpor variabel dari astro:env/client atau astro:env/server, dan pemisahannya ditegakkan. Variabel client publik bisa dibaca di mana saja; variabel server publik dan rahasia hanya di server, dan rahasia tidak pernah dibundel ke kode klien. Tidak ada yang namanya variabel client rahasia, karena tidak ada cara aman mengirimnya ke browser — API ini membuat kesalahan itu mustahil diungkapkan.
---
// Type-safe imports, split by where they are allowed to run
import { API_URL } from "astro:env/client";
import { API_SECRET } from "astro:env/server";
const res = await fetch(API_URL + "/users", {
headers: { Authorization: "Bearer " + API_SECRET },
});
---Untuk rahasia yang namanya tidak diketahui saat build, astro:env/server menyediakan getSecret, yang mengembalikan nilai mentah atau undefined saat runtime. Pakai ini hanya bila entri skema statis benar-benar tak bisa menggambarkan variabelnya — field bertipe adalah default yang lebih aman.
Dalam praktik fitur-fitur ini menyatu dengan rapi. Sebagian besar situs adalah island statis tanpa JavaScript, sehingga di-cache di edge dan memuat cepat. Satu atau dua fragmen yang dipersonalisasi menjadi Server Islands, sehingga personalisasi tak lagi merusak caching. Konten datang lewat Content Layer dari Markdown dan CMS headless berdampingan, divalidasi oleh satu skema Zod. Dan setiap kunci API yang merangkainya dideklarasikan sekali di astro:env, bertipe dan bercakupan, alih-alih tersebar di pembacaan process.env mentah.
| Aspek | Client island | Server island |
|---|---|---|
| Tempat render | Di browser setelah hidrasi | Di server, per permintaan |
| Mengirim JavaScript klien | Ya — komponen dan runtime framework | Tidak — hanya skrip loader kecil |
| Direktif | client:load, client:visible, dan sejenisnya | server:defer |
| Butuh adapter | Tidak | Ya — untuk rendering on-demand |
| Paling cocok | UI interaktif: menu, slider, formulir | Data personalisasi di halaman yang di-cache |
Astro 5 tidak meninggalkan filosofi tanpa JS demi mengejar fitur dinamis — ia memperluas metafora islands ke server sehingga keduanya bisa hidup berdampingan. Jika terakhir kali Anda melihat Astro sebelum Desember 2024, Server Islands dan Content Layer yang stabil sudah jadi alasan cukup untuk melihat lagi. Mulailah dengan mengubah satu fragmen personalisasi menjadi server:defer dan perhatikan sisa halaman tetap di-cache.