fetch a notebook info/thumbnail

Is there a way to obtain the info and thumbnail for a notebook given its url? I know we can obtain this information for entire collections using https://api.observablehq.com/collection/${collectionpath}, but is there an equivalent way to do it for a single notebook?

1 Like

I’m sure that @mootari knows, given that the thumbnails all show up in his Sortable notebook list.

There are two routes by which you can fetch the thumbnail ID for a specific notebook:

  1. If you already have the notebook ID, you can load a smaller dataset via

    https://api.observablehq.com/document/b8c5be7836c14484/meta
    

    The returned dataset also tells you wether a custom thumbnail was provided.

  2. If you only have the slug, you’ll have to use a route that also returns all of a notebook’s nodes:

    https://api.observablehq.com/document/@mootari/sortable-notebook-list
    

In both cases you can access the notebook thumbnail ID in the returned JSON data through data.thumbnail. The thumbnail URL is then constructed this way:

`https://static.observableusercontent.com/thumbnail/${thumbnail_id}.jpg`

Note that both routes require a special CORS proxy that allows you to set the Origin header to "https://observablehq.com". You can find such a proxy here (this proxy is also used by Sortable Notebook List).

2 Likes

Alternatively you can fetch the title and thumbnail URL from the notebook’s HTML. This still requires a CORS proxy, but doesn’t require a fake origin:

fetch('https://cors.bridged.cc/' + 'https://observablehq.com/@mootari/sortable-notebook-list')
  .then(r => r.text())
  .then(t => ({
    title: t.match('<meta property="og:title" content="([^"]+)')[1],
    thumbnail: t.match('<meta property="og:image" content="([^"]+)')[1],
  }))

Ideally we would have used a DOMParser + querySelector here. Unfortunately the HTML is heavily minified and omits closing tags whereever possible, which trips up DOMParser.

This is very cool!