Localess
Astro

Visual Editor

Reload-based and SSR live-preview Visual Editor sync tiers for the Astro SDK for Localess.

Visual Editor sync

Two tiers, mutually exclusive:

  • enableSync: true — on save/publish/unpublish, debounce (~500ms) and reload the page. Unsaved typing (input/change) isn't shown; use livePreview for that. Simplest option; no extra setup. Under static output a reload shows new content only in astro dev: a production static build keeps serving its prerendered HTML, so there you get click-to-select only.
  • livePreview: true — SSR-only in-place preview. Requires output: 'server'; the integration throws at config-setup time otherwise. save/publish/unpublish reload the page. input/change debounce (~500ms), POST the updated content back to the current page, and patch the returned HTML into the live DOM with morphdom — no full reload, keyed by each element's data-ll-id.

livePreview needs no extra wiring in your page beyond fetching the document as usual, then passing its id to getLivePayload() so the page renders the in-flight edited data on the POST round-trip. The middleware records which document each POST belongs to, and getLivePayload(Astro, documentId) returns the draft only when that id matches, so a page rendering several documents (a shared header plus the page, say) keeps the others as fetched:

---
// src/pages/[...path]/index.astro
import { getLivePayload, getLocalessClient, LocalessApiError, type Content } from '@localess/astro';
import LocalessDocument from '@localess/astro/LocalessDocument.astro';

let document: Content;
try {
  document = await getLocalessClient().getContentBySlug(Astro.params.path ?? 'home');
} catch (error) {
  if (error instanceof LocalessApiError && error.status === 404) {
    return Astro.rewrite('/404');
  }
  throw error;
}

// While the Visual Editor is editing this document, render its unsaved draft instead.
const preview = await getLivePayload(Astro, document.id);
if (preview.data) {
  document = { ...document, data: preview.data };
}
---

<LocalessDocument document={document} />
// astro.config.mjs — livePreview requires SSR
import node from '@astrojs/node';
import { defineConfig } from 'astro/config';
import { localess } from '@localess/astro';

export default defineConfig({
  output: 'server',
  adapter: node({ mode: 'standalone' }),
  integrations: [
    localess({
      origin: process.env.LOCALESS_ORIGIN,
      spaceId: process.env.LOCALESS_SPACE_ID,
      token: process.env.LOCALESS_TOKEN,
      livePreview: true,
    }),
  ],
});

Playgrounds: playgrounds/astro is a full SSR project using livePreview. playgrounds/astro-static mirrors it under static output using getStaticPaths and (optionally) enableSync instead.

Live edits are matched to the page by document id, so update your Localess deployment together with the SDK. See Troubleshooting.

On this page