<Editor /> Component
app/editor/page.tsx
import { Editor } from "@wecre8websites/strapi-page-builder-react";
import "@wecre8websites/strapi-page-builder-react/editor.css"
import { notFound } from "next/navigation";
import config from "../../blocks/PageBuilderConfig";
const strapiConfig = {
url: process.env.NEXT_PUBLIC_API_URL as string,
authToken: process.env.STRAPI_ADMIN_TOKEN as string,
imageUrl: process.env.NEXT_PUBLIC_IMAGE_URL as string,
}
export default async function EditorPage({ searchParams }: { searchParams: Promise<{ _pagebuilderToken?: string }> }) {
const { _pagebuilderToken } = await searchParams;
if (!_pagebuilderToken) return notFound();
return <Editor
config={config}
apiKey={process.env.PAGE_BUILDER_API_KEY as string}
strapi={strapiConfig}
allowedParentOrigin="https://cms.example.com" />
}Use <Editor /> from a Server Component. There it keeps apiKey and strapi.authToken on the server (see Security). If you wrap it in your own "use client" component, or render it in a client-only app, those values are sent to the browser.
Props
| Parameter | Description | Required |
|---|---|---|
apiKey | The API key for the Strapi Page Builder. Sign up for free. Server-only: never sent to the browser. | true |
config | The configuration object for the Strapi Page Builder. See Editor Configuration. | true |
strapi | The configuration object for Strapi. | false |
allowedParentOrigin | The origin of your Strapi admin, e.g. https://cms.example.com. When set, the editor only talks to that origin. Recommended in production, together with a frame-ancestors header. See Security. | false |
contentKey | If set, the entry being edited is exposed to components as metadata[contentKey] instead of at the top level. | false |
additionalContent | Extra data merged into the content available to components (for example a dictionary or navigation). Kept on the server until the editor token is validated. | false |
resolveLink | A Server Action  (path, locale) => { contentType, contentId, templateId?, locale? } | null. Called when a link is followed in the preview; return the Strapi entry that page is built from and the editor opens it. See Links in the preview. | false |
fetch | A Server Action  (contentId) => content used to load the entry yourself instead of using the data from Strapi. Its id is public, so it must check permissions itself. | false |
Strapi Configuration Object
| Parameter | Description | Required |
|---|---|---|
url | The URL of the Strapi API. | true |
authToken | A Strapi API token, used on the server to load content for previews. A Read-Only token is enough. Never sent to the browser. | false |
imageUrl | The URL of the image server. Required if using the media field type | false |
How the editor is protected
- The editor token that Strapi puts in the iframe URL is checked on the server, with your API key, before any content is shown. Invalid, expired or missing tokens show an error and nothing else.
- Content lookups made while editing go through a server action that needs the validated session, so the Strapi token is never used by the browser.
- The editor ignores messages from any window except its direct parent, and only after validation.
Links in the preview
Links inside the editor preview never navigate the editor away from your Strapi admin:
- External links (other sites,
mailto:,tel:) do nothing, whichever way they are opened (click, ctrl/cmd-click, middle-click). - In-page anchors (
#section) scroll the preview to the target. - Internal links (same site) do nothing unless you provide
resolveLink. With it, the editor asks your site which Strapi entry the path belongs to and opens that entry, updating the address of the Strapi admin page so you can bookmark or reload it. If you have unsaved changes the editor asks before leaving.
app/editor/page.tsx
async function resolveLink(path: string, locale?: string) {
"use server";
const entry = await findEntryByPath(path); // your own lookup
if (!entry) return null; // unknown paths are ignored
return {
contentType: "api::page.page", // the content type's uid
contentId: entry.documentId,
templateId: entry.template?.documentId, // recommended: the template the entry uses
locale: entry.locale,
};
}
<Editor config={config} apiKey={...} strapi={...} resolveLink={resolveLink} />Like the fetch prop, a Server Action’s id is public, so resolveLink should only return what the editor is allowed to open.
Last updated on