A link preview card needs four or five things from a page: a title, a
description, an image, the site's name and its icon. Pages say most of it in
Open Graph and Twitter tags, but not all pages, not always correctly, and some
only once JavaScript has run. Readmint's preview operation does the fetching
and the fallbacks.
One call
curl https://api-readmint.plxi.us/v1/preview \
-H "X-API-Key: $READMINT_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://github.com/rust-lang/rust"}'
{
"url": "https://github.com/rust-lang/rust",
"title": "GitHub - rust-lang/rust: Empowering everyone to build reliable and efficient software.",
"description": "Empowering everyone to build reliable and efficient software. - rust-lang/rust",
"site_name": "GitHub",
"type": "object",
"image": {
"url": "https://opengraph.githubassets.com/…/rust-lang/rust",
"width": 1200,
"height": 600,
"alt": "Empowering everyone to build reliable and efficient software. - rust-lang/rust"
},
"favicon": "https://github.githubassets.com/favicons/favicon.svg",
"oembed": null,
"rendered": false,
"credits": 1
}
Where each field comes from
- title, description: Open Graph first, then Twitter's tags, then the
page's own
<title>and meta description. - image:
og:image(orog:image:secure_url, or Twitter's image), made a full URL. When the page doesn't give its size, Readmint reads the width and height from the start of the image file, so you can lay out the card before the image loads. - favicon: the best of the page's icons: an SVG, then the one nearest 32
pixels;
/favicon.icowhen the page lists none. Every icon is inicons. - oembed: for pages that offer oEmbed (YouTube, Vimeo, X, Spotify and
others), the provider's own answer:
title,author_name,provider_name,thumbnail_urland the embedhtml.
Pages that need a browser
If a plain fetch finds no title (a page built by JavaScript, or a site that
turns plain clients away), Readmint loads the page in a real browser and reads
the tags from there. rendered says so. Send render: "never" to skip that.
Cache it
Previews change rarely. Readmint keeps each one for a day (max_age, in
seconds; 0 fetches it fresh), and you should cache the answer on your side
too, keyed by URL.
Safety
Users paste anything into a chat box. Readmint only fetches public addresses:
a link to localhost, a private network or a cloud metadata address is
refused, redirects included, and isn't charged. That's the part that is easy
to get wrong when you build previews on your own server.