Skip to content

docs(site): add the Deco Blocks docs site (Home, Docs, Under the hood, Roadmap) - #585

Draft
tlgimenes wants to merge 26 commits into
mainfrom
docs/blocks-site
Draft

tlgimenes wants to merge 26 commits into
mainfrom
docs/blocks-site

Conversation

@tlgimenes

@tlgimenes tlgimenes commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

What this is

The source of the Deco Blocks documentation site, under site/, plus a workflow that builds it and (after merge) publishes it to GitHub Pages.

The site is one self-contained HTML page with four hash-routed parts:

  • Home: what Deco Blocks is and how publishing works, with an interactive outage example.
  • Docs: the proposed API for the next major: quickstart, content model, schema, routing, preview, Studio compatibility, the Next.js and TanStack guides, and the API reference.
  • Under the hood: how the runtime resolves, routes and loads content, with a step-by-step walkthrough widget.
  • Roadmap: the to-do list that gets the next major to a release: ten release blockers, Studio support, work items (API, CLI, Studio, docs), migration plans for storefront-tanstack, blog-tanstack and a FastStore storefront, and a filterable table of 111 features with status and effort.

It also has ⌘K search, a light/dark theme toggle and a print layout. The only external requests are the Fontshare and Google Fonts stylesheets and the font files they load. No analytics and no third-party scripts.

Layout

  • site/build.py assembles site/dist/index.html (gitignored) from site/src/*. Python 3.9+, standard library only.
  • site/gen_roadmap.py renders the Roadmap from site/data/roadmap.json and checks it: ids, cross-links, counts, and links into the docs.
  • site/data/roadmap.json holds exactly what the Roadmap shows, nothing more.
  • site/src/ has the page shell, Home, the Docs/Under-the-hood content (with the MIT-licensed Prism bundle and its notice), CSS, JS and brand SVGs.
  • .github/workflows/pages.yml builds on PRs that touch site/ and deploys to Pages on pushes to main of this repository (and manual runs on main).

See site/README.md for the data format and the public-content policy.

Preview

Locally:

python3 site/build.py && open site/dist/index.html   # xdg-open on Linux

From this PR: open the "Docs site" workflow run under Checks, download the docs-site artifact, unzip it and open index.html.

Left out of the public build on purpose

  • The underlying analysis. The Roadmap comes from a code-level review of three sites. Only the conclusions are committed: feature statuses, effort, summaries and plans. The per-file evidence and working notes are not.
  • One of the three sites is private. It appears only as "the FastStore storefront", with platform-level facts (FastStore v4, Next.js Pages Router, VTEX Headless CMS). Details that could identify its codebase or owner were removed or generalized.
  • Issues in code that is deployed or released today are not described on the site. Where the next major needs a design change because of them, the Roadmap states only the design requirement for the unreleased API.
  • No local paths, personal data, internal URLs or customer names.

Before going public

  • Enable GitHub Pages with source GitHub Actions (Settings › Pages). Until then the deploy job on main fails; nothing else depends on it.
  • Review the anonymized FastStore storefront content (Roadmap › Site migrations › FastStore storefront, and the FastStore rows in the feature table).
  • Decide whether to announce the unreleased next major publicly. The Docs and Roadmap describe an API that isn't released yet.
  • Apply the docs corrections listed under Roadmap › Work items › Docs (the items that correct statements that are wrong today come first).
  • Optional: set up a custom domain for the Pages site.
  • Squash-merge with a docs(site): … title, so the change doesn't trigger a package release.

🤖 Generated with Claude Code

https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig


Summary by cubic

Adds the Deco Blocks docs site source under site/ and a workflow that builds it on every PR touching site/ (downloadable artifact) and deploys it to GitHub Pages from main. The site documents both the released framework (v7) and the proposed next-major API — the composition-based, Git-backed content model and the run resolve option — with technical-writer passes that define every term. It's a standalone Bun package: TanStack Start prerenders each page to static HTML, content lives in MDX, Shiki highlights code at build time, and Pagefind backs the ⌘K search.

Site

  • Four sections — Home, Docs, Under the hood, Roadmap — with light/dark themes and a print layout. v7 is the default version with its own home at / and 49 pages on the released framework and its apps; the next major lives under /next/, and a version select labeled "v7 (current)" / "next" on both homes switches between them. The Roadmap tab shows only while the next-major version is selected.
  • Blocks teaches function composition stored as data, with a step-by-step resolution walkthrough; JSON examples sit next to the TypeScript calls they mean.
  • "Section" is no longer a framework concept: a block that returns JSX is just a block, and only the page's sections field and Studio's legacy names keep the word.
  • The next-major docs tell one content story: content is JSON files in .deco/blocks that developers, agents and Studio edit; deco content turns them into a module createCMS reads, publishing is a commit, and the hosted CMS makes published commits live without a deploy. Custom loaders stay in the API but leave the narrative (one pointer and the Loader reference remain); the KV setup is gone.
  • The resolve option is run; the SDK reads no files and runs in any JavaScript runtime.
  • page, redirect and telemetry are built-in blocks that createCMS spreads under your block map (always defined, overridable); resolving a saved page returns it ready to render (seo and every block in sections resolved), and UNKNOWN_BLOCK only means a name is in neither the map nor the saved entries. remoteLoader polls for a release every minute (interval option, DECO_CONTENT_INTERVAL, with jitter), and the Workers guide keeps the bundled snapshot in memory as the fallback.
  • New next-major pages cover the content protocol Studio edits content through (deco content serve, polling), thin instrumented upstream API clients, and telemetry via createCMS({ site, token }), switched off through a Studio edit to the Telemetry entry.
  • CLI deco schema and deco content write .deco/blocks.gen.ts and run from predev/prebuild; deco schema finds blocks.ts(x) in root or src/ (--entry overrides it). Schema compatibility is a CI check (deco schema --check, part of the first release), not a runtime rule.
  • Studio builds its forms from whichever schema the user points it at, usually main's, and saves edits as commits on a draft branch.
  • A newcomer pass added a glossary, one revision rule everywhere, moved rendering before routing, fixed wrong statements, and normalized block types and entries; every code example now uses double quotes and semicolons.
  • The Home hero's "Resolve it" step shows the CMS setup and resolve call in one file; its stability section says changes go live in seconds; its points row is three columns ("Safe with the live code" is gone), and the "Swap any piece" card becomes "Publish by committing".
  • The v7 docs add a "Going live after a migration" page (cutover checklist, parity checks with @decocms/parity, migrator-written CI workflows, withABTesting traffic shift) and extend the migration, VTEX, routing, variants, content, loaders, TanStack, troubleshooting, observability, SEO and glossary pages with public links. The v7 overview embeds the five Deco Studio training videos (Portuguese), each paired with the English page covering the same ground.
  • The Roadmap renders from site/data/roadmap.json and is validated (ids, cross-links, counts); the analysis behind it and one private site are intentionally excluded.
  • Styling is Tailwind utilities driven by a themed token set, with a full-width docs shell that keeps a 720px article column; the build fails if any page's HTML exceeds 48 KB gzipped.

Rollout

  • Enable Pages with "GitHub Actions" as its source; until then the deploy job on main fails, with nothing else depending on it.
  • Squash-merge with a docs(site): title so no package release is triggered.
  • Review the anonymized FastStore content and decide whether to announce the unreleased API before going public.

Written for commit 27c4583. Summary will update on new commits.

Review in cubic

tlgimenes and others added 26 commits September 30, 2026 09:50
…, Roadmap)

Adds the source of the Deco Blocks documentation site under site/ and a
workflow that builds it on pull requests (downloadable artifact) and, once
GitHub Pages is enabled, deploys it from main.

The site is one self-contained page built with the Python standard library
(python3 site/build.py -> site/dist/index.html). The Roadmap is rendered
from site/data/roadmap.json by site/gen_roadmap.py, which also checks ids,
counts and cross-links.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
Prose, code blocks, tables, callouts and diagrams now share the same
720px column, so their left and right edges line up. This drops the
70ch cap on paragraphs, the wide-screen breakout of code and tables,
and the edge-to-edge code panels on phones. Code lines longer than the
column scroll inside their panel.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
The stability section no longer talks about CMS outages: no outage
switch, no "unreachable" status, and the points now speak to speed and
stability by design. The hosted-CMS section says changes go live in
seconds instead of about five minutes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
Drops the preview badge and notes from the home hero, the home footer,
the docs sidebar, the docs footer and the top of "How it works".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
…re it

createCMS's loader option is optional and defaults to "./.deco", so the
quickstart example drops it. "Loaders and deployment" gains a
"Configuring the loader" subsection: the default, a different root
directory, the hosted Deco CMS token (the site's API key, kept in an
environment variable), and both together.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
The hero's fourth step now shows the whole setup in one file:
createCMS({ blocks: { experiments } }) and the resolve call, instead of
importing a cms module the page never shows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
…xperiments.ts

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
- Flatter, shorter example file names, one name per file everywhere:
  cms.index.ts -> blocks.ts, src/cms/cms.ts -> cms.ts, content/* and
  views/* moved to the root, the framework guides' src/cms/*,
  src/views/*, src/server/* -> src/*. Framework-mandated paths
  (app/.../page.tsx, src/routes/*, .deco/*) stay.
- The guides' base map, product block and block map merge into one
  src/blocks.ts(x) each.
- Options equal to their defaults and no-op lines are dropped
  (runtime = 'nodejs', a bare `enabled;`, needless variables, duplicate
  react imports).
- Correctness fixes found on the way: "get" references renamed to
  resolve, the multivariate map's missing imports, the alias snippet's
  imports, a stray </section>.
- The Experiments result is named `flags` instead of `enabled`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
…nd loaders

- Blocks (#model) now teaches blocks as function composition stored as
  data: the composition in code, the same composition as JSON, saved
  entries as named compositions in a content map, and one page resolving
  step by step ("Resolving a page, step by step").
- Saved entries are no longer described as files in .deco/blocks. A new
  Core concepts section, "Content and loaders" (#content), explains where
  that map comes from: files by default, bundled JSON, the hosted Deco
  CMS or your own store, plus configuring the loader and writing one.
  Loaders and deployment keeps release and deployment behaviour.
- { resolve: false } moves out of the prose into one "Reading without
  running" callout; the Quickstart aside about it is gone.
- Troubleshooting now agrees with the registry rule (the function wins
  on a name clash), so that item leaves the Roadmap's contradictions list.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
Adds a TypeScript "Means" next to the JSON examples where it teaches
something: the quickstart's Experiments entry, HomeHero's variants, a
page holding blocks, ProductPage, two API reference rows and the
walkthrough caption, in the same layout the Blocks page uses.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
… new model

- client.resolve(target, { run: false }) reads without running any
  function; client.list(type, { run: true }) runs each entry. The
  signatures, examples, troubleshooting and the walkthrough follow.
- A cohesion pass over every page brings the rest of the docs in line
  with blocks as function composition and the content map: pages tagged
  with a Content type are read, not resolved; publishing is scoped to
  the hosted CMS vs the next deploy; captions name saved entries rather
  than files; loader wording no longer assumes the filesystem; stale
  links and leftovers fixed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
Six technical writers, a concept-order audit and a task-based newcomer
read the whole site as a developer who knows TypeScript and CS basics
but not Deco. About 75 edits followed, then a cold read and an accuracy
review:

- Deco terms defined at first use, with a short glossary; "section",
  "client", "release", "revision", "isolate" and the meanings of
  "loader" explained once and linked elsewhere.
- One revision rule everywhere, and pointers to the Roadmap where the
  client can't expose the revision yet.
- Rendering now comes before Routing; repetition trimmed ("one client
  per request", "section").
- Wrong statements corrected (page entries vs resolve, fallback while
  the API is down, route conflicts reaching production, satisfies and
  typing, RSC serialization).
- Block types are lowercase/kebab-case, entries capitalized.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
A block that returns JSX is just a block. The glossary entry,
definitions, "section" wording in guides and examples, the home page
block map comment and Roadmap titles now say "block" (or "a block that
returns JSX"). Kept: the page's `sections` field, described as a list
of blocks, and Studio's legacy names, labelled as such.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
…ling

- createCMS({ blocks, content, token? }): content (a generated snapshot
  or any Loader) replaces the loader option; the SDK never touches the
  filesystem and runs in any JavaScript runtime. KV example included.
- CLI: deco schema and deco content (writes .deco/blocks.gen.ts, one
  import per JSON file, hot-reloaded by the framework), both with
  --watch and --root, run from predev/prebuild.
- page and redirect are built-in content types; override them in
  Content or opt out with never.
- remoteLoader checks for a release every minute (interval option,
  DECO_CONTENT_INTERVAL, 1-minute minimum, +/-10s jitter), at idle
  moments, inside waitUntil on Workers; instances are shared through
  globalThis.
- A block is either a function (code) or saved content (JSON).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
…memory

- deco schema finds blocks.ts(x) in the root or src/; --entry overrides
  it. Flags listed once: deco schema [--entry] [--root] [--watch]
  [--check], deco content [--root] [--watch].
- Compatibility is a CI check, not a runtime rule: the claim that the
  Deco API holds back releases whose schema doesn't match is gone.
  "Keep the schema compatible" defines breaking vs non-breaking changes,
  explains backward vs forward compatibility (deploy code first), and
  ships a GitHub Actions workflow running deco schema --check (planned)
  against the base branch's schema.
- Workers guide: the bundled snapshot stays in memory as the fallback;
  large sites can pass a KV Loader as content instead, with the KV key
  seeded before the new Worker serves traffic.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
… line

- Studio builds its forms from whichever schema the user points it at,
  usually main's; the docs no longer say it is meant to read only the
  deployed schema. The Roadmap item becomes an option to follow the
  deployed schema.
- The home page's "Safe with the live code" point is gone (too technical
  for that page); the points row is three columns now.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
site/ is now a standalone Bun package (its own package.json and
bun.lock; the monorepo lockfile is untouched):

- TanStack Start (Vite + React 19), file-based routes, every page
  prerendered to static HTML for GitHub Pages; BASE_PATH sets the base.
- Content in MDX (content/next/*.mdx, content/v7/*.mdx) with
  frontmatter-driven navigation, Shiki highlighting at build time,
  and the docs' components (callouts, flows, terms, the walkthrough).
- Versions: /next/<page> for the next major, a /v7/ stub, and a version
  select in the header. Home at /, Roadmap at /roadmap (React port of
  the old generator, its checks in scripts/check-roadmap.ts).
- Pagefind for the search dialog; the build checks every internal link
  and a size budget.
- Text and code of all 25 doc pages are identical to the previous
  single-page site; the Python build is removed, and the Pages workflow
  builds the new site with Bun.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
- legacy.css and roadmap.css are gone: design tokens live in the
  Tailwind theme (colors via light-dark() variables, fonts, type sizes,
  radii, shadows, easing), components use utilities, and what remains
  is tokens, a base layer, the MDX prose layer and a few scoped
  component rules (CSS 154 KB -> 46 KB of source). Pixel-identical to
  the previous build apart from the layout below.
- The docs shell is full width: sidebar on the left edge, "On this
  page" on the right, the centre column takes the rest; the article
  keeps a reading width (720px, up to 800px from 1920px wide) and the
  whole shell caps at 1920px on very large screens.
- The build fails if a page's HTML exceeds 48 KB gzipped.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
…s, writing pass

- v7 (current): 49 pages documenting the released framework and its
  companion apps (TanStack Start on Workers, Next.js, CLI, Studio and
  the admin protocol, Fast Deploy, caching, observability, upgrading),
  checked against the source. v7 is the default version and has its
  own home at /; the next-major home moves to /next/. The version
  select appears on both homes and switches between them.
- Next major: "Studio and the content protocol" (JSON-RPC: describe,
  schema.get, blocks.list, blocks.apply; polling; GitHub backend and
  `deco content serve`; what degrades), "Upstream API clients" (thin
  instrumented clients, a recipe, caching in the bindings; invoke and
  cachedLoader removed), telemetry with createCMS({ site, token }) and
  a Telemetry entry, and RUM as a post-release follow-up.
- Writing pass across both versions: correctness, cohesion and style
  reviews; examples centred on blocks that render React components
  (ProductCard, PromoBanner, product hero), shorter and e-commerce.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
…h-off via Studio

- Every TS/TSX/JS code example now uses double quotes and semicolons
  (31 blocks; line breaks unchanged), plus inline code in prose and the
  Roadmap.
- Turning telemetry off is a Studio edit to the Telemetry entry,
  committed through Studio's GitHub integration and picked up with the
  next content check; no separate channel.
- deco schema --check is part of the first release.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
The Roadmap is about the next major, so the header and drawer list it
only while the next-major version is selected (next home, /next/ pages
and the Roadmap itself); v7 pages and the v7 home don't show it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
The version select drops "major": the options read "v7 (current)" and
"next". The v7 home's footer link reads "Next version".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
…page

- One story: content is JSON files in .deco/blocks in your repository,
  changed by developers, agents and Studio; deco content turns them into
  a module for createCMS; publishing is committing; the hosted Deco CMS
  makes published commits live without a deploy.
- Custom loaders stay in the API but leave the narrative: the
  "Where content comes from" table, the "Write your own loader"
  walkthrough and the KV setup are gone; one pointer remains, plus the
  Loader reference.
- "Your content in Git" (/next/content) opens with the files you
  already have, then how your app reads them, then publishing;
  resolve appears only where it's needed.
- Studio's role is stated consistently: saves are commits on a draft
  branch, publishing brings them to production.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
Content brought into the v7 docs only, each piece checked against the
source and corrected where it differed:

- New "Going live after a migration" page: cutover checklist, parity
  checks with @decocms/parity, the CI workflows the migrator writes,
  and shifting traffic gradually with withABTesting.
- Additions to the Fresh migration, VTEX (sales channel, sign-in,
  autocomplete), routing (your own routes), variants (whole-page
  variants, scheduled campaigns), content (saved vs local sections,
  redirects incl. CSV import), loaders, TanStack (React Compiler,
  chunking), troubleshooting, observability, SEO (robots.txt),
  glossary, and public links to Cloudflare, VTEX, Resend, React,
  TanStack, Next.js, npm and the repo's examples and skills.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
…mmitting

- v7 overview: the five Deco Studio training videos (Portuguese), each
  paired with the English page that covers the same ground.
- Next home: the "Swap any piece" card becomes "Publish by committing"
  (Git-based content, live in seconds with the hosted Deco CMS), and
  the "Content & loaders" labels become "Content".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
- page, redirect and telemetry are built-in blocks: createCMS spreads
  them under your block map, so they're always defined and your map
  can override them. Resolving a saved page returns it ready to render
  (seo and every block in sections resolved); UNKNOWN_BLOCK only means
  a name is in neither the block map nor the saved entries. Reading
  with { run: false } and resolving blocks one by one stays as an
  optional streaming technique.
- The content module: the SDK makes no filesystem calls so it runs in
  any JavaScript environment; content arrives as JSON imports that
  `deco content` generates.
- The deco publish note moves from the Content page to Design
  decisions (Under the hood).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
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.

1 participant