← All packagesConnect · v0.1.0 · Apache-2.0
@flashyos/page
One page, one card, one claim — written by the same call that sets the title
One page, one card, one claim — per-page social images, canonical metadata and structured data for a property that expects to be cited by search engines and answered from by generative ones.
Why it exists
A measurement across thirteen properties found the shape of a set of sites good at metadata and bad at identity: 77% of 733 pages had a title of their own, and 29% had a canonical, 20% had structured data, and 11% had a card. 539 pages rendered an ancestor’s card — the same rectangle on every sibling. One call sets the title, the description, the canonical, the Open Graph and Twitter cards and the card’s own URL, so a page’s card cannot disagree with its title, because the same call writes both.
What it refuses to do
It will not invent a description — no falling back to the site’s, no deriving one from the title, because a page with nothing of its own to say should say so in review rather than ship a card repeating the homepage. It will not date a page it cannot date: `dateModified` is omitted rather than stamped with the build time, because a summariser repeats that date as fact. And it will not restate the organisation — `publisher` is an `@id` reference to the org defined once at its own address, since a page carrying the org’s name and logo is a page that disagrees with the charter the week it changes.
How it works
One call composes a page’s metadata from the page’s own facts: title, description, canonical, Open Graph and Twitter cards, and the URL of a card rendered for that page. The card is one route rather than a file per segment — Next resolves `opengraph-image.tsx` per segment and walks up, so 733 cards is 733 files, which is why the estate had 79.
SEO and GEO are the same fields read twice. A search engine ranks a page; a generative engine decides whether to quote it and whether it can attribute the quote, and everything that makes the second possible is already on the first one’s list — a canonical so a citation resolves to one address, a description stating the claim rather than selling it, structured data naming the entity and the organisation answering for it, and a card so the citation renders as something. It is one function so a property cannot do the search half and skip the other.
The mark is the single restatement in the package: Satori renders inside a build with no access to a property’s vendored `brand/`, so `BOLT_PATH` and `ACCENT` are copies — and `tools/brand-drift.test.mjs` compares both against the canonical kit and fails on disagreement.
Related concepts
Use it
Declare the property once, then state each page’s own facts
export const meta = (page) => pageMetadata(SITE, page);
export const metadata = meta({
path: '/directory',
title: 'The Directory — verifiable relationship claims',
description: 'A provenance envelope for relationship claims…',
eyebrow: 'Directory',
});In practice
Give every page its own card instead of its ancestor’s
One card route takes the page’s eyebrow and title as query parameters, so a card exists for every page without a file per segment — and it is written by the same call as the title, so the two cannot drift.
Make a page quotable by a generative engine
A canonical so a citation resolves to one address, a description that states the claim, and structured data naming the entity and the organisation answering for it — set together, so a property cannot ship the ranking half and skip the attribution half.
How it stays honest
The one thing it restates — the mark, because Satori cannot reach a property’s vendored brand kit at build time — is pinned by `tools/brand-drift.test.mjs` against the canonical kit in flashy-group, and that test found a real drift on its first run: this site’s own social card drew a bolt of its own, on the property that publishes the standard.
Questions
What does @flashyos/page do?
It composes a page’s title, description, canonical URL, Open Graph and Twitter cards and its social image URL from the page’s own facts, in one call — so the card and the title are written together and cannot disagree.
Why does it refuse to inherit a description?
Because a page with nothing of its own to say should say so in review rather than ship a card repeating the homepage. Across thirteen properties, 539 of 733 pages rendered an ancestor’s card — the same rectangle on every sibling.
Why is dateModified omitted rather than defaulted?
A build time is not a modification date, and a summariser repeats whatever date it finds as fact. A page it cannot date carries no date.
Is this an SEO package or a GEO package?
Both, because they are the same fields read twice. A search engine ranks the page; a generative engine decides whether it can quote and attribute it — and the canonical, description and structured data that make the second possible are already on the first one’s list.
The licence
Apache-2.0, read from the package’s own manifest. Embed it in anything, including closed software — that is what makes a spec adoptable and a verifier worth running. FlashyOS’s server side is AGPL-3.0-only instead, and a test in the monorepo asserts the direction between them: AGPL code may consume this, this may never consume AGPL code.
Keep reading
Also in connect