Single-file Components
The Vite plugin in the project checkout compiles .sprig files into Sprig DOM calls. A component can contain <script setup>, one single-root <template>, and optional style blocks:
html
<script setup>
import { signal } from 'sprig-framework';
const [count, setCount] = signal(0);
</script>
<template>
<button class="counter" @click="setCount(count() + 1)">
Clicked {{ count() }} times
</button>
</template>
<style scoped>
.counter { color: seagreen; }
</style>The script block is JavaScript (not TypeScript). Templates must have exactly one root element. Plain <style> blocks are global; <style scoped> scopes selectors to the component's rendered elements.
Supported template syntax
- Text interpolation:
. - Reactive attributes:
:attribute="expression". - Native events:
@click="handler()",on:click="handler()", or@on:click="handler($event)". - Conditional rendering:
@if="condition()"followed immediately (apart from whitespace) by@else. Only the active branch is mounted. - Keyed loops:
@for="item of items()" :key="item.id". Keys are required; inside a row, an item is an accessor (for example, useitem()oritem.name). The existingeach="item of items()" :key="item.id"form is also supported. - Visibility without removal:
@show="condition()". - Element references:
@ref="callback"; the callback receives the element and laternullwhen its owner is disposed. - Two-way input bindings:
@bind="getter, setter",@bind:value="getter, setter", or@bind:checked="getter, setter".bind:valueandbind:checkedare also accepted. Bindings supportvalueandchecked; arbitrary binding expressions are not implemented. - Slots and imported
.sprigcomponents, including props, default children, and named slots. use:visibleIslandfor deferring a component loader until its placeholder is visible.
Example conditional and keyed list:
html
<template>
<main>
<p @if="connected()">Connected</p>
<p @else>Not connected</p>
<ul>
<li @for="item of items()" :key="item.id">{{ item.name }}</li>
</ul>
</main>
</template>@for cannot share an element with each, @if, or @else. Use a distinct key for each row. The compiler implements a focused template subset; it is not a full Vue or Svelte compiler. See specifications and limits before relying on unsupported syntax.