DEV Community

chovy
chovy

Posted on Originally published at dev.profullstack.com

OpenSite: one record about a page, and an index that reads any URL you paste

Every link you paste into a chat becomes a card. The card is drawn from tags the page carries for that purpose: a title, a line, a picture. A dozen apps read those tags a dozen ways, every one of them caches its first reading for days, and none of them tell you what they got.

This week a nixamp share link taught me that the hard way. The card read "server1" with no picture. I fixed the page. The chat app kept showing the old card, because it had cached the empty one from the minute after a redeploy. There was no way to see what the page said about itself, and no way to tell the app to look again.

So there are two new things.

The spec

OpenSite is the reading, written down. A record per URL: what a careful reader concluded about the page. Title, description, picture with its size, kind, canonical address, author, feeds, dates, and the og and twitter tags exactly as the page carried them, so you can see what each scraper saw. A descriptor a site serves about itself at /.well-known/opensite.json: its name, its operator, whether it wants to be read at all, and optionally a file of its own records so an index need not read every page.

The part I care about most is the reading order. Every scraper already does this and nobody had written it down: canonical from rel=canonical, else og:url, else where the redirects landed. Title from JSON-LD, else og:title, else twitter:title, else the title tag. Picture from og:image with its width and height, else twitter:image, else JSON-LD, else the biggest icon. Robots and the descriptor are honoured. At most five redirects, two megabytes, fifteen seconds.

The spec also carries a table of what each consumer reads and caches. Two rules fall out of it. Put the card tags in the first few kilobytes of the page. And when an app has cached a wrong card, the only certain fix is a URL it has not seen. A query parameter it ignores is enough.

The index

nichedb.dev/c/sites keeps records. Paste any address at nichedb.dev/c/sites/add and it is read now, the way the spec says, and you get three things on one page: every tag the page carries, the card as X, Slack, iMessage, Discord, LinkedIn and WhatsApp would draw it, and the OpenSite record that is kept. The record lives at /c/sites/<host>/<path>, query string and all, because a page's identity can be in its query.

The same read is an API. POST /api/v1/sites with a URL reads it now. GET /api/v1/sites?url= answers what is kept, or reads the page when the reading is older than an hour. Our own sites are walked from their sitemaps on a schedule, so there is a card for every page we publish before anyone asks.

What is deliberately not in it

No ranking. A record says what a page is; which page is better is an index's business, under its own name. No rendering rules; the consumer table is a reader's guide, not a law. No page content; the record is the card, not the page. No push; a site serves a file and an index reads it.

Get it

Spec: https://logicsrc.com/opensite. Index: https://nichedb.dev/c/sites. Paste a URL: https://nichedb.dev/c/sites/add.

The reader is in nichedb's core package, @nichedb/core/opensite, pure except for the fetch, so anyone can run the same reading over their own pages.

Top comments (0)