Enhancing Your Miro Boards By Building Your Own Miro Web Plugin
By: Colin Wren
Tags: Programming, JavaScript, Software Development, Product Development, UX

Enhancing Your Miro Boards By Building Your Own Miro Web Plugin Colin Wren Follow Nov 22 · 6 min read

An example of the Miro web plugin I built to add specifications to the images my team uses to plan new functionality. Doing this allows us to define specs on the fly and see the test results as we discuss new functionality

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 boards:read and boards:write permissions.

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.

When Miro loads this file it will create a new entry in the bottom UI with the SVG icon. When the icon is pressed it will launch the sidebar UI which will load the sidebar.html into an iframe

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.

The 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

The Miro onReady function will be called when your sidebar UI is loaded and is used to set up listeners and the initial state

At the time of writing the following events for widgets are available:

SELECTION_UPDATED — For when the user’s selection changes

— For when the user’s selection changes WIDGETS_CREATED — For when a user creates a new widget

— For when a user creates a new widget WIDGETS_DELETED — For when a user deletes a widget

— For when a user deletes a widget WIDGETS_TRANSFORMATION_UPDATED — For when a user updates the size of the widget

— 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

— 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.

As the selectionCallback is called whenever the selection updated event is triggered the miro.board.selection.get() call will return the actively selected widget(s)

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.

Based on the sidebar.html file rendered into the sidebar UI having a convert button the callback on that button being clicked will get all selected stickies and turn them into shape widgets in the current position of the existing widgets.

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.

Summary

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.