Sunucu adaları
Bu sayfada
Bazen başka türlü statik olan bir sayfanın tek bir bölgesi taze, isteğe özgü veri ister — önbelleğe alınmış bir blog yazısının altındaki yorumlar, bir ürün sayfasındaki stok rozeti. Sunucu adaları sayfayı statik tutar ve sayfa görüntülendiğinde yalnızca o bölgeyi bir sunucuda işler.
1. Adayı yazın
Bir ada, src/islands/ altındaki bir parça modülüdür — düz bir .js ya da .ts dosyası (.ht.js değil, çünkü adalar sayfa değil parçadır). sitelo’nun her yerindeki fikrin aynısı: HTML döndüren bir fonksiyon.
export default async function comments({ props, request }) {
const comments = await fetchComments(props.postId)
return `<ul>${comments.map((c) => `<li>${c.text}</li>`).join('')}</ul>`
}{ name, props, request } alır ve bir HTML dizesi döndürmelidir. Ada modülleri yalnızca sunucuya aittir — src/ altındaki başvurulmayan kod tarayıcıya hiç gönderilmez.
2. Sayfaya yerleştirin
sitelo/islands içinden island() içe aktarın. Statik derleme yedek HTML’i yayımlar; proplar yer tutucuya gömülür, bu yüzden onları küçük ve gizli olmayan tutun.
import { island } from 'sitelo/islands'
export default ({ params }) => `
<html>
<body>
<article>…statik içerik…</article>
${island('comments', { postId: params.slug }, '<p>Yorumlar yükleniyor…</p>')}
<script type="module" src="/islands.js"></script>
</body>
</html>
`import { html, body, article, script } from 'javascript-to-html'
import { island } from 'sitelo/islands'
export default ({ params }) =>
html(
body(
article('…statik içerik…'),
island('comments', { postId: params.slug }, '<p>Yorumlar yükleniyor…</p>'),
script({ type: 'module', src: '/islands.js' }),
),
)import { island } from 'sitelo/islands'
export default function Post({ params }) {
return (
<html>
<body>
<article>…statik içerik…</article>
{island('comments', { postId: params.slug }, '<p>Yorumlar yükleniyor…</p>')}
<script type="module" src="/islands.js" />
</body>
</html>
)
}3. İstemci yükleyicisini ekleyin
Küçük bir betik, işlenen her parçayı getirir ve yerine koyar. Normal varlık hattından geçer, bu yüzden düz bir src/islands.js girişi yeterlidir:
import { mountIslands } from 'sitelo/islands/client'
mountIslands()sitelo (geliştirme) ve sitelo preview içinde bu zaten çalışır — ikisi de adaları src/islands/ dizininden /_sitelo/islands/<name> adresinde sunar. Önizleme yerel .js / .mjs modüllerini yükler (bir Node sunucusuyla aynı); TypeScript adaları geliştirmede Vite üzerinden desteklenir.
Üretim
Statik sunucunuz sayfaları sunmayı sürdürür. Sunucu kodu çalıştırdığınız yere küçük bir işleyici bağlayın — Node, sunucusuz ya da bir kenar fonksiyonu — ve aynı ada modüllerini işlesin. Çalıştırılabilir bir Node sunucusu ile Netlify ve Vercel taslaklarını içeren tam bir anlatım için Sunucu adaları örneğine bakın.
// örneğin bir Node sunucusu ya da bir serverless/edge işlevi
import { createIslandsHandler } from 'sitelo/islands/server'
const handleIslands = createIslandsHandler({
islands: {
comments: () => import('./src/islands/comments.js'),
},
})
// web Request → Response | null (null = ada isteği değil)
export default { fetch: (request) => handleIslands(request) }Düz Node http ya da express üzerinde bunun yerine createIslandsNodeHandler(options) kullanın — aynı seçenekler, (req, res, next) imzası. src/islands/ altındaki her .js / .mjs modülünü createIslandsFromDirectory ile kendiliğinden bağlayın. Yükleyici farklı bir kaynaktan ya da yoldan getiriyorsa mountIslands({ endpoint: 'https://api.example.com/islands' }) geçirin ve işleyicinin endpoint seçeneğiyle eşleştirin.
Kararlılık listesi
island()/mountIslands()/createIslandsHandler/createIslandsNodeHandler— genel API, kararlı sayılırsitelovesitelo previewikisi de/_sitelo/islandsadresinisrc/islands/dizininden sunarcreateIslandsFromDirectory— Node sunucuları ve önizleme için aynı eşleme (yerel.js/.mjs/.cjs)- Sunucu adaları örneğindeki sunucu taslakları: Node
server.js, Netlify fonksiyonu + yeniden yazma, Vercel sunucusuz + yeniden yazma - Proplar küçük ve gizli olmayan kalır (GET sorgu dizesi) — bu kasıtlıdır; sırları adanın içinde, sunucuda getirin
- Proplar istemciden gelir — doğrulayın ya da
SITELO_ISLANDS_SECRETile imzalayın
Yükleme stratejileri
Varsayılan olarak her ada sayfa yüklenir yüklenmez getirir, bu yüzden sekiz adalı bir sayfa ilk boyama sırasında sekiz eşzamanlı istek yapar. Hemen görünmeyenleri ertelemek için when geçirin.
// Sayfa yüklenir yüklenmez yükle — varsayılan.
island('cart', { id }, '<p>…</p>')
// Boşta kalma geri çağrısını bekle.
island('recommendations', { id }, '<p>…</p>', { when: 'idle' })
// Görünüme girene dek bekle.
island('comments', { postId }, '<p>Yorumlar yükleniyor…</p>', {
when: 'visible',
rootMargin: '400px', // 400px erken yüklemeye başla
})'load'(varsayılan) — hemen, diğer her adayla birlikte'idle'—requestIdleCallbackanında (zaman aşımına geri düşer)'visible'— IntersectionObserver aracılığıyla, görünüme kaydığında
rootMargin yalnızca 'visible' için geçerlidir ve varsayılanı '200px' değeridir. Adalar sonsuza dek dönmek yerine zaman aşımına da uğrar:
mountIslands({
timeout: 5000, // ada başına; 0 devre dışı bırakır. Varsayılan 10000
rootMargin: '300px', // `when: 'visible'` adaları için varsayılan
})mountIslands() anlık adalar yerine oturduğunda çözülür — ertelenenler kendi başlarına sonradan yüklenir ve bilerek beklenmez. Başarısız olan ya da zaman aşımına uğrayan bir ada yedek HTML’ini korur.
Proplar güvenilmez girdidir
Ada propları istemciden gelir. Sayfaya gömülür, istekte geri gönderilir ve herkes önce onları düzenleyebilir:
GET /_sitelo/islands/profile?props={"userId":"someone-else"}Adanızın aldığı propları tam olarak bir sorgu parametresi gibi değerlendirin — doğrulayın ve onları, görüntüleyenin görmeye zaten hakkı olmayan verileri aramak için asla kullanmayın.
Proplar ayrıcalıklı veri seçiyorsa onları imzalayın. Bir sır belirleyin; sitelo her yer tutucuyu derleme sırasında imzalar ve başka her şeyi bir 403 ile reddeder:
SITELO_ISLANDS_SECRET=$(openssl rand -hex 32) sitelo buildAynı değişkeni sitelo, sitelo preview ve createIslandsHandler okur, böylece geliştirme, önizleme ve üretim uyuşur. Üretim sunucunuza aynı sırrı verin. Kod içinde ayarlamayı mı tercih edersiniz?
import { configureIslands } from 'sitelo/islands'
configureIslands({ secret: process.env.MY_SECRET })İmzalar, ada adı ve propları üzerinde HMAC-SHA256’dır; bu yüzden bir ada için verilen bir imza bir başkasına karşı yeniden oynatılamaz. İmzalama, propların sizin derlemenizden geldiğini kanıtlar — onları gizlemez, dolayısıyla yine de gizli olmamaları gerekir. Sır olmadan proplar olduğu gibi kabul edilir ve onları doğrulamak tümüyle ada modülünüzün işidir.
Bilmekte fayda var
- Ada uç noktası dağıtılmadı mı? Yedek HTML olduğu gibi kalır — sayfalar zarifçe geriler.
- İstekler, propları sorgu dizesinde taşıyan
GETistekleridir, bu yüzden yanıtlar önbelleğe alınabilir — bir CDN’in parçaları kısa süre tutmasını istiyorsanız işleyicinincacheControlseçeneğini ayarlayın. - Yüklenirken yer tutucu
data-sitelo-island-state="loading"taşır (sonraloadedya daerror) — CSS için kullanışlıdır.