# Adding editable regions to Bookshop sites (Hugo, Jekyll, and Eleventy)

**URL:** <https://community.cloudcannon.com/t/adding-editable-regions-to-bookshop-sites-hugo-jekyll-and-eleventy/345>\
**Category:** Announcements\
**Tags:** 11ty, hugo, jekyll, bookshop\
**Created:** [December 17, 2025, 2:19am UTC](https://community.cloudcannon.com/t/adding-editable-regions-to-bookshop-sites-hugo-jekyll-and-eleventy/345 "2025-12-17T02:19:33Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![george](https://community.cloudcannon.com/user_avatar/community.cloudcannon.com/george/32/184_2.png) [@george](https://community.cloudcannon.com/u/george)\
**Post date:** [December 17, 2025, 2:19am UTC](https://community.cloudcannon.com/t/adding-editable-regions-to-bookshop-sites-hugo-jekyll-and-eleventy/345/1 "2025-12-17T02:19:33Z")

</div>

If you’re using Bookshop for component management on your Hugo, Jekyll, or Eleventy site, you can now take advantage of a more modern visual editing experience.

Bookshop v3.17.1 introduced the `--editable-regions` flag, which injects a live editing script that allows you to use your existing Bookshop components inside our new editable regions. This brings modern visual editing support to Hugo, Jekyll, and Eleventy sites using Bookshop as a component development workflow.

This guide walks you through updating a website that uses Bookshop to leverage the new editable regions feature.

## Why would you want to use editable regions?

The traditional Bookshop approach used data binding panels, which worked well but was somewhat removed from the actual content you were editing. Editable regions change this by letting you:

- Edit text directly where it appears on the page
- Click on images to change them in context
- Add, remove, and reorder components with visual controls right in the editor
- Get a more intuitive editing experience overall

This migration makes sense if you’re already using Bookshop and want a better visual editing experience. You can also keep using the old approach if it’s working well for you. This is an enhancement, not a requirement.

## Prerequisites

- Bookshop v3.17.1 or later
- A site already using Bookshop for component management

## Step 1: Update Bookshop

Update your Bookshop packages to v3.17.1 or later:

```bash
npm update @bookshop/generate

```

Or update your `package.json` to specify the new version:

```json
{
  "dependencies": {
    "@bookshop/generate": "^3.17.1"
  }
}

```

> Note: Version 3.17.0 has a known issue with the visual editor loading state. Use v3.17.1 or later.

## Step 2: Update Your postbuild command

Modify your `.cloudcannon/postbuild` script to include the `--editable-regions` flag:

**Before:**

```bash
#!/usr/bin/env bash

npx @bookshop/generate

```

**After:**

```bash
#!/usr/bin/env bash

npx @bookshop/generate --editable-regions

```

> Note: This flag also disables the traditional data binding panels. You will need to complete the following steps to get live editing working again.

## Step 3: Update your layout file (optional but recommended)

Wrap your bookshop page include in an `<editable-component>` element. This sets up the data property path for nested editable regions.

### For Jekyll

**Before:**

```auto
{%- include head.html -%}
{% bookshop_include page content_blocks=page.content_blocks %}
{{ content }}
{%- include tail.html -%}

```

**After:**

```auto
{%- include head.html -%}
<editable-component data-prop="content_blocks" data-component="page">
    {% bookshop_include page content_blocks=page.content_blocks %}
</editable-component>
{{ content }}
{%- include tail.html -%}

```

> Why this matters: The data-prop attribute values stack as they go down the DOM tree. By setting data-prop=“content\_blocks” on the wrapper component, nested editable regions can use data-prop=“” (empty string) because the path is already established. If you skip this step, you’ll need to use data-prop=“content\_blocks” on the array element instead.

## Step 4: Update your page templates

Add editable region data attributes to your page templates where you render component arrays.

### For Jekyll

**Before:**

```html
<main>
  {% for block in include.content_blocks %}
    {% bookshop {{block._bookshop_name}} bind=block %}
  {% endfor %}
</main>

```

**After (with Step 3 wrapper):**

```html
<main data-editable="array" data-prop="" data-id-key="_bookshop_name" data-component-key="_bookshop_name">
  {% for block in include.content_blocks %}
    <editable-array-item data-component="{{block._bookshop_name}}" data-id="{{block._bookshop_name}}">
      {% bookshop {{block._bookshop_name}} bind=block %}
    </editable-array-item>
  {% endfor %}
</main>

```

**After (without Step 3 wrapper):**

```html
<main data-editable="array" data-prop="content_blocks" data-id-key="_bookshop_name" data-component-key="_bookshop_name">
  {% for block in include.content_blocks %}
    <editable-array-item data-component="{{block._bookshop_name}}" data-id="{{block._bookshop_name}}">
      {% bookshop {{block._bookshop_name}} bind=block %}
    </editable-array-item>
  {% endfor %}
</main>

```

### Key attributes explained

| Attribute | Purpose |
| --- | --- |
| `data-editable="array"` | Marks this element as an editable array region |
| `data-prop` | The property path — empty if parent already set it, otherwise the full path (e.g., `content_blocks`) |
| `data-id-key="_bookshop_name"` | The key used to identify each item |
| `data-component-key="_bookshop_name"` | The key that specifies the component type |
| `data-component` | On each item, specifies which component to render |
| `data-id` | On each item, provides a unique identifier |

### Understanding `data-prop` stacking

The `data-prop` attribute values accumulate as you traverse down the DOM. For example:

```html
<!-- Parent sets the base path -->
<editable-component data-prop="content_blocks">
  <!-- Child can use empty string since path is already set -->
  <main data-editable="array" data-prop="">
    ...
  </main>
</editable-component>

```

Is equivalent to:

```html
<!-- No parent wrapper, so array must specify full path -->
<main data-editable="array" data-prop="content_blocks">
  ...
</main>

```

For more details on this behavior, see the [CloudCannon documentation on visually editing complex arrays](https://cloudcannon.com/documentation/guides/set-up-visual-editing/visually-edit-complex-arrays-and-page-building/).

### For Hugo

```go
<main data-editable="array" data-prop="" data-id-key="_bookshop_name" data-component-key="_bookshop_name">
  {{ range .Params.content_blocks }}
    <editable-array-item data-component="{{ ._bookshop_name }}" data-id="{{ ._bookshop_name }}">
      {{ partial "bookshop" . }}
    </editable-array-item>
  {{ end }}
</main>

```

### For Eleventy

```auto
<main data-editable="array" data-prop="" data-id-key="_bookshop_name" data-component-key="_bookshop_name">
  {% for block in content_blocks %}
    <editable-array-item data-component="{{ block._bookshop_name }}" data-id="{{ block._bookshop_name }}">
	    {% bookshop "{{page.component._bookshop_name}}" bind: component %}
    </editable-array-item>
  {% endfor %}
</main>

```

## Step 5: Deploy and test

1. Commit your changes
2. Push to trigger a new build on CloudCannon
3. Open the Visual Editor and verify that:
  - Components render correctly
  - You can add, remove, and reorder components
  - Inline editing works within components

## Step 6: Add Editable Regions inside components (optional)

Once the basic migration is complete, you can add any type of editable region inside your Bookshop components to enable inline editing for text, images, and more.

### Text editing

Add text editable regions to enable inline text editing within your components:

```auto
<!-- hero.jekyll.html -->
<section class="hero">
  <h1 data-editable="text" data-prop="title">{{ include.title }}</h1>
  <p data-editable="text" data-prop="description">{{ include.description }}</p>
</section>

```

For more details, see [Visually edit text](https://cloudcannon.com/documentation/guides/set-up-visual-editing/visually-edit-text/).

### Image editing

Add image editable regions to enable image selection and metadata editing:

```auto
<!-- hero.jekyll.html -->
<section class="hero">
  <img
    data-editable="image"
    data-prop-src="background_image"
    data-prop-alt="background_image_alt"
    src="{{ include.background_image }}"
    alt="{{ include.background_image_alt }}"
  />
</section>

```

For more details, see [Visually edit images](https://cloudcannon.com/documentation/guides/set-up-visual-editing/visually-edit-images/).

### Nested arrays

You can even add nested arrays inside your components for more complex editing scenarios. See [Visually edit complex arrays](https://cloudcannon.com/documentation/guides/set-up-visual-editing/visually-edit-complex-arrays-and-page-building/) for details.

## What’s changed

With editable regions enabled:

- **Rendering** uses the editable regions system instead of data binding panels
- **Visual editing** becomes more intuitive with inline controls
- **Performance** may improve due to the streamlined rendering approach

## Troubleshooting

### Components not rendering in the editor

Ensure your `<editable-array-item>` wrapper includes both `data-component` and `data-id` attributes.

### Visual editor stuck on loading

Upgrade to v3.17.1 or later. Version 3.17.0 has a [bug where the loading state doesn’t hide correctly](https://github.com/CloudCannon/bookshop/releases/tag/v3.17.1).

* * *

## Summary of changes

| File | Change |
| --- | --- |
| `package.json` | Update `@bookshop/generate` to `^3.17.1` |
| `.cloudcannon/postbuild` | Add `--editable-regions` flag |
| Layout file (e.g., `base.html`) | Wrap bookshop include in `<editable-component>` (optional) |
| Page template (e.g., `page.jekyll.html`) | Add `data-editable="array"` attributes and wrap items in `<editable-array-item>` |

## Further reading

- [Bookshop v3.17.1 Release Notes](https://github.com/CloudCannon/bookshop/releases/tag/v3.17.1)
- [Bookshop v3.17.0 Release Notes](https://github.com/CloudCannon/bookshop/releases/tag/v3.17.0)
- [Example Migration Commit](https://github.com/CloudCannon/sendit-jekyll-bookshop-template/commit/35bbeb0b51395edfad827e0e549f7d264e455465)
- [Full Migration PR (Jekyll Example)](https://github.com/CloudCannon/sendit-jekyll-bookshop-template/pull/6)
- [CloudCannon: Visually Edit Complex Arrays](https://cloudcannon.com/documentation/guides/set-up-visual-editing/visually-edit-complex-arrays-and-page-building/)
