Block options

The eight option types a block can declare, json as the escape hatch, options shared across blocks with globalOptions, and the display modes radios can take.

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.

app/components/blokkli/hero/index.vue
<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:

typeEditor controlNotes
checkboxSingle toggledefault is a boolean.
checkboxesMulti-selectRequires options: Record<string, string>; default is a string array.
textText inputOptional inputType: 'text' | 'number' | 'date'.
colorColour pickerdefault is a hex string.
radiosSegmented choiceRenders as colours, a grid, plain radios, or icons — see display modes.
rangeSliderRequires a [min, max] range.
numberNumber inputBounds optional; supports nullable: true.
datetime-localDate 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:

TypeScript
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:

DisplayUse it for
Plain radiosA short list of named choices — the default.
ColoursA choice between swatches, where the label is the colour's name.
GridLayout choices, where the shape of the option communicates the result.
IconsAlignment, 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:

nuxt.config.ts
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:

Vue
<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

Was this page helpful?