Administration

Einblick SDK In-Page-Editing

Externe Sites registrieren, Framework-Support verstehen und Einblick In-Page-Editing integrieren, ohne SSR oder Host-Caching zu brechen.

Einblick SDK In-Page-Editing

Öffne Systemeinstellungen → API, um External Sites zu registrieren, erlaubte Origins zu verwalten und den publishable site key für die In-Page-Editing-Runtime zu kopieren.

Framework-Support

  • @einblick/sdk ist framework-agnostisch. Nutze es für typisierte Reads, Schema-Generierung, Public-Command-Aufrufe und serverseitiges CMS-Fetching in jedem JavaScript- oder TypeScript-Stack.
  • @einblick/sdk/react enthält die aktuelle In-Page-Editing-Runtime. Sie ist für React-basierte Sites wie Next.js, Remix, plain React oder Astro-Seiten mit React-Komponenten gedacht.
  • Nicht-React-Sites können @einblick/sdk heute weiterhin für typisierte Reads und Public Commands nutzen, bekommen aber noch keinen fertigen Editing-Provider und keine fertigen Wrapper.

Typisierte Reads und Response-Formate

  • Collection-Reads unterstützen limit, cursor, sort und include. Für sort nutzt du komma-separierte Feldnamen und stellst bei absteigender Sortierung ein - vor das Feld. Ohne explizites sort folgen CMS-Collections der in Einblick gepflegten manuellen Reihenfolge, und jeder Record liefert diesen Wert als sort in den Record-Metadaten mit.
  • Relation-Includes funktionieren nur für lesbare Relationsfelder und nur dann, wenn derselbe API-Schlüssel auch Zugriff auf die verknüpfte Collection hat. Eingeschlossene Records kommen in included zurück.
  • CMS-richtext-Werte werden als strukturierte Dokument-JSON zurückgegeben, nicht als bereits abgeflachte HTML-Ausgabe.
  • Asset-Payloads liefern stabile URLs sowie optionale width, height, title, copyright, description, tags und sort. Wenn zu einem CMS-Video eine Web-Playback-Variante erzeugt wurde, zeigt die öffentliche Asset-URL auf diese browser-kompatible MP4- oder WebM-Datei. Browser-Anfragen mit Origin-Header werden für nicht transformierte Dateien mit CORS-Headern und Range-Support geproxyt; serverseitige Anfragen ohne Origin-Header können kurzlebigen Storage-Redirects folgen.

Resource-Writes

  • Nutze client.createResource(...), client.updateResource(...) und client.deleteResource(...) für die Standard-Resource-API. CMS-Ressourcen liegen unter /api/v1/cms/{slug}; native Ressourcen liegen unter /api/v1/{slug}.
  • Resource-Writes brauchen eine passende Resource-Write-Freigabe am API-Schlüssel sowie schreibbare Felder für Create- und Update-Payloads. CMS-Ressourcen unterstützen Create, Update und Delete. Native Resource-Writes unterstützen aktuell Gebäude, Events und Festivals; native Deletes archivieren den Datensatz.
  • Übergib für wiederholbare Resource-Writes einen idempotencyKey. Wird derselbe Key für dieselbe Route und denselben Payload erneut genutzt, kommt das gespeicherte Ergebnis zurück; bei anderem Payload gibt es einen Konflikt.

Public Commands

  • Public Commands sind von Resource-Reads getrennt und brauchen explizite Write-Action-Freigaben auf dem API-Schlüssel.
  • Mit client.getCommandSchema() prüfst du, welche Commands für den aktuellen Token verfügbar sind.
  • Nutze client.command(name, input) oder typisierte Helfer wie client.jobs.submitApplication(...) für freigegebene Actions. Für wiederholbare Submit-Aufrufe kannst du einen idempotencyKey mitgeben.
  • Newsletter-Anmeldungen sind über client.newsletter.signup(...) verfügbar, wenn der Schlüssel newsletters.signup freigibt. Der Aufruf erstellt oder aktualisiert einen Kontakt, kann veröffentlichte Kontaktgruppen-Slugs anwenden und liefert je nach Workspace-Einstellung subscribed oder pending_confirmation.

Was die Runtime macht

  • Anonyme Besucher behalten das normale SSR-, Caching- und Performance-Verhalten der externen Site.
  • Angemeldete Editor*innen erhalten Hover-Indikatoren, Inline-Bearbeitung für einfache Felder und einen gehosteten Drawer für komplexere Felder.
  • Standardmäßig zeigt der authentifizierte Edit-Modus unten eine fixe Einblick-Kontrollleiste mit verbundener Site, einem allgemeinen Sammlungen-Button und einem Mehr-Menü für Einblick-Öffnen oder Logout. Mit chrome="badge" nutzt du den bisherigen Launcher; mit chrome="none" stellt die Host-Site eine eigene Oberfläche bereit.
  • Das Collections-Panel erlaubt Suche über alle Ressourcen, die der External-Site-Session zur Verfügung stehen. CMS-Collections sind unter einem aufklappbaren CMS-Eintrag gruppiert; unterstützte native Ressourcen stehen auf derselben Ebene wie diese Gruppe. Editor*innen können verschachtelte CMS-Collections auf- und zuklappen, die passende Ressource in Einblick öffnen, bestehende Records im gehosteten Drawer bearbeiten oder löschen und Records direkt von der Host-Site erstellen. Native Drawer-Bearbeitung nutzt aktuell die normalen Einblick-Formulare für Gebäude, Events und Festivals. Die Suche klappt passende Zweige auf, damit Treffer in Unter-Collections erreichbar bleiben. Record-Labels nutzen das konfigurierte Display-Feld, wenn es vorhanden ist, und fallen sonst auf title, name, headline, ein anderes anzeigbares Feld, den Slug oder ein generisches Record-Label zurück. Singleton-Ressourcen zeigen die Erstellen-Aktion nur, solange noch kein Record existiert.
  • Editor*innen können CMS-Records im Collections-Panel über den Drag-Handle umsortieren, solange Sortierung für die Collection nicht deaktiviert ist.
  • Umschließe gerenderte Listenflächen mit EditableCollection und einem createEditableCollectionBinding({ resourceSlug })-Binding, um eine Eintrag hinzufügen-Aktion anzuzeigen, die den gehosteten Drawer direkt im Erstellmodus öffnet. Lege item-bezogene EditableRegion-Bindings innerhalb dieses Wrappers an, damit jeder Record seinen eigenen Hover-Bearbeitungszustand behält.
  • Im gehosteten Drawer können Editor*innen mehrwertige files- und tags-Felder umsortieren. Gespeicherte files-Arrays behalten diese Reihenfolge in SDK- und Public-API-Antworten.
  • Relationsfelder und mehrwertige Relationsfelder im gehosteten Drawer laden auswählbare Records über die aktuelle Edit-Session und bleiben auf die im Feld konfigurierte Ziel-Collection begrenzt. Der Picker nutzt das Display-Feld der Ziel-Collection für Labels, liefert aktuell bis zu 100 Datensätze aus demselben Workspace, und Editor*innen können verknüpfte Records direkt daraus erstellen oder bearbeiten, ohne separat ins CMS zu wechseln. Wenn beim Erstellen in der Ziel-Collection ein Relationsfeld zurück zur aktuellen Collection existiert, füllt Einblick diese Rückreferenz vor.
  • Feldbezogene Saves patchen aktuell sichtbare textartige Bindings sofort.
  • Bild-, Galerie- und Datei-Bindings können Medien aus dem externen Editor hochladen und ersetzen. Einwertige Felder speichern die hochgeladene Datei; mehrwertige Bild- und Dateifelder werden durch die hochgeladene Datei als neue Liste ersetzt.
  • Der Refresh-/Refetch-Pfad der Host-Site über onSave bleibt nötig, wenn die gerenderte Seite von aufgelösten Asset-URLs, SSR-Ausgabe oder gecachten Daten abhängt.

Login und Edit-Sessions

  • Der Login-Flow versucht zuerst ein Popup und fällt auf einen Full-Page-Redirect zurück, wenn der Browser Popups blockiert.
  • Nach dem Sign-in kehrt der Editor direkt auf die aktuelle Seite zurück und aktiviert dort den Edit-Modus.
  • Der Provider speichert die Edit-Session pro Site-Key auf dem aktuellen Gerät, damit Editor*innen auf derselben registrierten Origin weiterarbeiten können, bis die Session abläuft oder der Edit-Modus beendet wird.
  • Edit-Sessions sind an die Origin gebunden. Nutzt eine Site mehrere erlaubte Origins, ist auf jeder Origin ein eigener Sign-in nötig.

Was die Host-Site weiterhin verantwortet

  • Die Host-Site bleibt für serverseitige Reads, das Rendering der Seite und langlebige Cache-Layer verantwortlich.
  • Das SDK kann Teile des aktuell sichtbaren DOM sofort patchen, aber nicht automatisch framework-spezifische SSR-Caches, CDN-Caches oder Static-Generation-Outputs auf jedem Host invalidieren.
  • Für die beste Erfahrung verdrahte den onSave-Callback des Providers mit der Cache-Invalidierung plus dem kleinstmöglichen Refresh-/Refetch-Mechanismus, der frische Daten neu rendert. Der Callback läuft auch nach Creates und Deletes im gehosteten Drawer; gelöschte Records kommen mit value: null.
  • Die Standard-Kontrollleiste reserviert unten Body-Platz und setzt --einblick-editor-bottom-offset sowie data-einblick-editor-bar-active auf <html>. Verschiebe fixe Bottom-UI der Host-Site mit dieser Variable oder setze reserveBottomSpace={false}, wenn die Host-Site den Abstand selbst steuert.

Best Practices für Cache-Invalidierung

  • Wenn deine Site kein persistentes SSR- oder CDN-Caching nutzt, können textartige Feldänderungen und Inline-Medienersetzungen bereits sofort korrekt aussehen. Refreshe oder refetche nach dem Save trotzdem, wenn die Seite aufgelöste Asset-URLs oder gecachte Daten rendert.
  • Nutzt deine Site tag-basierte Daten-Caches, invalide den kleinsten Tag-Bereich, der die bearbeitete Ressource abdeckt.
  • Rendert deine Site Routen statisch, invalide zusätzlich den betroffenen Route-Output. Tags erneuern den Data-Cache; Pfade erneuern den prerendered Page- oder Layout-Cache.
  • Nutzt deine Site ein CDN oder Reverse-Proxy-Caching, purge den relevanten Cache-Key oder Pfad nach einem erfolgreichen Save.

Next.js

  • Halte CMS-Fetching auf dem Server.
  • Versehe Resource-Fetches mit next.tags, am besten über createEinblickCmsTags() aus @einblick/sdk/next.
  • Stelle POST /api/einblick/revalidate mit createEinblickRevalidateHandler({ tags }) bereit. Für Route-Handler und Einblick-Webhooks nutze sofortige Expiration (revalidateTag(tag, { expire: 0 })); profile: "max" kann einmal stale Content ausliefern, bevor neu geladen wird.
  • Für statisch gerenderte App-Router-Seiten muss dieselbe Route auch betroffene Pfade invalidieren. Der SDK-Helper nutzt standardmäßig revalidatePath('/', 'layout'), ein robuster Default für kleine Sites. Größere Apps können eine engere paths-Map übergeben.
  • Montiere EinblickNextEditBoot im Root-Layout. Der Boot pingt nach Inline-Saves und Saves im gehosteten Drawer den Revalidierungs-Endpoint und ruft danach router.refresh() auf, damit die aktuelle Route ohne Full-Page-Reload neu rendert.
  • Lass in den External-Site-Einstellungen den Revalidierungs-Endpunkt auf /api/einblick/revalidate, damit direkte Änderungen in Einblick dieselben Tags invalidieren. Einblick sendet nach CMS-Create, -Update, -Delete, Umsortierung und Dateiänderungen aus dem externen Editor { resourceSlug } an diesen Pfad auf jeder erlaubten Origin. Ein gemeinsamer Revalidierungs-Token ist optional; wenn du einen verlangst, übergib ihn sowohl in der External-Site-Konfiguration als auch an EinblickNextEditBoot.
// lib/einblick-cache.ts
import { createEinblickCmsTags } from '@einblick/sdk/next'

export const einblickTags = createEinblickCmsTags({
  fanOut: { 'gedanken-sections': ['gedanken'] },
})
// app/api/einblick/revalidate/route.ts
import { createEinblickRevalidateHandler } from '@einblick/sdk/next'
import { einblickTags } from '@/lib/einblick-cache'

export const POST = createEinblickRevalidateHandler({
  tags: einblickTags,
  // Default: paths: [{ path: '/', type: 'layout' }]
})
// app/layout.tsx
import { EinblickNextEditBoot } from '@einblick/sdk/next'

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html>
      <body>
        <EinblickNextEditBoot>{children}</EinblickNextEditBoot>
      </body>
    </html>
  )
}

Remix und Custom SSR

  • Halte CMS-Fetching auf dem Server oder in Loaders.
  • Invalidiere nach dem Save Loader-Daten, Route-Caches oder CDN-Caches im kleinstmöglichen Scope und triggere danach den kleinsten Refresh-/Refetch-Pfad, der frische Server-Daten neu rendert.
  • Wenn du clientseitige Query-Caches nutzt, triggere nach dem Save bei Bedarf zusätzlich ein Refetch.

Empfohlene Integrationsform

  1. Hole CMS- oder native Resource-Daten serverseitig mit @einblick/sdk.
  2. Mappe rohe Records in View-Models und halte bearbeitbare Bindings daneben vor.
  3. Umschließe CMS-basiertes Output mit EditableText, EditableImage oder EditableRegion. Für wiederholte Listen umschließt du die ganze Liste mit EditableCollection und legst item-bezogene Regions darin ab. Für native Records setzt du am Binding sourceType: 'native' und übergibst den nativen Resource-Slug plus Record-ID.
  4. Montiere EinblickEditProvider mit dem publishable site key und wähle die Standard-Kontrollleiste, chrome="badge" oder eine eigene Host-Oberfläche.
  5. Nutze EinblickLoginButton oder ?einblick-login / ?login als Einstieg in den Editor.
  6. Nutze onSave, um Caches zu revalidieren und den Refresh-/Refetch-Pfad der Host-Site anzustoßen, wenn die Seite Resource-Daten per SSR oder andere Caches liest.

Verwandte Doku