Merkur widget API
A Merkur widget, whether within the application or when returned as JSON by the API endpoint, contains six predefined properties: name
, version
, $in
, $external
, $dependencies
, and $plugins
. The property $in
is intended for internal usage by merkur widget plugins or merkur itself.
Other properties are for your own needs. The property $external
is for storing variables. The property $dependencies
is for defining widget dependencies and specific features of the environment where the widget operates. The last property, $plugins
, is for defining specific widget plugins.
The widget also contains two methods for plugins; setup
and create
. For more details continue to the plugins section. You can use these methods also in widgetProperties
.
The widget instance is sealed after creation so you cannot add properties or functions to the widget directly. But for rare use cases you can use the $external
property. Merkur automatically binds widget functions to receive the widget as a first argument. You can see it in the example widget.
Sometimes you might not be sure whether to store data in widget state or the $external
property. The best way to decide is to ask if you need to react to the change of the variable. If you do, store it in state; if you don’t, or specifically want to avoid that, $external
might be the right choice.
import { createMerkurWidget, createMerkur } from '@merkur/core';
import { componentPlugin } from '@merkur/plugin-component';
import { eventEmitterPlugin } from '@merkur/plugin-event-emitter';
import { render } from 'preact';
import View from './component/View';
import { name, version } from '../package.json';
export const widgetProperties = {
// base merkur widget structure
name,
version,
$dependencies: {
render, // specific render method for client side and server side
},
$plugins: [componentPlugin, eventEmitterPlugin],
setup(widget, widgetDefinition) {
console.log(widgetDefinition); // argument from createMerkurWidget
return widget;
},
// properties and methods which adding componentplugin
assets: [
{
name: 'polyfill.js',
type: 'script',
},
{
name: 'widget.js',
type: 'script',
},
{
name: 'widget.css',
type: 'stylesheet',
},
],
load(widget) {
return {
counter: 0,
...widget.props,
};
},
mount(widget) {
const View = widget.View();
const container = document.getElementById(widget.props.containerSelector);
return widget.$dependencies.render(View, container);
},
update(widget) {
const View = widget.View();
const container = document.getElementById(widget.props.containerSelector);
return widget.$dependencies.render(View, container);
},
// your own defined properties and methods
View,
onClick(widget) {
widget.setState({ counter: widget.state.counter + 1 });
},
onReset(widget) {
widget.setState({ counter: 0 });
},
};
// factory function
// widgetParams are params from API call for widget,
// widgetParams.props = { containerSelector: '.container' };
// we will explain in next section
function createWidget(widgetParams) {
return createMerkurWidget({
...widgetParams,
...widgetProperties,
});
}
// we will explain in next section
const merkur = createMerkur();
merkur.register({
...widgetProperties,
createWidget,
});