Skip to content

Astro components

@static-bloom/astro ships three framework-free components. Import them by path:

---
import Layout from '@static-bloom/astro/components/Layout.astro'
import FlavorSelect from '@static-bloom/astro/components/FlavorSelect.astro'
import FlavorScript from '@static-bloom/astro/components/FlavorScript.astro'
---

A complete HTML document for pages outside Starlight. The body gets the canvas background, the body text color, the sans font and the base line height; it adds no grid and no landmarks, so your page owns its structure.

<Layout title="Settings" description="Choose your appearance." class="settings">
<link slot="head" rel="icon" href="/favicon.svg" />
<main class="sb-container sb-stack">…</main>
</Layout>
Prop Default Effect
title 'Static Bloom' The <title>
description none A <meta name="description">
lang 'en' lang on <html>
flavor none Initial data-flavor and data-theme in the server HTML
accent none Initial data-accent in the server HTML
class none Classes on <body>

The default slot is the page; the head slot adds elements to <head>.

Without flavor, the server HTML carries no flavor attribute, so the CSS fallback applies without JavaScript (Midnight, or Daybreak for a light system), and two theme-color metas follow the system color scheme. With flavor, the HTML starts in that flavor and the single theme-color uses its base color. Either way, once a flavor runtime runs it owns the attributes and the meta. For a fixed starting flavor, also set defaultFlavor on the integration or on FlavorScript; a visitor’s stored choice still wins.

Layout renders no flavor script and imports no CSS. The integration provides both; without it, add FlavorScript and import the stylesheet yourself.

A labelled native <select> with Auto and the four flavors, wrapped in an <sb-flavor-select> custom element. It reads and sets the page runtime, and every instance on the page stays in sync through static-bloom:flavor-change. This one controls the site, like the selector in the header:

<FlavorSelect label="Color flavor" class="settings-flavor" />
Prop Default Effect
label 'Color flavor' Visible label and accessible name
class none Classes on the custom element

The control stays disabled until a runtime is available, including when JavaScript is off. It is styled with sb-label and sb-select, so pages that do not load the full CSS need @static-bloom/css/components.css.

The flavor runtime as an inline <script>, for pages that do not use the integration. It accepts the integration’s options as props:

src/pages/standalone.astro
---
import '@static-bloom/css'
import Layout from '@static-bloom/astro/components/Layout.astro'
import FlavorScript from '@static-bloom/astro/components/FlavorScript.astro'
---
<Layout title="Standalone page">
<FlavorScript slot="head" flavors={{ dark: 'dusk' }} accent="ion" />
<main class="sb-container">…</main>
</Layout>

Put it once per page, in the head, so it runs before the first paint. Its styles prop is validated but imports nothing: import the CSS in the page or layout. Do not combine it with the integration, which already injects the same script.

The showcase is built this way: a Layout page in this Starlight project, with FlavorScript, its own stylesheet, the Astro FlavorSelect and Vue islands.