Îlot "use client"
Les composants dans src/components/ ou src/islands/ portant une directive "use client" en tête de fichier sont empaquetés pour le navigateur. Le composant retourne une chaîne HTML ; le runtime de montage l'insère dans l'hôte et exécute tout bloc <script> embarqué. C'est l'analogue des React islands dans bext — moins fin que les signaux (le re-rendu remplace tout le DOM interne), mais ergonomique pour les widgets autonomes.
Astuce
Le re-rendu d'un îlot « use client » remplace l'intégralité du DOM interne — les sélecteurs et listeners créés entre deux montages sont perdus. Préférez les signaux lorsque seules des valeurs individuelles changent ; réservez « use client » aux widgets à état complexe ou qui dépendent de bibliothèques tierces.
Résultat
count: 7
"use client";
// Component returns a string. The mount runtime stuffs the HTML
// into the host element AND runs any inline <script> blocks the
// component embeds — that's where interactivity gets wired up.
export default function ClientCounter(props: { initial?: number }): string {
const initial = props.initial ?? 0;
const id = "cc-" + Math.random().toString(36).slice(2, 8);
return `<div id='${id}'>
<p>count: <strong data-c>${initial}</strong></p>
<button data-act='inc'>+1</button>
<button data-act='dec'>−1</button>
</div>
<script>(function(){
var r = document.getElementById('${id}');
var n = ${initial};
var c = r.querySelector('[data-c]');
r.addEventListener('click', function(e) {
var t = e.target.closest('[data-act]');
if (!t) return;
n += t.dataset.act === 'inc' ? 1 : -1;
c.textContent = String(n);
});
})();</script>`;
}import { island } from "@bext-stack/framework/island";
import { Raw } from "@bext-stack/framework/jsx-runtime";
import ClientCounter from "../../../components/ClientCounter";
export default function Page() {
return (
<Raw html={island("ClientCounter", { initial: 7, nonce: 42 }, ClientCounter({ initial: 7, nonce: 42 }))} />
);
}