Frontend developer guide
Inka makes an existing frontend editable. You add a small script and a few HTML attributes, and editors compose pages inside the bounds your design system allows — no React or Vue required in the frontend itself. This guide takes you from a running page to custom blocks, live preview, and templates.
Quick start
Add Inka to a page in your framework. Each tab is a real, working starter — the same source the test suite runs against.
<!-- pages/[...slug].vue -->
<template>
<div v-for="id in page?.blocks_layout?.items" :key="id"
:data-block-uid="editing ? id : undefined">
<!-- The card block is rendered editable; anything else is shown as raw JSON. -->
<a v-if="page.blocks[id]['@type'] === 'card'"
:href="page.blocks[id].link"
:data-edit-link="editing ? 'link' : undefined">
<!-- data-edit-media: click to pick/upload image · data-edit-text: edit text in place -->
<img :src="page.blocks[id].image" :data-edit-media="editing ? 'image' : undefined" />
<h3 :data-edit-text="editing ? 'title' : undefined">{{ page.blocks[id].title }}</h3>
<p :data-edit-text="editing ? 'description' : undefined">{{ page.blocks[id].description }}</p>
</a>
<pre v-else>{{ JSON.stringify(page.blocks[id], null, 2) }}</pre>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { initBridge } from '@hydra-js/hydra.js'
const page = ref(null)
const editing = ref(false)
onMounted(async () => {
// Only init the bridge when loaded inside the editor.
if (window.name.startsWith('hydra')) {
editing.value = true
initBridge({
// Declare the one block type we render richly.
blocks: { card: { blockSchema: { properties: {
image: { widget: 'image' },
title: { type: 'string' },
description: { type: 'string' },
link: { widget: 'url' },
} } } },
// Re-render on every edit.
onEditChange: (data) => { page.value = data },
})
} else {
// On the live site: fetch this page and render once.
page.value = await (await fetch(`/++api++${useRoute().path}`)).json()
}
})
</script>Next: Installation for the full setup, then Build a frontend for framework specifics.
In this guide
Advanced
Advanced topics for optimising your Inka integration: lazy loading the bridge, authentication, and preventing reloads.
Templates & Layouts
Templates allow editors to centrally control content and reuse content. They allow a developer to not have to hard code layout decisions and instead use rules to apply user layouts in template content stored separately from the page, or give the user a choice on which layout they want.
Listings & Dynamic Blocks
A listing block fetches content from the server (e.g. latest news) and renders each result as a separate block, repeating each block once per result entry. This means a listing can be moved between containers and reuse normal blocks for what it repeats.
Container Blocks
A block — or the page itself — is divided into regions, and each region holds an ordered list of blocks. Sliders have a slides region, grids have columns, accordions have panels; a page has its main items region (and optionally a header, footer, …).
Custom Blocks
Define custom block types directly in your frontend configuration via the blocks option in initBridge. No Volto plugin deployment required. Each block type needs an id, title, and a blockSchema with its field properties.