Miro is an amazing tool, I’ve been using it for about 3 years now and I love it.
Miro’s strength is that it, much like the physical whiteboard it’s emulating, can hold anything which makes it really powerful for collaboration and big picture work.
My team have been using it to aid visualising the ‘as-is’ and ‘to-be’ for the work our client is requesting, using images to visualise the user journey with loads of arrows and stickies to pinpoint areas we need to build an understanding in.
This works well, but I felt there was something missing from the conversation which was the output of our automated tests.
If we could have access to the test results from within Miro we’d be able to get a quick glance of test coverage, spot any areas where coverage needed to be increased and be able to see if the tests were passing. Essentially turning Miro into a living documentation tool.
So I set about building a proof-of-concept and over an evening managed to pull together a functioning plugin, using Glitch to host the files needed to power it and I’m really happy with the result.
Setting up a Miro web plugin
Before you start building anything you first need to set up your Miro ‘Dev Team’ account and create an app to install on your Miro account.
Creating a Dev Team gives you a special developer account which has the same limitations of the free account but this allows you to install your web plugin without impacting your main account.
Once you’ve created your Dev Team account you can then create a new app under that account’s Apps & Integrations section. This app needs to be set up to have the
With the permissions set you then install the app onto your Dev Team account and take note of the OAuth access token this generates. This is only needed if you’re going to use the Miro REST API so even if you don’t think you need this, it’s best to save it.
Finally the last step is to set the ‘Web-plugin’ value for the app. This is the URL for the main HTML file that will act as the entry point for the web plugin. I used a Glitch ‘hello-webpage’ starter for this but you can also use tools like
ngrok to make files on your local machine available.
With the app installed to your board and pointed to the entry point you’re now ready to start building your plugin. I’ll cover some basics on building a web plugin below but Miro provide a number of examples to get you started.
Working with the Miro web plugin SDK
Miro web plugins work by loading your HTML into an iframe and using postMessage to communicate between the iframe and the Miro app itself.
This means you’ll need to load the Miro SDK in your HTML entry point so it can be used to facilitate this communication. If you’re looking to build an interface for your plugin it’s also worth loading in the Miro CSS styles so your plugin meets the Miro UI standards.
As your loading HTML into an iframe you can build your app in any framework you’d like but I decided to build mine in statically served HTML and vanilla JS as this was quicker to get started with and I only needed to update a couple of elements on the page when the user interacted with the board.
Adding your plugin to the Miro UI
In order to have your plugin accessible to the user you need to first add it to the UI. There are a number of places in the UI you can add your plugin to but the common pattern appears to be the bottom bar.
You can add your plugin to the bottom bar using the code below and can define an icon to show and a callback to fire when the user presses the button.
As part of the callback you can tell Miro to open a sidebar which will load the defined URL into an iframe. The page that is loaded into the sidebar will need a copy of the Miro SDK too to handle the communication via postMessage but the use of the sidebar allows for more information to be shown to the user and in a dynamic fashion as it can be updated as the user selects widgets.
Interacting with Widgets on the board
Widgets are the name given to the entities (such as text, stickies, images etc) present on the Miro board.
miro object of the Miro SDK allows for the setting up of event listeners which will be triggered when events such as the selection of a widget happen. You can subscribe to these events using the code below, supplying a function to call when the event is triggered
At the time of writing the following events for widgets are available:
SELECTION_UPDATED— For when the user’s selection changes
WIDGETS_CREATED— For when a user creates a new widget
WIDGETS_DELETED— For when a user deletes a widget
WIDGETS_TRANSFORMATION_UPDATED— For when a user updates the size of the widget
ALL_WIDGETS_LOADED— For when all the widgets on a board have finished loading in
METADATA_CHANGED— For when the metadata on a widget is updated
For my simple app that showed information for the currently selected widget(s) I only needed to listen to
SELECTION_UPDATED but I can imagine
WIDGETS_DELETED would also be useful to listen to so records can be deleted when the widget is.
In order to get the list of selected widgets after the
SELECTION_UPDATED event has triggered you need to query the board’s active selection using
miro.board.selection.get() which returns a promise of an array of widget objects.
The widget object contains the id, position, sizing and transformation information for the widget along with properties that hold the actual data for the widget such as the text or image information.
You can check the Miro API docs for more information on the properties available on the different widget types.
Once you have the widget you can change these properties and update them on the board using the
miro.board.widgets.update function which takes an array of partial widget objects containing just the fields to update and the widget id.
If you need to change the type of widget being shown but want to retain the information then you can delete the old widget and re-use the values from it to create a new widget of the desired type.
This can be seen in the ‘Stickies to shapes’ example on the Miro developer docs but you can use these independently for your use case.
Notifying the user
If your operation takes a while then you might find yourself needing to inform the user that it’s completed successfully. You can use the
miro.showNotification function to do this, providing the message to show as an argument.
This will show a toast like pop-up in the UI with the provided message.
Testing your plugin
In order to test the functionality within Miro the best means to do this is to create a board in your Dev Team account with a set of widgets in various different states so that you can work through a set of scenarios to test the functionality.
As the Miro web plugin is just loaded into an iframe though you can build your plugin using the development tooling that you normally use for web development and treat the iframe to host page postMessage functionality as the boundary for these tests.
In Miro’s app-examples repository on Github they’ve included
miro.d.ts which can be used to help mock out the Miro SDK objects for unit testing.
You could even use the interfaces in
miro.d.ts to create a set of postMessage commands to send into your plugin to test it’s behaviour in an iframe and use a tool like selenium to verify the DOM changes and trigger the messaging.
Miro web plugin development is really easy to get started with and hosting your plugin files on Glitch makes development quick and collaborative.
One aspect I have yet to fully understand is the distribution of a web plugin to the Miro marketplace and how a plugin developer would be able to monetise their creations. It looks like you have to offer your Miro integrations for free and charge users outside of the Miro platform.
If you’re on a team that’s using Miro and want to enhance your team’s ability to collaborate by bringing data in from the tools you use then I’d highly recommend spending some time building a Miro web plugin.