embed runtime with external require

Hi All:

I’ve built an interactive chart that depends on MathJax for rendering pretty math as svg. I’d like to embed the cell containing the the chart as a runtime in a website I’m building (using Quarto).

Things work just as I want them to in the observable notebook. But when I select “embed” for the cell I want, select “javascript runtime”, paste the code into my project and render my site, it appears that the import of the MathJax code that happens in the notebook is not included in the runtime code that I’ve copied. I get an error in the render process when building the site that says effToUtility = RuntimeError: MathJax.tex2svg is not a function. (effToUtility is the variable name for the cell I’m trying to export as a runtime).

Here’s the notebook containing the cell I’m trying to embed (the first cell after the title):

I’ve also tried adding

let MathJax = await require('https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js').catch(
  () => window['MathJax']
)

to the top of the codeblock in the cell in which I use MathJax.tex2svg. But that did not change the result of embedding the cell I want as a runtime.

I’ll be very grateful to be told what I’m misunderstanding about require, external dependencies and embedding a runtime!

Thank you!

Embedding into seems to work fine on my site:

https://wncviz.com/temp/temp.html

Javascript console produced no errors. I’ve never used Quarto so I’m not sure if there’s anything there that might cause a problem.

I’ve been a bit curious about Quarto, so I figured I’d look into this a bit more closely. After a bit of fiddling, I successfully embedded your notebook into a site built by Quarto here:
https://wncviz.com/temp/Quarto/embed/

I’m completely new to Quarto but here’s the deal, as far as I understand it:

First, you’re not going to use embed code generated by the Observable notebook. Instead, you’re going to write a markdown file (actually, an extended version of markdown with a .qmd extension) and then process that file with a Quarto command. Specifically, I wrote a markdown file named index.qmd and then processed that file with

quarto render index.qmd

Alternatively, you could process it with

quarto preview index.qmd

The second version is nice because it automatically fires up a web server and loads the page. The render command simply generates the output. You can’t just open the index.html file from your hard drive or you’ll get CORS errors; you need to open it from a web server.

You can look at the output that I linked on my web page to see the result. Quarto also produces a “Code” button in the upper right that allows you to view the source of the original .qmd source file that I typed and processed. In that source file, you’ll see code blocks like:

```{ojs}
MathJax = require('https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js').catch(
  () => window['MathJax']
)
```

This is a block of markdown that Quarto interprets as ojs or Observable Javascript. The point is that Quarto takes these and turns them into actual executable Javascript in the output .html file. At no point does it even “embed” your notebook - at least, not the version that lives on ObservableHQ. Rather, it generates output that includes all the dependencies - like the Observable runtime.

1 Like

And here’s an even easier way. Evidently, Quarto is aware of and can import all the notebooks on ObservableHQ. Thus, the following is a complete .qmd file that embeds your demo after a quarto render command:

---
title: "Quarto Embed"
format:
  html:
    toc: false
    echo: false
---

Just trying to figure out how to use Quarto!

```{ojs}
effToUtility
```

```{ojs}
import {effToUtility} from '5d6e6641d816d80d'
```
1 Like

Thanks mcmcclur!

Your example quarto source files are helpful, because I think they helped me identify what’s probably going wrong in my quarto source: I’m trying to embed (or import) an observable notebook into a quarto source file that already embeds other observable notebooks that also import tex2svg, assigning the imported module to a variable with the same name. I’m guessing that this is causing some sort of conflict in the JS code quarto generates for the page as a whole.

Anyway, this is clearly an issue that belongs on the quarto forum, not on this one!

Right now, the page I’m developing contains several charts, each of which is embedded or imported from a different observable notebook. I’m going to try to solve my problem by creating a single observable notebook that produces all the charts I need for the page I’m developing (and thus has only one cell that imports tex2svg and my other dependencies), and see if embedding/importing all the various cells from that single notebook results in a functioning page rendered by quarto.

1 Like

Still troubleshooting this, and ran into some truly weird behavior when I try to access tex2svg via require in quarto. This seems to be the root of the problem I’m running into. I’ve posted the details over in the quarto forum, because this seem to me to be an issue specific to quarto. Nonetheless, linking it here because I’m pretty sure it’s the “true” root of the problem that inspired this post in the first place!

1 Like