Landing Pages — Hub Package Pages
landing-pages specs/landing-pages/packages.kmd
Estrutura, meta tags Open Graph + Twitter Card, e composição da OG image para páginas de pacote individual no Koder Hub (`hub.koder.dev/apps/{slug}`, `/skills/{slug}`, `/bundles/{slug}`). Garante que sharing via WhatsApp/Facebook/Twitter/etc. mostre ícone + nome + descrição do pacote, não thumbnail genérico.
Quando esta spec se aplica
Todos os triggers
- Criar ou editar página de pacote no Hub (rotas /apps/{slug}, /skills/{slug}, /bundles/{slug})
- Configurar OG image dinâmico ou pré-gerado para pacote no Hub
- Auditar sharing de pacote do Hub via /k-housekeep FASE 2.5
Corpo da especificação
Spec — Hub Package Pages (Open Graph + Social Sharing)
Status: Normative
Applies to: Every package page rendered by the Koder Hub web client at
https://hub.koder.dev/apps/{slug} (and equivalent under future kpkg.type
paths: /skills/{slug}, /bundles/{slug}).
Origin: Bug observed on 2026-04-29 — sharing a Koder Hub package page
via WhatsApp showed the generic Store thumbnail instead of the package's own
icon, name and description, because the SPA serves a static OG-tagged
index.html for every route.
1. Requirement
Every Hub package page MUST be discoverable to social-media scrapers — WhatsApp, Facebook, Twitter/X, LinkedIn, Telegram, Slack, iMessage, Discord — with package-specific Open Graph metadata that yields a rich preview containing:
- The package's icon (the same SVG/PNG master used by the package itself, scaled to OG dimensions).
- The package's name (
namefield in the package'skpkg.toml/ Hub catalog entry). - The package's brief description (
descriptionfield, ≤200 chars).
Static SPA-served OG tags are insufficient and violate this spec.
2. Implementation Contract
The Hub backend (products/dev/hub/depot/, currently products/dev/store/depot/)
MUST handle package page URLs as follows:
2.1 Routing
The web server intercepts GET requests to /apps/{slug}, /skills/{slug},
/bundles/{slug}. For these routes:
- If the request comes from a scraper user-agent (regex covering
facebookexternalhit,whatsapp,twitterbot,linkedinbot,slackbot,telegrambot,discordbot,applebot,redditbot,pinterest,skypeuripreview), or - If the query string contains
?og=1(manual override for testing), or - Always (preferred — avoids fragile UA sniffing and benefits humans whose browsers prefetch links),
the server returns a server-rendered HTML shell that contains the complete OG/Twitter Card meta block for the specific package, followed by the SPA hydration script.
The hydrated SPA then takes over for interactive use as before. Result: humans see the same SPA UX, scrapers see correct meta.
2.2 Required meta tags per package page
<!-- Open Graph -->
<meta property="og:type" content="website">
<meta property="og:site_name" content="Koder Hub">
<meta property="og:url" content="https://hub.koder.dev/apps/{slug}">
<meta property="og:title" content="{name} — Koder Hub">
<meta property="og:description" content="{description}">
<meta property="og:image" content="https://hub.koder.dev/apps/{slug}/og-image.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta property="og:image:alt" content="{name} — {short_tagline}">
<!-- Twitter / X -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="{name} — Koder Hub">
<meta name="twitter:description" content="{description}">
<meta name="twitter:image" content="https://hub.koder.dev/apps/{slug}/og-image.png">
<!-- Canonical + page <title>/<meta name="description"> as usual -->
<title>{name} — Koder Hub</title>
<meta name="description" content="{description}">
<link rel="canonical" href="https://hub.koder.dev/apps/{slug}">
2.3 OG image generation
Each package page exposes /apps/{slug}/og-image.png (and equivalent for
skills, bundles). The image is dynamically composed by the Hub
backend with the following layout (1200×630):
- Left third (400×630): the package's icon, centered, with subtle drop shadow and the Hub's accent gradient as background. Icon is the master SVG rasterized to ~360×360 (transparent background preserved).
- Right two-thirds (800×630): the package's
name(large, bold, brand font),description(medium, two lines max with ellipsis), and the Koder Hub wordmark + URL in the bottom-right corner.
The composer reads from the catalog entry (no need to fetch the kpkg artifact). Cache the rendered PNG on first request, invalidate on package version bump.
Reference implementation lives in products/dev/hub/depot/handlers/og_image.go
(to be created; see ticket).
2.4 Fallback
If the catalog entry is missing icon, name, or description (data integrity
failure), serve the generic Hub OG image (hub.koder.dev/og-image.png)
with og:title="{slug} — Koder Hub" and a placeholder description, AND
emit a backend warning to the audit log so the gap can be fixed.
3. Validation
- Manual:
curl -sA "WhatsApp/2.0" https://hub.koder.dev/apps/koder-talk | grep -E 'og:|twitter:'returns the package-specific block. - Automated: a regression test (per
policies/regression-tests.kmd) hits the endpoint with each of the listed scraper user-agents AND with a regular browser UA, asserting that all required meta tags are present and that the image URL resolves to a non-empty PNG of the correct dimensions. - The
/k-housekeepaudit MUST flag any package in the Hub catalog whose page does not return correct OG meta when probed.
4. Coverage of Existing Pages
This spec applies retroactively. When the Hub backend gains the renderer (see ticket), every existing package in the registry is automatically covered without per-package work — the renderer reads from catalog data.
5. Non-Goals
- Marketing landing pages (
<product>.koder.dev/about, etc.) — covered bylanding-pages/products.kmd. This spec is for the catalog pages on the Hub itself, not for product landing pages. - Per-package custom OG art. The composer renders a uniform layout for every package; allowing custom OG images is a future concern and would open the door to inconsistent shareability.
6. Related
landing-pages/products.kmd— OG conventions for product landing pages (1200×630 image, Twitter Card summary_large_image, etc.)landing-pages/catalog.kmd— top-level catalog page (hub.koder.dev) metadatahub-RFC-006-unification-and-rename.md— Hub naming, supersedes "Store" references in any future spec text- Bug origin: shared a package page via WhatsApp on 2026-04-29; preview showed generic Koder Hub thumbnail instead of package-specific.
Referências
specs/landing-pages/products.kmdspecs/landing-pages/areas.kmdspecs/icons/products.kmd