Skip to content

@storyblok/preview-bridge

@storyblok/preview-bridge enables real-time preview of an iframe-embedded website within the Visual Editor.

StoryblokBridge can only run in a browser environment.

  • Modern web browser (latest versions of Chrome, Firefox, Safari, Edge, etc.)

To add the package to a project, run this command in the terminal:

Terminal window
npm install @storyblok/preview-bridge@latest

Access StoryblokBridge in the global scope, either directly or as a property of window:

<body>
<script>
const storyblokBridge = new StoryblokBridge();
</script>
</body>

Following is a minimal implementation of the StoryblokBridge class. This webpage loads within the editor’s iframe and logs the story’s unsaved state each time the input in the Visual Editor changes.

<!doctype html>
<html lang="en-US">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
</head>
<body>
<script>
const storyblokBridge = new StoryblokBridge();
storyblokBridge.on("input", ({ story }) => {
console.log(story);
});
</script>
</body>
</html>

The StoryblokBridge() constructor creates a bridge client that allows an iframe-embedded webpage to communicate with the Visual Editor.

StoryblokBridge(parameters);

The constructor accepts the following optional parameters:

KeyDescriptionType
resolveRelationsDefine an array of references to other stories. To ensure that the linked data populates on each update, resolve any relations defined in the API request. Learn more about the resolve_relations Content Delivery API parameter.array
resolveLinksSet to "story", "url", or "link" to track values of link fields. To ensure that the linked data populates on each update, resolve any links defined in the API request. Learn more about the resolve_links Content Delivery API parameter.string
preventClicksEnable or disable interactions within the preview area. Defaults to false. To allow standard click behavior, such as navigation between pages, set to true.boolean
customParentDefine the parent app of the bridge. Defaults to "https://app.storyblok.com".string
fallbackLangSet the fallback language of non-translated fields.string
const storyblokBridge = new StoryblokBridge({
resolveRelations: ["article.author", "article.category"],
resolveLinks: "url",
preventClicks: true,
customParent: "https://your-storyblok-domain.com",
fallbackLang: "de",
});

StoryblokBridge has three prototype methods available on all instances:

  • on()
  • pingEditor()
  • isInEditor()
StoryblokBridge.prototype.on(event, callback);
StoryblokBridge.prototype.on([events_array], callback);

Create a listener to subscribe to the following editor events:

EventDescription
publishedThe user published the story
changeThe user saved the story
inputThe user updated a field value (returns the complete, unsaved story)
enterEditmodeThe Visual Editor initialized

The callback receives an event object. Each event type returns a matching object:

{
"reload": true,
"action": "published",
"slug": "home",
"storyId": 24840769,
"slugChanged": true
}

The StoryblokBridge.prototype.on() method accepts a single event or an array of multiple events.

Inject the raw JSON of the story into the DOM on each input:

storyblokBridge.on("input", ({ story }) => {
document.getElementById("app").innerHTML = `
<pre>
${JSON.stringify(story, null, 2)}
</pre>
`;
});

Reload the page when the user saves or publishes the story:

storyblokBridge.on(["change", "published"], () => {
location.reload(true);
});
StoryblokBridge.prototype.pingEditor(callback);

Returns the full StoryblokBridge instance if the user previews the webpage within the Visual Editor.

The callback function receives a payload parameter that indicates the state of the preview within the editor.

storyblokBridge.pingEditor((payload) => {
console.log(payload);
});
StoryblokBridge.prototype.isInEditor(callback);

Returns true if the user previews the webpage within the Visual Editor and false if not. This method can only run in the callback function of pingEditor().

storyblokBridge.pingEditor(() => {
if (storyblokBridge.isInEditor()) {
// For example, fetch draft content
} else {
// For example, fetch published content
}
});

Was this page helpful?

What went wrong?

This site uses reCAPTCHA and Google's Privacy Policy. Terms of Service apply.