Skip to main content

1.3. Render File

note

Take a look at the i18n page for more information on translating widgets.

Widgets are stand alone JS applications, but a component library only has components. To bridge that gap we need to create a render file. This is a file that will render a component in a <div> that the CMS will print on the page. The JavaScript application will render inside that <div>.

Rendering a component is heavily dependent on the JS framework you are using. This step will look different for React, Vue, Angular, Web Components, ...

src/components/notification/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.scss';
import ToastNotification from './components/Widget';
import * as serviceWorker from './core/bin/serviceWorker';
import { IntlProvider } from 'react-intl';
import i18n from './core/bin/i18n.js';

/**
* Renders the widget.
*
* It renders a react application as the widget.
*
* @param {string} instanceId
* The already present HTML element ID where the react app will be rendered.
* @param {string} langCode
* The language code for internationalization purposes.
* @param {string} origin
* Protocol and hostname where a JSONAPI endpoint is available.
* @param {Function} cb
* A callback that executes after the widget has been rendered.
*
* @return {Promise<void>}
* The async render function.
*/
module.exports = async function(instanceId, langCode, origin, cb) => {
const element = document.getElementById(instanceId);
const translation = new i18n(langCode || serviceWorker.getUrlLocale());

ReactDOM.render(
<React.StrictMode>
<IntlProvider locale={translation.locale} messages={translation.messages}>
<ToastNotification
title={element.getAttribute('data-title')}
subtitle={element.getAttribute('data-description')}
caption={element.getAttribute('data-caption')}
kind={element.getAttribute('data-kind')}
/>
</IntlProvider>
</React.StrictMode>,
element,
() => cb(element),
);
serviceWorker.unregister();
}
info

Note that the editorial input from the CMS is made available to you as data attributes in the wrapping <div>. You can get those values with element.getAttribute('data-<propertyname>'). This is how you feed the editorial input to the JavaScript component props.