# @revenexx/editor

The visual page editor for **revenexx Revenue Cloud themes** — a hard fork of
[blökkli](https://github.com/blokkli/editor) ([live demo](https://blokk.li)),
adapted to the revenexx UI and platform. How the fork is maintained, synced with
upstream and released is documented in [FORK.md](./FORK.md).

The editor gives buyers of a theme true WYSIWYG page building: drag & drop
blocks, inline text editing, undo/redo history, comments, a reusable-block
library, templates, multi-language content and a publish workflow. The editor
**does not store data** — every mutation goes through an _adapter_ to a backend.
In the Revenue Cloud that backend is the **pages platform app** (`apps/pages`),
and the reference integration is **`@revenexx/cover-theme`**.

## Using it in a revenexx theme

### 1. Install

```bash
npm install @revenexx/editor
```

### 2. Register the module

```ts
// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@revenexx/editor'],

  blokkli: {
    itemEntityType: 'block',
    defaultLanguage: 'de',
    // Where your block components live:
    pattern: ['app/components/blokkli/**/*.vue'],
    // Your edit adapter (see step 4):
    editAdapterPath: 'app/blokkli.editAdapter.ts',
  },
})
```

> The config key stays `blokkli` and all in-app imports go through the generated
> `#blokkli/*` aliases — only the package name is revenexx-specific.

### 3. Write blocks

A block is a Vue component using the `defineBlokkli()` macro. Props are the
editable fields; options control appearance and show up in the editor toolbar.

```vue
<!-- app/components/blokkli/hero/index.vue -->
<script setup lang="ts">
const props = defineProps<{
  headline: string
  subheadline?: string
}>()

const { options } = defineBlokkli({
  bundle: 'hero',
  options: {
    alignment: {
      type: 'radios',
      label: 'Alignment',
      default: 'left',
      options: { left: 'Left', center: 'Center' },
    },
  },
  editor: {
    // Props a freshly added block starts with:
    mockProps: () => ({ headline: 'Headline' }),
  },
})
</script>

<template>
  <section :class="options.alignment === 'center' && 'text-center'">
    <!-- v-blokkli-editable enables inline editing for this field -->
    <h1 v-blokkli-editable:headline>{{ headline }}</h1>
    <p v-if="subheadline" v-blokkli-editable:subheadline>{{ subheadline }}</p>
  </section>
</template>
```

Nested blocks (sections, grids, accordions) render their children with
`<BlokkliField name="items" :list="..." />`.

### 4. The edit adapter

The adapter translates editor actions (add, move, delete, options, publish,
comments, …) into backend calls. **Don't write one from scratch** — copy the
reference implementation:

- **Adapter:** `cover/packages/cover-theme/app/blokkli.editAdapter.ts` — full
  feature surface against the pages app
- **Backend contract:** `apps/pages/README.md` has the complete adapter-method →
  endpoint mapping (mutation log with undo/redo, ownership, revisions, comments,
  library, templates, translations, notifications)
- **BFF proxy:** the browser never calls the pages app directly; a Nitro route
  (`/api/blokkli/app/[...path]`) forwards calls with tenant context

### 5. The `/admin/` pattern

Live storefront routes never ship editor code. The editor mounts on a dedicated
route the cockpit embeds in an iframe:

```
/admin/edit?page={id}&langcode={lang}     ← editor surface (BlokkliProvider)
/preview/{token}                          ← read-only share preview
/{slug}                                   ← live rendering, zero editor weight
```

The cockpit hands a short-lived, user-scoped token to the iframe via
`postMessage` (`{ type: 'blokkli:edit-token', token }`) or the `#token=`
fragment; the theme attaches it to every adapter call. See
`cover-theme/app/pages/admin/edit.vue` + `useEditToken.ts`.

## Development (this repo)

```bash
npm install
npm run dev:prepare        # generate the .nuxt alias environment (required once)
npm run dev -- --port 3001 # playground with the revenexx theme
npm test                   # vitest
npm run typecheck          # see /typecheck for targeted commands
```

Releasing & upstream syncs: see [FORK.md](./FORK.md).

## Acknowledgments

blökkli was created by [dulnan](https://github.com/dulnan) at
[Liip](https://www.liip.ch/) (MIT). This fork tracks upstream closely — we pull
new releases regularly and replay the revenexx customizations on top.
