Tool Plugin
Tools are a different way to extend your visual editor. They allow you to improve your productivity by adding some functionality to the editor. Two examples of Tools are importing and exporting content or a custom clipboard.
Tools are specific to stories and will appear in your Visual Editor when editing a story. You can access the installed tools from the top bar
{1}. Here we have installed the Import Translatable Fields {2}

Getting Started
To create a new tool you need to be signed up as a Partner. Head into the partner portal and click on Apps {1} and then the New button {2}. As App type select Tool {3} and click Create {4}.

To get started we will clone the tool plugin starter template: github.com/storyblok/storyblok-tool-example
$ git clone https://github.com/storyblok/storyblok-tool-example.git
$ cd storyblok-tool-example
$ npm install
We will also need to install ngrok to create a tunnel to our local application. Once you installed ngrok, you can start the tunnel to port 3000.
$ npm i -g ngrok
$ ngrok http 3000
After starting the tunnel you will need to add the tunnel URL to the development settings in your tool settings, like in the image below. You need a URL to the app, e.g. the tunnel URL + auth/connect/storyblok
{3} and an Oauth2 callback, e.g. the tunnel URL + auth/callback
{4}.

Inside the starter, you will find a .env-example
file. Rename this file to .env
and fill in the client id {1} and client secret {2} as well as the Oauth2 callback {4}.
.env.local
CONFIDENTIAL_CLIENT_ID="Id from Storyblok App"
CONFIDENTIAL_CLIENT_SECRET="Secret from Storyblok App"
CONFIDENTIAL_CLIENT_REDIRECT_URI=https://YOUR_ID.ngrok.io/auth/callback
Now we can start our development server:
npm run dev
Now if you open http://localhost:3000/
it should redirect to Storyblok, but nothing happens. In order to test it, we first need to install our tool plugin in a specific space. Open any space click on Apps {1}, My apps {2}, and then on the new tool {3}.

Then click Install {1} and open a Story within that Space.

Now go back into Content and open a Story, e.g. Home. The first time you should see a confirmation screen to authorize the application to have access to Storyblok. Click Approve {1}.

Once you authenticate your tool you should be able to see it {2} within the Tools {1} section in the editor.

Reading the Story Context
Inside a tool, you can use the context to get the data of the current story. For that you have to use two window events: message
and postMessage
.
First, we let Storyblok know that there is a tool via the following event. Make sure that name of the tool you created matches the name in the tool
parameter.
window.parent.postMessage({
action: 'tool-changed',
tool: 'storyblok@first-tool',
event: 'getContext'
}, 'https://app.storyblok.com')
After that Storyblok will reply with the Story context, so we need to listen for that with the following listener:
window.addEventListener('message', this.processMessage, false)
Finally, we need to connect everything and add the processMessage
method to set our local component data:
export default {
data() {
return {
story: {},
loadingContext: true
}
},
mounted() {
// redirects you to Storyblok
if (window.top === window.self) {
window.location.assign('https://app.storyblok.com/oauth/tool_redirect')
}
// listens for Storyblok answer
window.addEventListener('message', this.processMessage, false)
// Use getContext to get the current story
window.parent.postMessage({action: 'tool-changed', tool: 'storyblok@first-tool', event: 'getContext'}, 'https://app.storyblok.com')
},
methods: {
processMessage(event) {
// processes the event answer
if (event.data && event.data.action == 'get-context') {
this.loadingContext = false
// get the context story
this.story = event.data.story
// get the context language
this.language = event.data.language
}
}
}
}
Changing the Height of the Tool
It's possible to change the height of the tool by sending an event with the name heightChange
with a height
parameter to the parent window
window.parent.postMessage({
action: 'tool-changed',
tool: 'storyblok@first-tool',
event: 'heightChange',
height: 500},
'https://app.storyblok.com')
Reading the Editor Language
It's possible to get the current language from the get-context
event.
export default {
mounted() {
window.addEventListener('message', this.processMessage, false)
window.parent.postMessage({action: 'tool-changed', tool: 'storyblok@first-tool', event: 'getContext'}, 'https://app.storyblok.com')
},
methods: {
processMessage(event) {
if (event.data && event.data.action == 'get-context') {
this.language = event.data.language
}
}
}
}
Changing Content via the API
Tools work with the storyblok-nuxt-auth module to retrieve and change data from Storyblok via the Storyblok Management API. Inside of a tool you can get for example the user information with the following request:
axios.get('/auth/user', {params: {space_id: this.$route.query.space_id}})
.then((response) => {
console.log(response.data)
})
You can also change stories inside of Storyblok by making post or put requests. You can create for example a new story with the following code:
import axios from 'axios'
export default {
data() {
return {
loading: false,
story: {
name: ''
}
}
},
methods: {
createStory() {
this.loading = true
// The request body is the same from Management API
// https://www.storyblok.com/docs/api/management#core-resources/stories/create-story
const body = {
story: { ...this.story }
}
// get the space id from URL and use it in requests
return axios
.post(`/auth/spaces/${this.$route.query.space_id}/stories`, body)
.then((res) => {
this.loading = false
})
}
}
}