The Storyblok Bridge
To build a bridge between Storyblok and your website, you need to load our storyblok-v2-latest script on your page. This script will communicate via iframe with Storyblok to tell the editing interface which component needs to be opened when the user clicks on it.
Please note that the _editable
property is only included in the draft version of the story.
This is done using a simple HTML comment before that element. The data for this comment is shipped in the draft JSON by adding the key _editable
to each component.
Include the script inside your <body> tag
Since the script has a considerable size, in most cases, you would want to load the script only when you're inside Storyblok edit mode or on a preview deployment. You can check the asynchronous loading example in the FAQ below.
Some methods to check for the edit mode:
- Check for the URL parameter
_storyblok
(see FAQ below) - Check for a cookie (You could set a cookie the first time the URL has
_storyblok
in it)
Usage of StoryblokBridge
Once your bridge is loaded, you can initialize it with new StoryblokBridge(config)
.
StoryblokBridge configuration
resolveRelations
(array of strings): If you use theresolve_relations
parameter in your API requests you need to tell the Storyblok bridge to resolve the relations too. Example:["article.author", "article.category"]
resolveLinks
(string: "url" | "link" | "story"): If you use theresolve_links
parameter in your API requests you need to tell the Storyblok bridge to resolve the links.
customParent
(string): If you are using the Storyblok editor on your own domain a URL needs to be provided. Default is:https://app.storyblok.com
.
preventClicks
(boolean): If you want to prevent the iframe events, like clicking on a link, to happen, you can set this option. Default is:false
.
Please checkout also our detailed guide about the Visual Editor and the Storyblok Bridge.
You get a 404 error after changing the slug of a Story?
If you use Storyblok with server-side rendering and want to reload whenever the content changed you need to make an additional check on the slugChanged attribute. This makes sure that the page doesn’t throw a 404 error if you change the slug:
We can use multiple events together by providing the event.name
inside of an array. The example above will reload the page, if the user clicks save or publish.
event payload: published, change
Input event
The input
event is triggered after a user changes the value of a field. It's used to enable live updates of the content.
event payload: input
enterEditmode event
The enterEditmode
event is triggered after the editor has been initialized. It can be used to request the draft content, when we're inside of Storyblok.
event payload: enterEditmode
See the complete list of events below:
Event | Will be emitted |
---|---|
input | after a user changes the value of a field |
change | after the user saves the content |
published | after the user clicks publish |
unpublished | after the user clicks unpublish |
enterEditmode | after the editor has been initialized in the editmode |
customEvent | custom event used by third party plugins |
Check for editor environment
With storyblokInstance.isInEditor()
and storyblokInstance.pingEditor()
you can check if your user has opened a page inside Storyblok. If that is the case, you can use the storyblok-js-client to request the draft
version of the content.
Component Menus
Once you listen to events on the Visual Editor, you will be able to click the components and see their name with an outline {1}. If you listen only the save
or publish
events, you will see a simple menu, that allows navigation to parent components {2}. If you listen to the input
event, you will see a more extended menu {3}, that allows you to have components actions like adding blocks before or after, duplicating a component, or moving the component forwards or backward. You can also delete the components directly.
Param | Description |
---|---|
_storyblok | the content entries ID |
_storyblok_tk[space_id] | the space ID |
_storyblok_tk[timestamp] | a timestamp |
_storyblok_tk[token] | a validation token. Combination of space_id, timestamp and your preview_token |
_storyblok_release | currently selected id of a release |
_storyblok_lang | currently selected language |
_storyblok_c | content type of the story |
The initialization of the bridge should happen after the storyblok-v2-latest.js
the script was loaded, so for example on the callback
function of the loadBridge
function above.
Checking if you are inside of Storyblok
Since your application will be loaded inside an iframe in Storyblok, the iframe will be passed a _storyblok
parameter that we can check for. If this parameter is present, we should be inside the Visual Editor.
Why is the live preview not working?
Check if you are not redirecting to another URL by clicking "Open Draft" in the top right submenu. The URL should contain the query parameter _storyblok
.
How to validate if the user is viewing your site in the Storyblok editor?
If the user opens your page in Storyblok, we add a few parameters which you can use to securely validate their use of the edit mode.
You will need that validation to load the right version of your content to the right users. The draft
version is for the editor and the published
version is for the public.
Checking for _storyblok
A simple validation would be to check if there is the _storyblok
parameter in URL. This could be done in the frontend or in the backend. But for a secure check, we recommend implementing the logic in the backend and validate the _storyblok_tk
parameter.
Here are some examples of how to securely check if the user is in edit mode:
import crypto from 'crypto' // getQueryParam = access requests URL param by name let validationString = getQueryParam('_storyblok_tk[space_id]') + ':' + YOUR_PREVIEW_TOKEN + ':' + getQueryParam('_storyblok_tk[timestamp]') let validationToken = crypto.createHash('sha1').update(validationString).digest('hex') if (getQueryParam('_storyblok_tk[token]') == validationToken && getQueryParam('_storyblok_tk[timestamp]') > Math.floor(Date.now()/1000)-3600) { // you're in the edit mode. this.editMode = true }
$sb = $app['request']->query->get('_storyblok_tk'); if (!empty($sb)) { $pre_token = $sb['space_id'] . ':' . YOUR_PREVIEW_TOKEN . ':' . $sb['timestamp']; $token = sha1($pre_token); if ($token == $sb['token'] && (int)$sb['timestamp'] > strtotime('now') - 3600) { $app['config.storyblok.edit_mode'] = true; // you're in the edit mode. } }
In the demo above we expect 1 hour as the time of a token being valid. So basically that an editor will work max 1 hour on one page before switching to another entry inside the editor or refreshing the browser window. You can extend that by adjusting 3600
with the value you need.