Download Button (landings)

landing-pages specs/landing-pages/download-button.kmd

Botão Download em landings de produto Koder: sempre via `<koder-download-button slug="…">` do `engines/sdk/koder_web_kit` v0.2+. URL canônica do CTA: `hub.koder.dev/apps/<slug>`. Nunca hand-roll link direto pra Flow release, Store home ou hosted-file download.

When this spec applies

Primary triggers

All triggers

Specification body

Spec — Download button on Koder landings

Applicability

Every Koder product / module landing page that offers the user a way to install / get / try / use the product. Institutional landings (about / company / brand) don't have a Download button and are out of scope.

Required behaviour

  1. One canonical destination: the product's page on the Koder Hub. The Download button always points to https://hub.koder.dev/apps/<slug>. No direct link to a Flow release artefact, no link to the Store home page, no APK / DMG / MSI hosted on the landing's own domain.

  2. Slug availability check is mandatory. Before a landing ships a Download button pointing to the Store, the slug must already exist:

    curl -sf https://hub.koder.dev/api/v1/apps/<slug>   # 200 = OK
    

    A 404 is a blocking error — the button cannot be deployed in its normal form while the Store listing is missing.

  3. Fallback is a tracked state, never silent. When the slug is not yet registered in the Store, the button renders as a "Coming soon" state. Every such state must have a tracking ticket in the module's backlog recording exactly what is blocking the Store listing (missing CI, missing keystore, slug not registered, product not MVP-ready). Landings without a corresponding ticket are non-compliant.

  4. The destination opens in the same tab. No target="_blank". The user came from the landing to download; they stay on the Store to finish the flow.

  5. Only one Download button per landing. If the landing links to multiple artefacts (e.g., "Get for Android" / "Get for iOS" / "Download source"), they are not Download buttons — they are platform-specific links, and the primary Download button still exists pointing at the Store. Source-code links go to a secondary "Source" button, never the Download button.

SDK-provided widget

Flutter (engines/sdk/koder_kit): ticket KIT-7 to ship a KoderDownloadButton(slug:) widget in v0.6.0.

Web (engines/sdk/koder_web_kit v0.2.0): <koder-download-button slug="…">.

<!-- Simplest form — resolves https://hub.koder.dev/apps/<slug> -->
<koder-download-button slug="koder-dek"></koder-download-button>

<!-- With explicit ticket URL for fallback state -->
<koder-download-button
    slug="koder-eye"
    ticket="https://flow.koder.dev/Koder/koder/src/branch/master/dev/eye/backlog/pending/008-landing-page.md"
    coming-soon-label="Coming soon">
</koder-download-button>

The element:

  1. At render time, calls GET /api/v1/apps/<slug> (once, cached per page load).
  2. If 200 → renders <a href="https://hub.koder.dev/apps/<slug>">Download</a>.
  3. If 404 → renders a disabled button labelled "Coming soon" (localised per <html lang>) plus, when ticket="…" is set, a small info icon linking to the ticket.
  4. Emits a koder:download-ready or koder:download-blocked CustomEvent so analytics / deploy gates can react.

Required label

  • Default English: Download
  • Default Portuguese (<html lang="pt"> or lang="pt-BR"): Baixar
  • Default Spanish: Descargar
  • Overridable via label="…" attribute.

Never use: "Get", "Install", "Try", "Buy" as the button label — those are the Store's concern, not the landing's.

Deterministic audit checks

/k-housekeep (ticket planned):

  1. For every landing <module>/site/index.html (and sites/*/index.html):
    • Extract the Download button: <koder-download-button slug=…> or any <a> / <button> whose visible text is Download / Baixar / Descargar.
    • If it is not the SDK element: ❌ error — migrate to <koder-download-button>.
    • If it is the SDK element: extract slug; curl the Store API; report 200 vs 404.
  2. For every 404 slug:
    • Check the module's backlog/pending/ for an open "Coming soon" tracking ticket. If none: ❌ error. If present: ⚠ warning ("tracked").
  3. Report all hand-rolled alternatives: direct Flow release links, arbitrary hosted files, Store home-page links. All are ❌ errors.

Canonical reference

engines/sdk/koder_web_kit/koder-web-kit.js<koder-download-button> impl. engines/sdk/koder_kit/lib/src/download_button.dart — Flutter impl (planned v0.6).

  • products.kmd — parent landing spec
  • ../themes/light-dark.kmd
  • ../../policies/sdk-first.kmd — "Download links → engines/sdk/koder_web_kit; never hand-roll"
  • ../errors/user-facing-messages.kmd — used for Store API 5xx failure surface

References