Overview
SiteX renders components statically unless an imported component uses a client directive.
Client directives only work on imported React components. Do not put them on HTML elements or components declared in the same file.
Choosing Directives
Use the least eager directive that still matches the interaction.
- Use
client:loadfor controls that must be interactive as soon as possible. - Use
client:idlefor page chrome that is already useful as static HTML, such as a sidebar or theme-aware shell. - Use
client:visiblefor below-the-fold widgets and repeated controls, such as copy buttons in long documentation pages. - Use
client:mediafor viewport-specific UI that should hydrate only when a media query matches.
client:load
Hydrates immediately.
import Search from "@/components/search"
export default function Page() {
return <Search client:load />
}client:only
Renders only in the browser.
import Search from "@/components/search"
export default function Page() {
return <Search client:only />
}client:visible
Hydrates when the component enters the viewport.
import CopyButton from "@/components/copy-button"
export default function Page() {
return <CopyButton client:visible value="pnpm build" />
}client:idle
Hydrates after the browser has idle time.
import Sidebar from "@/components/sidebar"
export default function Page() {
return <Sidebar client:idle />
}client:media
Hydrates after a media query matches.
import DesktopNav from "@/components/desktop-nav"
export default function Page() {
return <DesktopNav client:media="(min-width: 64rem)" />
}Boundaries
Island roots must be imported React components.
Props must be JSON-serializable data. Functions, symbols, cyclic values, and React elements cannot cross the static-to-client boundary as props.
Children are rendered as static slot HTML. If those children contain another island, it renders independently with its own client boundary.