> ## Documentation Index
> Fetch the complete documentation index at: https://docs.blockli.app/llms.txt
> Use this file to discover all available pages before exploring further.

# defineBlokkli() — Register and Configure a Block

> API reference for the defineBlokkli() compiler macro. Registers a Vue SFC as a blökkli block, declares its bundle, options, and editor behavior.

`defineBlokkli()` is a compiler macro and composable auto-imported by the blökkli Nuxt module. Call it inside `<script lang="ts" setup>` in every block component to register the component as a blökkli block and declare its options. At build time, blökkli reads your `defineBlokkli()` calls to generate typed option resolvers, chunk manifests, and editor metadata.

## Signature

```typescript theme={null}
function defineBlokkli(options: BlokkliOptions): { options: ComputedRef<ResolvedOptions> }
```

## Parameters

<ParamField path="bundle" type="string" required>
  The unique bundle identifier for this block type. Must exactly match the bundle string in your block data (e.g. the paragraph machine name in Drupal, or the `type` field from your API).

  **Examples:** `'text'`, `'hero'`, `'image-gallery'`
</ParamField>

<ParamField path="options" type="object">
  Local option definitions for this block. Each key is an option name; each value is an option definition object. Options are rendered as controls in the blökkli editor sidebar. The resolved values are returned as a reactive `ComputedRef` by `defineBlokkli()`.

  See [Block Options](/blocks/block-options) for all available option types (`radios`, `checkbox`, `range`, `select`, `text`, and more) and their full configuration properties.
</ParamField>

<ParamField path="globalOptions" type="string[]">
  An array of global option keys to include on this block. Global options are defined once in `nuxt.config.ts` under `blokkli.globalOptions` and reused across all blocks that opt in — useful for shared concerns like color scheme or spacing scale.

  ```typescript theme={null}
  // nuxt.config.ts
  blokkli: {
    globalOptions: {
      colorScheme: {
        type: 'radios',
        label: 'Color scheme',
        default: 'light',
        options: { light: 'Light', dark: 'Dark' },
      },
    },
  }
  ```

  ```typescript theme={null}
  // In a block component
  defineBlokkli({
    bundle: 'hero',
    globalOptions: ['colorScheme'],
  })
  ```
</ParamField>

<ParamField path="editor" type="object">
  Override editor behaviors for this specific block. All properties are optional.

  <Expandable title="editor properties">
    <ParamField path="disableEdit" type="boolean">
      If `true`, clicking the edit icon in the editor toolbar for this block does nothing. Use this for layout or structural blocks that don't expose an editable form.
    </ParamField>

    <ParamField path="editTitle" type="string | ((props: BlockProps) => string)">
      Custom label shown for this block in the editor panel. Accepts a static string or a function that receives the block's current props and returns a string — useful for showing dynamic content like a heading value as the block title.

      ```typescript theme={null}
      editor: {
        editTitle: (props) => props.title || 'Card',
      }
      ```
    </ParamField>
  </Expandable>
</ParamField>

<ParamField path="chunkName" type="string">
  Named async chunk for code splitting. Blocks that share the same `chunkName` are bundled into a single lazy-loaded chunk. Group blocks that are typically used together (e.g. all form-related blocks) to reduce the number of network requests on first load.
</ParamField>

<ParamField path="renderFor" type="object[]">
  A constraint array that limits where this block is rendered. Each entry is an object specifying conditions such as entity type or bundle. Blocks are only rendered when their constraints match the current context; non-matching blocks are skipped during render.
</ParamField>

## Return Value

`defineBlokkli()` returns an object with a single property:

<ResponseField name="options" type="ComputedRef<ResolvedOptions>">
  Reactive resolved option values. Updates automatically when the user changes options in the editor. Access individual values as `options.value.myOptionKey` in `<script setup>`, or as `options.myKey` directly in templates — Vue unwraps `ComputedRef` automatically in template expressions.
</ResponseField>

```typescript theme={null}
const { options } = defineBlokkli({ bundle: 'card', options: { /* ... */ } })

// In <script setup>: access via options.value.myKey
// In <template>:     access via options.myKey  (Vue auto-unwraps)
```

## Full Example

The following component demonstrates a `card` block with three local options and one global option:

```vue theme={null}
<template>
  <article
    :class="['card', `card--${options.variant}`]"
    :style="{ '--gap': `${options.gap}px` }"
  >
    <img v-if="options.showImage && image" :src="image" alt="" />
    <h2>{{ title }}</h2>
    <p>{{ body }}</p>
  </article>
</template>

<script lang="ts" setup>
defineProps<{
  title: string
  body: string
  image?: string
}>()

const { options } = defineBlokkli({
  bundle: 'card',
  globalOptions: ['colorScheme'],
  options: {
    variant: {
      type: 'radios',
      label: 'Card variant',
      default: 'default',
      options: { default: 'Default', featured: 'Featured', compact: 'Compact' },
    },
    showImage: {
      type: 'checkbox',
      label: 'Show image',
      default: true,
    },
    gap: {
      type: 'range',
      label: 'Inner gap',
      default: 16,
      min: 0,
      max: 48,
    },
  },
})
</script>
```

In the editor, blökkli automatically renders a **Radios** control for `variant`, a **Checkbox** for `showImage`, and a **Range slider** for `gap` in the options sidebar — with no additional configuration required.
