What is the long term permalink strategy for published notebook?

When we publish a notebook, what is the rule that creates the URL? It seems that if the first cell is a markdown with a h1 string, the URL is set to that string. And there is not versioning hash like in gist.

I created a notebook this way with title # Einstein, the URL is https://beta.observablehq.com/@ontouchstart/einstein

Then I delete the published notebook, so you will get a 404 with the above URL.

However, then I create another notebook with the same title, it gives me a new URL:
https://beta.observablehq.com/@ontouchstart/einstein/2
there is no way for me to reuse the URL I just deleted. Is this the right behavior by design?

What is the long term https://en.wikipedia.org/wiki/Permalink strategy? I think this could be a critical issue for the eco-system.

2 Likes

Sorry for the delay in answering this one:

Okay, so:

It seems that if the first cell is a markdown with a h1 string, the URL is set to that string.

Yep! The URL slug of each notebook is derived from:

  • the text content of the first cell
  • removing/replaces spaces, punctuation, and adding - in their place, to make it url safe
  • and then if that user already has a notebook with that slug, adding a /2 (or 3, 4…) to disambiguate the slugs

However, then I create another notebook with the same title, it gives me a new URL:
https://beta.observablehq.com/@ontouchstart/einstein/21
there is no way for me to reuse the URL I just deleted. Is this the right behavior by design?

Deleting a notebook removes it from listings, but because other people could have added something like

import {thing} from "@ontouchstart/einstein"

To their notebooks, we don’t want one person deleting a notebook to cause a chain reaction of broken notebooks - like in the left-pad controversy. So, notebooks that import parts of deleted notebooks continue to work, which means that the original permalink - @ontouchstart/einstein - continues to be reserved, so any new notebooks named the same thing will get a /2 (or 3 or 4) disambiguating postfix.

Re: versioning. Notebooks do have versions, but they aren’t exposed, yet. We’ll soon launch the ability to go back in time, and expose better ways to import specific versions of a notebook. The data’s there so that all notebooks will have history on feature launch, but we’re being careful about implementation. Linked URLs, though, won’t likely contain versions, much like GitHub repo URLs don’t have versions by default, and instead show the current HEAD version of a repository.


Footnote: this deletion policy does mean that deleted published notebooks can still be imported; if you require a deleted notebook to be deleted for security reasons, you can contact the staff and we’ll manually, permanently, delete it.

re: versioning—any thoughts on adding lockfiles for transitive notebook deps? given what’s been said about notebook stability, it seems like lockfiles will inevitably come up.

i wonder if it’s appropriate to publish notebooks as @observable-scoped packages to solve that problem.

Shaun — great point!

We haven’t yet implemented it, but the plan is to begin pinning all external notebook dependencies by default. This won’t involve an explicit, separate, lockfile — but it will involve metadata at the notebook level that remembers exact versions of imported libraries and other notebooks (and their transitively linked libraries and notebooks).

Our current notion is to pin the imported version at the moment you first import the dependency, and provide you a facility to update it (re-pinning at a later version) should you wish to update later.

Of course, you can always specify a specific version to import ("library@3"), or the most recent version ("@jashkenas/super-useful@latest").

As for publishing notebooks as modules, or npm packages — a suggested workflow for that is going to be a bit later down the line. But it’s certainly promising…