Skip to main content

    Creating a new React widget

    We're moving our docs!

    Find the latest version of this page on the Platform website.

    Still can't find what you're looking for? Reach out to #vfs-platform-support on Slack.

    Note: Check out the Adding a new feature doc to make sure you're trying to add the right type of feature to VA.gov.

    Adding a new widget

    All the static pages use the static-pages entry bundle, so any JS code included from that file will be on all static pages. In order to add a widget, you'll want to create a function that loads your desired React components (or plain JS) asynchronously, and mounts to an element on the page with your widget id.

    1. Ensure your page includes the static-pages bundle:
    title: My awesome widget page
    layout: page.html
    ---
    

    Note: The entryname must be absent from the markdown file's front matter or the resulting HTML file will include ${entryname}.js instead of static-pages.js.

    1. Add a mount point element in the static content page your widget will live on:
    <div data-widget-type="my-new-widget" id="someId"></div>
    
    1. Add a start up function to: src/applications/static-pages/static-pages-entry.js:
    ...
    createMyWidget(store, widgetTypes.MY_NEW_WIDGET);
    ...
    

    You should also add a constant for your widget type in src/applications/static-pages/widgetTypes.js:

    export default {
      ...
      MY_NEW_WIDGET: 'my-new-widget',
      ...
    }
    
    1. Write your create widget function:
    export default async function createMyWidget(store, widgetType) {
      const widget = document.querySelector(`[data-widget-type="${widgetType}"]`);
    
      if (widget) {
        // Load widget if there's a mount point for it
        const {
          default: MyNewWidget,
        } = await import(/* webpackChunkName: "my-new-widget" */ '../../platform/site-wide/my-new-widget');
    
        // Do whatever you need to do to start up your widget
        ReactDOM.render(<MyNewWidget>, widget);
      }
    }
    

    Note that we don't import the widget code unless there's a mount point in the DOM. This function will run on every page, so we want to make sure we only download the bulk of the widget code when we're actually going to use it.

    Guidelines for using React on a static page

    We should be careful to not create a bad user experience when using React on static pages. Here are some guidelines you should follow:

    1. JS and React take time to download, parse, and render. Make sure you are providing the appropriate feedback to users while that is happening, with a spinner or another method from the UX team.
    2. Make sure the page is still usable if your React code fails to work. This can mean it fails to download, an error occurs, or just handling the different login states a user can be in.
    3. Be aware of how much weight you're adding to the static-pages bundle and code-split/lazy load when it makes sense.

    Running end-to-end tests on a widget

    Before running end-to-end (e2e) tests for a widget, you must add an entry for your widget to src/applications/registry.scaffold.json. This will allow a landing page to be generated for your widget so you can run end-to-end tests in vets-website. An example entry looks something like:

    {
       "appName": "About VA Disability Ratings",
       "rootUrl": "/disability/about-disability-ratings",
       "widgetType": "disability-rating-calculator"
    },
    
    • appName: The name of the title that will be used for the page.
    • rootUrl: The relative url of the page that the widget will be mounted on.
    • widgetType: The name of the data-widget-type attribute that will be used to mount your widget on the page.