Embed an Observable Notebook in a Hugo site

I recently discovered and started playing around with Observable Notebooks, a neat product from the brilliant mind behind d3, Mike Bostock. Observable Notebooks are interactive documents defined by code - a combination of markdown, javascript, and more - that can be used to explain as well as visualize data.

It turns out its pretty simple to embed one of these notebooks in a hugo site using a custom shortcode. I defined the shortcode to take exactly one parameter, which is the directory or url to the notebook file. An example implementation, which appears at the end of this post, was generated using:

{{< observablenotebook "/notebook/mynotebook.js" >}}

where mynotebook.js is located in the static/notebook/ folder within my site.

You can also use the url from the Observable api, which allows you to update the notebook there and have the changes reflected here in the post. The url should be of the form https://api.observablehq.com/@jchatkinson/design-of-a-diagonally-reinforced-header.js?key=xxxxxxxxx" where the key is unique to the user.

The quick ‘n dirty way to get started is to grab the code snippet below and save it as layouts\shortcodes\observablenotebook.html in the directory of your site. Note that the name of the file (minus the .html) becomes the shortcode identifier.

<div id="obs-notebook"></div>

<script type="module">
  // Load the Observable runtime and inspector.
  import {Runtime, Inspector} from "https://unpkg.com/@observablehq/notebook-runtime?module";

  // Your notebook, compiled as an ES module or local file.
  import notebook from "{{ index .Params 0 }}";

  // Load the notebook, observing its cells with a default Inspector
  // that simply renders the value of each cell into the provided DOM node.
  Runtime.load(notebook, Inspector.into(document.getElementById('obs-notebook')));
  
</script>

<style>
    #obs-notebook {
      font-size: 0.8em;
      background: #fdfdfd;
      border-radius: 4px;
      border: 1px solid #ccc;
      padding: 9px;
    }
</style>

The code above was modified from Jeremy Ashkenas’ notebook on embedding notebooks

It’s not perfect, but it works pretty good considering it took all of 15 minutes to set up. In the future I will play with the css to differentiate it from the rest of the post, as well as work out some bugs - for instance, my function code for db() and A() is not shown. Also, any variable that you want editable will need to be defined in the notebook at an html input, rather than simply assigning the variable a value.

You can see the embedded notebook below using the shortcode we just created: