Using Graphviz JS in Gatsby to preview DOT

November 30, 2020

Our website DevToolsDaily is implemented on Gatsby and hosted in Netlify; and it has GraphViz Playground which previews dot markup in the browser.

Graphviz JS library is WASM library, that is heavy, takes time to load, and loads asyncronously, and is hard to integrate with static file generator like gatsby.

Gatsby website has a guide for that which mentions few options:

  1. use different library
  2. load from CDN using <Helmet>
  3. use loadable-components
  4. use react-lazy

We've tried all options, and none of them fully worked.

The solution that worked is to inject a script tag on the page after it loads.


How we do that

  1. helper script to asyncronously add script tag on a page
function new_script(src) {
    return new Promise(function(resolve, reject) {
        if (typeof window !== "undefined") {
            var script = window.document.createElement('script');
            script.src = src;
            script.addEventListener('load', function () {
                resolve();
            });
            script.addEventListener('error', function (e) {
                reject(e);
            });
            window.document.body.appendChild(script);
        }
    })
};

that will complete promise when script is loaded.

  1. invoke that script on componentDidMount so it's only executed on client side
  componentDidMount() {
      var my_script = new_script('https://cdn.jsdelivr.net/npm/@hpcc-js/wasm/dist/graphviz.umd.js');
      my_script.then(() => {
        ...
      });
  }
  1. after wasm is loaded, you need to asyncronously load Graphviz, and then graphviz object is ready to use
  componentDidMount() {
      var my_script = new_script('https://cdn.jsdelivr.net/npm/@hpcc-js/wasm/dist/graphviz.umd.js');
      my_script.then(() => {
        window["@hpcc-js/wasm"].Graphviz.load().then(graphviz => {
          window.graphviz = graphviz;
          // DO what you want with `graphviz`
        });
      });
  }

This article was originally published in DevToolsDaily blog