|
| 1 | +In this page, technical requirements to create widgets compatible with the registry are described. |
| 2 | + |
| 3 | +### Required commands |
| 4 | + |
| 5 | +All widgets need to include a `package.json` file which provides the following two commands: |
| 6 | + |
| 7 | +* `npm install` to install dependencies, libraries or any other components needed by the widget. |
| 8 | +* `PUBLIC_URL='<some url>' npm run build` to build a production compilation of the widget. The `PUBLIC_URL` parameter will be discussed later. |
| 9 | + |
| 10 | +### Directory structure |
| 11 | + |
| 12 | +The build command should generate a directory on the root of the project named `build`, and with the following structure: |
| 13 | + |
| 14 | +``` |
| 15 | +build |
| 16 | +├── js |
| 17 | +│ └── main.js |
| 18 | +└── media |
| 19 | + └── picture.png |
| 20 | +``` |
| 21 | + |
| 22 | +### Loading the widget on the browser |
| 23 | + |
| 24 | +The widget itself should be fully contained on the `build/js/main.js` file, which should provide a render function to allow the widget to be loaded on the browser. This render function should be injected onto the window object in the browser. It is important to name the render function as `render` + the machine name of the widget in camel case (eg. for the Case Studies widget, whose machine name (or shortcode) is `case-studies-widget`, the expected name for the render function is `renderCaseStudiesWidget`). |
| 25 | + |
| 26 | +This is an example of a render function with a documentation block explaining the different parameters: |
| 27 | + |
| 28 | +``` |
| 29 | +/** |
| 30 | + * Renders the widget. |
| 31 | + * |
| 32 | + * @param {string} instanceId |
| 33 | + * The already present HTML element ID where the react app will be rendered. |
| 34 | + * @param {string} langCode |
| 35 | + * The language code for internationalization purposes. |
| 36 | + * @param {string} origin |
| 37 | + * Protocol and hostname where a JSONAPI endpoint is available. |
| 38 | + * @param {Function} cb |
| 39 | + * A callback that executes after the widget has been rendered. |
| 40 | + */ |
| 41 | +function render(instanceId, langCode, origin, cb) { |
| 42 | + // Do widget stuff |
| 43 | +} |
| 44 | +
|
| 45 | +window.renderExampleWidget = render; |
| 46 | +``` |
| 47 | + |
| 48 | +### Loading assets |
| 49 | + |
| 50 | +The `main.js` library has the responsibility to load any asset from the `build/media` directory. To access these files from the `main.js` library, it's required to use relative urls prepended by an environment variable named `PUBLIC_URL`, something like this: |
| 51 | + |
| 52 | +``` |
| 53 | + <img src="`${PUBLIC_URL}/media/picture.png`" /> |
| 54 | +``` |
| 55 | + |
| 56 | +This way you can leave the `PUBLIC_URL` variable empty for local development, but, once uploaded to the registry, the production build of the widget will know where it can locate the assets on the registry. More information about the `PUBLIC_URL` parameter can be found [here](https://github.com/js-widgets/widget-registry-boilerplate/wiki/Deployment-process#the-widget-building-process). |
| 57 | + |
| 58 | +If you are using the [Example Widget](https://github.com/js-widgets/example-widget) as a base for your widget, you would need to load assets like this: |
| 59 | + |
| 60 | +``` |
| 61 | +import logo from 'assets/images/logo.png'; |
| 62 | +
|
| 63 | +class Widget { |
| 64 | + render() { |
| 65 | + return ( |
| 66 | + <img src={logo} alt="Logo" width="100" height="*" /> |
| 67 | + } |
| 68 | + } |
| 69 | +} |
| 70 | +``` |
| 71 | + |
| 72 | +A final consideration about styles: All custom CSS should be written using a CSS-in-JS pattern, such as [using object syntax with style attribute](https://reactjs.org/docs/dom-elements.html#style) or including a CSS-in-JS library like [Emotion](https://emotion.sh/docs/introduction) or one of [many other options](https://blog.bitsrc.io/9-css-in-js-libraries-you-should-know-in-2018-25afb4025b9b). The widget registry does not support CSS files in an effort to keep widget styles from having adverse affects on the page in which they're embedded. |
0 commit comments