Skip to content

Embed the content editor

The content editor can run inside your own app, so your customers change their logo, colours and wording themselves. Each customer edits one content set of a template and sees the pages as they type. They need no Typefold account: your server makes an embed token for them, and your page shows the editor that token opens.

  1. A developer marks the template’s content fields and publishes it. Each of your customers gets a content set of that template.
  2. When a customer opens the editor in your app, your server makes an embed token for their set with an API key.
  3. Your page frames the editor at the token’s url.
  4. The customer edits the fields and clicks Save. Renders that name the set use the new values at once.

The editor shows the template’s published version. Fields that only the draft has are not shown, and their values in the set are kept.

In Studio, open Settings → Embedding and list the origins of the pages that show the editor under Allowed sites, one per line, such as https://app.example.com. https://*.example.com allows every subdomain. http://localhost and http://127.0.0.1 are allowed for development. No other site can frame the editor, and no embed token can be made until a site is listed.

Under Style, match the editor to your app. The preview beside the settings shows the editor inside your site with the style as you change it. To check the real editor, pick a published template and a content set under Try the real editor and open it: it opens in a new tab with the saved sites and style, and what you save there changes that content set.

Setting What it changes
Colour mode Light, dark, or as the viewer’s device.
Accent Buttons, links and the outline of the parts that can be changed.
Background The page behind the editor.
Font Figtree (the default), the viewer’s system font, a serif or a monospace font.
Corner radius Of buttons, inputs and panels, 0 to 24 pixels.

Only owners and administrators can change these settings. An API key with template:read can read them with GET /v1/workspace/embedding.

Create an API key under Manage → API keys with the permissions template:read, template:content and render:create, and keep it on your server. Each time a customer opens the editor, make a token for their content set:

Terminal window
curl "$PDF_URL/v1/embed-tokens" \
-H "x-api-key: $API_KEY" \
-H "content-type: application/json" \
--fail-with-body \
-d '{
"templateId": "'"$TEMPLATE_ID"'",
"contentSetId": "'"$CONTENT_SET_ID"'",
"expiresInMinutes": 30,
"label": "customer-42"
}'
Field What it does
templateId Required. A published template with content fields. Spreadsheet templates are not supported.
contentSetId Required. The content set the customer edits.
actions What the customer may do: save and uploadImages. Both when left out; without save the editor only shows the pages.
expiresInMinutes How long the token works, 5 to 1,440 minutes. 60 when left out.
label Who the token is for, such as your own customer ID, kept on the audit log.

The answer is 201 with the token’s id, expiresAt, the secret token and the url your page opens. The secret is returned only here; Typefold keeps only its hash. Make a new token each time the editor opens rather than storing one.

A workspace with no allowed site, or a template without content fields or not yet published, answers 400 BAD_REQUEST. A workspace without the visual editor answers 403 FORBIDDEN.

Load /embed.js from your Typefold address and pass it the token’s url:

<div id="content-editor"></div>
<script src="https://app.typefold.dev/embed.js"></script>
<script>
const editor = Typefold.embed({
url: embedUrl, // embed.url from your server
container: "#content-editor",
height: "760px",
onSaved: ({ revision }) => console.log("Saved revision", revision),
onClosed: () => editor.destroy(),
onError: ({ code, message }) => console.warn(code, message),
});
</script>

On a self-hosted installation, load it from your own installation’s address instead.

Option What it does
url Required. The token’s url.
container Required. The element the editor goes in, or a CSS selector for it.
height The frame’s height, such as "760px". 720px when left out.
title The frame’s title for screen readers. Content editor when left out.
onReady Called once the editor has connected to your page.
onSaved Called after each save with { revision, values }: the set’s new revision and values.
onClosed Called when the customer clicks Close.
onError Called with { code, message } when something fails.

Typefold.embed returns { frame, destroy }: the <iframe> element, and a function that removes it. The editor talks only to a page on an allowed site, and /embed.js listens only to its own frame.

onError code Meaning
session_ended The token expired or was revoked. Make a new token and open the editor again.
conflict The set was saved elsewhere since the editor opened. The editor offers to load the latest values.
save_failed The save was refused, such as a value that does not fit its field.

A token stops working when it expires, when you revoke it, when the API key that made it is disabled or deleted, when the member who made it leaves the workspace, and when its content set is deleted. Revoke one early, such as when the customer signs out:

Terminal window
curl -X POST "$PDF_URL/v1/embed-tokens/$EMBED_TOKEN_ID/revoke" \
-H "x-api-key: $API_KEY" \
--fail-with-body

Revoking needs template:content. The open editor shows that the session has ended.

  • One content set of one template: reading its fields and values, showing its pages, and, with the token’s actions, saving the set and uploading images for its image fields. It cannot publish, read other templates or sets, or render documents.
  • Never more than the API key or member that made it may do. Narrowing the key’s permissions narrows its tokens at once.
  • The secret travels in the address’s # part, which browsers do not send to servers, and the editor removes it from the address bar once loaded.
  • Each token may make 120 previews a minute and upload 20 images.

Making and revoking tokens and changing the embedding settings are recorded in the audit log as embed_token.created, embed_token.revoked and workspace.embed_settings_updated. A customer’s saves are recorded as template.content_set_updated, as made by the key or member that made the token.