> ## 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.

# BlokkliProvider: Establishing the Block Editing Context

> Wrap editable content with BlokkliProvider to establish the entity context for blökkli. Controls edit permissions and editor state for child fields.

`<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>`](/blocks/field-component) 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

```vue theme={null}
<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

<ParamField path="entity" type="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:

  <ParamField path="entity.entity_type" 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.
  </ParamField>

  <ParamField path="entity.entity_bundle" type="string" required>
    The entity bundle identifier — for example `'article'`, `'landing_page'`, or `'blog_post'`. Used together with `entity_type` to look up field configurations.
  </ParamField>

  <ParamField path="entity.entity_uuid" type="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.
  </ParamField>
</ParamField>

<ParamField path="can-edit" type="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.
</ParamField>

<ParamField path="language" type="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.

  ```vue theme={null}
  <BlokkliProvider
    :entity="entity"
    :can-edit="canEdit"
    language="de"
  >
    <!-- ... -->
  </BlokkliProvider>
  ```
</ParamField>

## Activating the Editor

With `can-edit` set to `true`, navigate to your page URL and append `?blokkliEditing={entity_uuid}`:

```text theme={null}
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.

<Steps>
  <Step title="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.
  </Step>

  <Step title="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.
  </Step>

  <Step title="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.
  </Step>
</Steps>

<Warning>
  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.
</Warning>

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

```vue theme={null}
<!-- 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.

<Note>
  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.
</Note>

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

```vue theme={null}
<!-- 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>
```

<Tip>
  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.
</Tip>
