Block options
Options are the knobs an editor turns — spacing, colour, variant, width — as opposed to content, which comes from props. You declare them on defineBlokkli and read them back from the reactive options object it returns.
<script setup lang="ts">
const { options } = defineBlokkli({
bundle: 'hero',
options: {
align: {
type: 'radios',
label: 'Alignment',
default: 'left',
options: { left: 'Left', center: 'Center' },
},
},
})
</script>
<template>
<section :class="`text-${options.align}`">
<slot />
</section>
</template>
The eight types
The set of option types is closed:
type | Editor control | Notes |
|---|---|---|
checkbox | Single toggle | default is a boolean. |
checkboxes | Multi-select | Requires options: Record<string, string>; default is a string array. |
text | Text input | Optional inputType: 'text' | 'number' | 'date'. |
color | Colour picker | default is a hex string. |
radios | Segmented choice | Renders as colours, a grid, plain radios, or icons — see display modes. |
range | Slider | Requires a [min, max] range. |
number | Number input | Bounds optional; supports nullable: true. |
datetime-local | Date and time picker |
Every type takes label, default, and optionally description and group.
group keeps a busy block usable
Options sharing a group are collapsed into one dropdown in the editor. That is how you keep a block with a dozen knobs from becoming a wall of controls:
options: {
paddingTop: { type: 'range', label: 'Top', default: 4, range: [0, 12], group: 'Spacing' },
paddingBottom: { type: 'range', label: 'Bottom', default: 4, range: [0, 12], group: 'Spacing' },
showBorder: { type: 'checkbox', label: 'Border', default: false, group: 'Appearance' },
}
radios display modes
radios is the type you'll reach for most, and it can present itself four ways depending on what the choice actually is:
| Display | Use it for |
|---|---|
| Plain radios | A short list of named choices — the default. |
| Colours | A choice between swatches, where the label is the colour's name. |
| Grid | Layout choices, where the shape of the option communicates the result. |
| Icons | Alignment, direction, density — anything with a conventional glyph. |
The rule of thumb: if an editor can recognise the choice faster from a shape than from a word, don't use words.
json — the escape hatch
There is a ninth type, json, for complex structured options whose shape is project-specific — a table of tier thresholds, a list of external ids, a nested layout description.
Reach for it only when none of the eight above fit. A json option is a text area holding a structure the editor has to keep valid by hand, so it trades editor ergonomics for expressiveness. If you can decompose the structure into two or three typed options, do that instead.
globalOptions
Some options belong to every block rather than to one — a width in a column grid, a flag for whether the block renders inline. Declaring them per block means duplicating them ninety times and keeping the copies in step.
globalOptions solves that. The theme declares them once in its Blökkli configuration:
export default defineNuxtConfig({
blokkli: {
globalOptions: {
inlineBlock: {
type: 'checkbox',
label: 'Inline Block',
default: true,
},
colSpan: {
type: 'radios',
label: 'Width',
default: '1',
options: {
1: '1 column',
2: '2 columns',
3: '3 columns',
},
},
},
},
})
A block then opts in by name, and the option is merged into its own options object:
<script setup lang="ts">
const { options } = defineBlokkli({
bundle: 'badge',
globalOptions: ['inlineBlock'],
})
// options.inlineBlock is available exactly as a locally declared option would be
</script>
Opting in per block rather than applying globals everywhere is deliberate: an option only shows up in the editor sidebar for blocks that actually respond to it, so an editor never turns a knob that does nothing.
Options versus props, one more time
If you're unsure which a value should be: an option changes how the block looks or behaves; a prop is the thing the block is about. A product grid's sort order is an option. The category it lists is a prop.
Next steps
- How a block works — the full
defineBlokklikey list. - Inline editing — editing props directly on the canvas.
- Shells and fields — blocks that hold other blocks.
- Block catalog — the bundles that already exist, and the options they expose.