Skip to main content
<BlokkliProvider> is the root component that establishes the editing context for a content entity. It tells blökkli which entity is being displayed, whether the current user is allowed to edit it, and (optionally) which language is active. All <BlokkliField> components must be descendants of a provider — they rely on the context it provides to register themselves with the editor. You typically place one <BlokkliProvider> per page, wrapping all editable regions.

Basic Usage

<template>
  <BlokkliProvider
    :entity="{
      entity_type: 'node',
      entity_bundle: 'page',
      entity_uuid: page.uuid,
    }"
    :can-edit="userCanEdit"
  >
    <BlokkliField :list="page.blocks" name="blocks" />
  </BlokkliProvider>
</template>

<script setup>
const { userCanEdit } = useAuth() // your own auth composable
</script>

Props

entity
object
required
Describes the content entity this provider wraps. blökkli uses these values to load the correct editor state, persist changes through your adapter, and scope field configurations. The object must include all three of the following properties:
entity.entity_type
string
required
The entity type identifier — for example 'node', 'page', or 'product'. This should match the entity type strings your adapter and getFieldConfig() use.
entity.entity_bundle
string
required
The entity bundle identifier — for example 'article', 'landing_page', or 'blog_post'. Used together with entity_type to look up field configurations.
entity.entity_uuid
string
required
The unique identifier for this specific entity instance. blökkli appends this to the ?blokkliEditing query parameter to activate the editor for the right entity. Use a UUID or any other stable unique string.
can-edit
boolean
required
Whether the current user has permission to edit this entity. When false, blökkli never activates the editor UI, even if the ?blokkliEditing query parameter is present in the URL. When true, visiting the page with the correct query parameter opens the editor.Derive this value from your application’s own authentication and authorisation logic.
language
string
The BCP 47 language code for the content currently being displayed — for example 'en', 'de', or 'fr-CH'. Pass this when your site uses blökkli’s translations feature so the editor can associate changes with the correct language variant.
<BlokkliProvider
  :entity="entity"
  :can-edit="canEdit"
  language="de"
>
  <!-- ... -->
</BlokkliProvider>

Activating the Editor

With can-edit set to true, navigate to your page URL and append ?blokkliEditing={entity_uuid}:
https://yoursite.com/about?blokkliEditing=f7a3c21b-4d92-4f3a-b1e0-9c8d7f6a5b23
blökkli detects this query parameter on page load, matches the UUID to the provider’s entity.entity_uuid, and activates the full editor overlay.
1

Set can-edit to true

Make sure your auth logic resolves can-edit to true for the current user. This is the gating condition — without it the editor never loads regardless of the URL.
2

Navigate to the page with the query parameter

Append ?blokkliEditing={entity_uuid} to the page URL. You can add an “Edit page” button to your site’s navigation toolbar that constructs this URL automatically.
3

Editor overlay activates

blökkli boots the editor, highlights all <BlokkliField> regions, and loads the editor toolbar. You’re ready to add, reorder, and configure blocks.
Never set can-edit to true unconditionally. Always derive it from a server-side session check or a trusted auth composable. If can-edit is hardcoded to true, any visitor who constructs a ?blokkliEditing URL can access the editor and modify your content.

Nesting Providers

You can nest <BlokkliProvider> components for cases where blocks themselves contain editable sub-entities — for example, a reusable “Teaser” content item rendered inside a block, where the teaser has its own independent block fields:
<!-- components/Blokkli/TeaserReference.vue -->
<template>
  <BlokkliProvider
    :entity="{
      entity_type: 'teaser',
      entity_bundle: teaser.type,
      entity_uuid: teaser.uuid,
    }"
    :can-edit="canEditTeaser"
  >
    <BlokkliField :list="teaser.blocks" name="teaser_content" />
  </BlokkliProvider>
</template>

<script lang="ts" setup>
defineProps<{
  teaser: { uuid: string; type: string; blocks: BlockItem[] }
}>()

const canEditTeaser = useCanEdit('teaser') // your own logic

defineBlokkli({
  bundle: 'teaser_reference',
})
</script>
Each provider maintains its own isolated editing context. The outer provider’s editor state does not bleed into the inner provider, and vice versa. This means you can have independent save/discard cycles for each entity on the page.
Nesting providers is an advanced pattern. For most sites with a single editable entity per page, one top-level provider wrapping all fields is all you need.

Usage with Nuxt <NuxtPage>

If you’re wrapping entire page content, place <BlokkliProvider> inside your page component rather than in a layout. This ensures the provider receives the correct per-page entity data:
<!-- pages/[...slug].vue -->
<template>
  <BlokkliProvider
    :entity="{
      entity_type: 'node',
      entity_bundle: page.bundle,
      entity_uuid: page.uuid,
    }"
    :can-edit="$auth.can('edit', page)"
  >
    <PageHeader :title="page.title" />
    <BlokkliField :list="page.blocks" name="blocks" />
    <PageFooter />
  </BlokkliProvider>
</template>
Only <BlokkliField> components need to be inside the provider — surrounding elements like headers and footers can live inside or outside it without affecting editor behaviour.