Anchors don't work in embedded notebook

Hi, I tried using anchors to allow the reader to jump around my Observable notebook.

The anchors work fine on the notebook itself. However, I’m embedding my notebook in my personal site. And, I found out that the anchors don’t work there. This is because the name of the cell isn’t being carried over to the embedded notebook as the id of the div.

Any idea how to fix this? Is it also a bug that needs to be fixed?

1 Like

Here’s a modification of the intoFilter function (from your last thread) that’ll make these links work:

<script type="module">

import {Runtime, Inspector} from "https://cdn.jsdelivr.net/npm/@observablehq/runtime@4/dist/runtime.js";
import notebook from "./YOUR-NOTEBOOK.js";

// modified from https://github.com/observablehq/inspector/blob/master/src/index.js#L51
const intoFilter = function(container, filterFunc) {
  if (typeof container === "string") {
    container = document.querySelector(container);
    if (container == null) throw new Error("container not found");
  }
  return function(variable) {
    if (filterFunc(variable.name)) {
      const div = document.createElement("div");
      if (variable.name) {
        const name = variable.name.split(' ');
        if (name[0] === "viewof" || name[0] === "initial") name.shift();
        if (name.length === 1 && !document.querySelector(name[0])) div.setAttribute("id", name[0]);
      }
      return new Inspector(container.appendChild(div));
    }
  };
};

// you can enter an arbitrary filtering function as the second argument to intoFilter.
// it should take the variable name (a string or undefined) as an input and return a boolean
Runtime.load(notebook, intoFilter(document.body, (name) => name !== "excludeThis"));

</script>

Edit: made more robust; should work better now with viewof and mutable cells.
Edit 2: added missing braces…

Missing braces fixed the issue haha. It works now. :slight_smile:

if (name.length === 1 && !document.querySelector(name[0]))

The second check is just to make sure nothing else on the page already has that id, right?

Yeah, it’s kind of a hack. The underlying concern there is that a cell viewof X actually expands into 2 variables, one named viewof X and one named X (similarly, mutable Y expands into initial Y, mutable Y and Y). However, only viewof X (respectively, initial Y) is displayed on observablehq.com. The code there should give the id only to viewof X (resp. initial Y) and not X (resp. Y) (though things can break down if you have name conflicts between variables in the notebook and pre-existing id’s on the page you’re embedding the notebook into).

Ah okay, got it. :slight_smile:

Is the id thing not a bug? Is it not reasonable to expect that ids will be assigned automatically so that that your anchors still work on an embedded notebook? Or, do you reckon there’s some reason that shouldn’t be the default behaviour?

I definitely see where you’re coming from. On the other hand here’s a reply I got a while back which suggests that this sort of thing could also be considered out-of-scope in some sense: