Attaching an element as the preamble when embedding RunKit


#1

Hi,
I discovered RunKit a few days ago and I find the product amazing.

However, there is one use case I wasn’t able to handle while embedding a notebook in a web page:
I have a blog post containing two code blocks:

<div id="code-1"><pre>
  // some JS code here:
  const message = "Hello RunKit";
</pre></div>
Blah Blah Blah
<div id="code-2"><pre>
  // some other JS code here:
  console.log(message);
</pre></div>

I want to replace the element id=“code-2” by a RunKit notebook. But using the code in element “code-1” as the preamble to “code-2”.

I tried several things with no success:

Attaching RunKit to an existing element

<script src="https://embed.runkit.com" data-element-id="code-2" data-preamble-id="code-1">

But it didn’t work. A quick look at the embed.runkit.com script showed me there was no provision for handling preamble like that (or did I missed it?)

Programmatically creating a notebook

I tried also to programmatically create a notebook instead:

<script src="https://embed.runkit.com"></script>
<script>var notebook = RunKit.createNotebook({
    element: document.getElementById("code-2"),
    source: document.getElementById("code-2").textContent,
    preamble: document.getElementById("code-1").textContent,
})</script>

It works, but the notebook is added inside the element “code-2”. It does not replace the inner content of that block.

In that case, an empty element to hold the notebook as described in the doc is unacceptable to me as I want to code to be visible even if JS is disabled in the client browser.

Create a detached notebook to attach it later

Finally, I tried to manually creae a notebook to attach it myself:

 var element = document.getElementById("code-2");
  var notebook = RunKit.createNotebook({
    source: element.textContent,
    preamble: document.getElementById("code-1").textContent,
  });
  element.parent.replaceChild(notebook.iframe, element);

But this time I wasn’t even able to create the notebook. It seems the element attribute is required.

I have no more ideas now. If someone could point me to a possible solution or identify a mistake I made, that would be greatly appreciated!


#2

Hi Sleroux,

Sorry about the issues you’re having. We know our Embed API is a little weird. We’re actively working on a bunch of improvements and changes right now.

You’re correct there was no data attribute, but I’ve gone ahead and added it. It doesn’t reference an element but instead you will just need to inline your code: eg:

<script src = "..." data-preamble = "const message = 'hi runkit';"></script>

Will this work for you?


#3

Cool! Thank you @me1000!

As a matter of fact, this is probably better than referencing a DOM element, since, I realized that later, for tutorial-style blog posts, I may split the preamble into several code blocks. So, with your solution, I can concatenate them.

Concerning the changes in the embed API, I heard that too from Francisco Tolmasky on Twitter. Good luck with that–and I’m looking forward to taking a look at it (I heard it could be published on GitHub :wink:

Best regards,

  • Sylvain