Skip to content

App Viewer: social cards and search metadata - #824

Merged
tavdog merged 8 commits into
tronbyt:app-viewer-sourcefrom
saltedlolly:feature/app-viewer-social-cards
Oct 14, 2026
Merged

tavdog merged 8 commits into
tronbyt:app-viewer-sourcefrom
saltedlolly:feature/app-viewer-social-cards

Conversation

@saltedlolly

@saltedlolly saltedlolly commented Oct 13, 2026 •

Copy link
Copy Markdown
Collaborator

What this adds

Sharing an App Viewer page on Bluesky, Mastodon, X, Discord, Slack and similar now shows a proper preview card, and the pages are easier for search engines to understand.

Examples

App cards:

Social card for DigiFacts Social card for Nightscout

The home page and author pages tile the most recently updated apps:

Social card for the App Viewer home page Social card for an author with many apps

Social card for an author with three apps Social card for an author with two apps

Share cards

Every card is a 1200x630 PNG generated during the normal site build, with the Tronbyt logo, "Tronbyt App Viewer", and screenshots drawn as an LED dot matrix, in the Viewer's Press Start 2P font.

  • App cards show the app's screenshot with its name, summary and author. The screenshot is the busiest frame of the 128x64 screenshot if there is one (many animations start on a blank frame), otherwise 64x32 or 64x64. Enlarged screenshots are shrunk back to their real pixels first; photos and screenshots with a grid already drawn on are shown as they are; apps without a screenshot get the logo.
  • Author cards tile the author's most recently updated apps, up to 9 (3x3), with larger tiles for fewer apps and a single large screenshot for one app. The home card tiles the 9 most recently updated apps in the catalogue. Tiles only use real display renders with something lit, filling in from the next app: they skip apps marked broken, screenshots that can't be read, blank or nearly blank screens, and photos (used only when an author has nothing better). An author with no usable screenshots gets the Tronbyt logo. Screenshots showing an error or setup message can't be detected; they'll drop out as Apps that need a better screenshot #823 is worked through.
  • Card file names include a hash of everything on the card, so a changed card gets a new URL and sharing sites fetch it again rather than showing a cached copy. This includes the home card: the deploy copies index.html into the site before the generator runs, and the generator rewrites that copy to point at the current home card. The source index.html keeps a placeholder name and is never modified, including by local builds into app-viewer/.
  • Text is drawn from the bundled font file (opentype.js), so cards look the same wherever they're built. The font is under the SIL Open Font License, included alongside it.
  • A screenshot that can't be read falls back to the logo, so one bad file can't fail a deploy.

Previously og:image pointed at the app's 64x32 screenshot, which is too small for sharing sites to use (most want at least 200-300px) and often an animated WebP.

Search

  • Every page has a canonical URL and full Open Graph / Twitter tags; the home page and author pages now have them too.
  • App pages include SoftwareApplication structured data.
  • App pages have the app's name, summary, description, author and tags written into the HTML, and author pages list links to their apps, for search engines and sharing sites that don't run JavaScript. The page script replaces this with the full page as before, so nothing changes for visitors.
  • A sitemap.xml lists every app and author page. As the site lives at /apps, it can't have a robots.txt; the sitemap can be submitted in Google Search Console by someone who controls the tronbyt organisation (see also Suggestion: serve the App Viewer at apps.tronbyt.com #835).

Build

No workflow change is required: the generator writes the cards and sitemap into the site, and the existing npm ci installs sharp and opentype.js. A full build of the current catalogue draws 1,706 cards (1,106 app, 599 author and the home card) in about 50s locally and adds about 59MB to the site. --no-cards skips them for quicker local builds.

--reuse-cards <folder> copies any card whose hashed file name is already in a folder of previously published cards instead of drawing it again. Rebuilding with the previous build's cards took 1s (every card reused) with identical output. Card names hash only screenshot contents, not file paths, so they don't depend on where the apps were checked out. A separate PR on main passes the last deployment's cards to the build, so a typical deploy only draws the cards that changed. Either can merge first: without the option the generator draws everything, and older generators ignore it.

Related

The cards made it easy to see which apps have no screenshot or a poor one; those are listed in #823.

Testing

  • npm test (28 tests): escaping of all generated tags, structured data and pre-rendered content, card file names (app and author), text wrapping and sizing, screenshot scaling, tile grids, tile selection and which screenshots can be tiled, rewriting the home page's card tags, and the sitemap
  • Full Pages build with the deploy workflow's script and the generated-site reference check
  • All app pages: valid structured data, and every card they refer to exists
  • A rebuild with --reuse-cards produces byte-identical cards
  • Checked in Chrome that app and author pages look and behave as before

🤖 Generated with Claude Code

Generate a 1200x630 share card for every app (its screenshot as an LED dot
matrix, with its name, summary and author), plus a card for the home and
author pages. Add canonical, Open Graph and Twitter tags to every page,
structured data and pre-rendered details to app pages, and a sitemap.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@saltedlolly
saltedlolly requested a review from tavdog as a code owner October 13, 2026 19:36
@tavdog

tavdog commented Oct 13, 2026

Copy link
Copy Markdown
Member

@saltedlolly merge conflicts !

saltedlolly and others added 2 commits October 14, 2026 01:01
…e/app-viewer-social-cards

# Conflicts:
#	app-viewer/generate-apps-json.js
#	app-viewer/generate-apps-json.test.js
@saltedlolly

Copy link
Copy Markdown
Collaborator Author

@tavdog Fixed. 🙂

saltedlolly and others added 5 commits October 14, 2026 12:33
…unchanged cards

- author cards tile the author's most recently updated apps (up to 9),
  with larger tiles for fewer apps; the home card tiles the most recently
  updated apps across the catalogue
- tiles skip apps marked broken and screenshots that can't be read
- author cards have their own hashed file names
- --reuse-cards copies cards whose hashed file name is already in a
  folder of previously published cards instead of drawing them again

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Tiles only use real display renders with something lit; photos are used
only when an author has nothing better, and the logo when they have
nothing at all.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The deployed copy of index.html is rewritten to point at it, so sharing
sites fetch the new card when the recently updated apps change. The
source index.html is left alone. Tiled card names now hash only the
screenshots' bytes, not their paths.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@tavdog
tavdog merged commit 92f6aee into tronbyt:app-viewer-source Oct 14, 2026
2 checks passed
@saltedlolly
saltedlolly deleted the feature/app-viewer-social-cards branch October 14, 2026 20:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants