Next framework readiness
Release blockers and readiness evidence for the proposed next Blocks framework, preserved from PR #585.
This page preserves the release-readiness assessment from PR #585 at commit befb394. It is a design snapshot, not a live release tracker. Review the current pull request before making a migration decision.
Release readiness
None of the 111 features those sites use is done yet: 11 are still to build, 66 are to finish, 28 are left to site code, and 6 go away with the migration.
Release blockers
Let the site editor talk to a next-major site
At the source revision: The site editor reads the schema and content from the running site (/live/_meta, /.decofile) and calls it for previews, /deco/invoke and the secrets encrypt action. A next-major site serves none of these.
Intended change: The site editor talks to stored content through the content protocol instead, which needs only the committed schema and .deco/blocks: the site editor's GitHub backend in production, deco serve on a developer's machine. Features that need the site's code degrade in this version (see What works without your code).
Make the CLI write a schema the site editor can read
At the source revision: The CLI writes .deco/schema.gen.json with top-level definitions; the site editor reads .deco/meta.gen.json in LiveMeta shape (btoa keys, schema.root). There are no apps or actions groups, no per-type variant definitions, and the widget vocabulary is undocumented, so 22 image pickers would become text inputs and HTML fields plain strings.
Intended change: Emit the site editor's exact format as .deco/schema.gen.json, one multivariate definition per field type a variant can fill, write static option lists into the schema, publish the JSDoc/@format table, and keep widget-alias detection and return-type loader unions.
Give blocks the page URL and route params
At the source revision: On SPA navigation getRequest() returns the /_serverFn URL, Next's headers() has no URL, app packages' loaders have no standard way to receive the URL or match.params, and apps-vtex's RequestContext is never populated.
Intended change: Add one request scope (url, params, request, client, response headers) that the templates' openPage populates and that block functions and site code can read, passing what a client needs as arguments.
Make draft preview work inside the site editor's iframe
At the source revision: The SameSite=Lax cookie is rejected cross-site, the TanStack guide never sets it, and ?__draft=off is ignored. There's no no-store rule, and no StudioBridge or data-manifest-key, so click-to-select is lost.
Intended change: Give the templates withDeco()/decoProxy() recipes, which set the cookie as Secure; SameSite=None; Partitioned, treat ?__draft=off as exit and mark drafts private/no-store. Add <StudioBridge/>, and have the templates wrap each rendered block in the site editor's section[data-manifest-key] marker.
Define the non-CMS SDK surface
At the source revision: apps-* and the ClickHouse telemetry depend on sdk/requestContext, instrumentedFetch, fetchCache and cachedLoader, and sites' widgets on sdk/useDevice and the Image and JsonLd hooks. These docs only list 'loaders, client, resolution, router'.
Intended change: The framework doesn't fetch data: the apps become thin, instrumented API clients over the framework's instrumented fetch, the core drops /deco/invoke and cachedLoader, and caching moves to template recipes. Ship @decocms/blocks/image.
Add a revision handle, an edge cache recipe and an ISR recipe
At the source revision: Clients expose no revision and there's no forRevision. Degraded pages get cached. The planned check for a new release runs once a minute, at an idle moment (inside ctx.waitUntil on Workers), so propagation depends on the check interval and manifest cache lifetime; a cold isolate serves the content module it was deployed with until its first check.
Intended change: Add a revision handle, a way to read and pin the revision a client serves (client.revision(), cms.forRevision(), onUpdate), and markDegraded(). Add an edge cache recipe for Workers templates, withEdgeCache(), for caching rendered pages at the edge, and an ISR (Incremental Static Regeneration: re-rendering cached pages in the background) recipe for Next.js.
Stop resolving everything eagerly
At the source revision: The one registry rule resolves inputs bottom-up. Lazy defers nothing (43 wrappers on the storefront), hidden variants still run their loaders, and Resolved<T> can't be expressed.
Intended change: Add the built-in lazy block, so multivariate runs only the chosen variant. The alias bridge unwraps the legacy Lazy/SingleDeferred/Deferred block wrappers: the wrapped block renders normally, with no client-side deferral.
Make the next major load and resolve legacy content
At the source revision: Filename decoding is unspecified, and the alias bridge covers only pages, matchers and multivariate, while the site editor writes Lazy, SeoV2, site/apps/site.ts, redirect, secret and the multi matcher. UNKNOWN_BLOCK now fails the parent block.
Intended change: Use the protocol's one filename rule (decode exactly once), widen the alias bridge, ship deco content (with deco schema reporting collisions), and have the CLI emit a runtime alias table.
Make routing accept the content sites already store
At the source revision: There's no splat, so /* PLPs never match. matchRoute throws per request on an ambiguity a single site editor commit can introduce. Page.seo is required but content stores null, and with no 404 gate unknown URLs return soft 200s.
Intended change: Add a trailing splat and make matchRoute non-throwing, with a deterministic tie-break. A hosted publish isn't validated: the tie-break keeps the site up and deco check catches ambiguous routes in CI. Make seo optional and add a critical-block notFound/redirect sentinel.
Define a model for apps, config and secrets
At the source revision: App loaders get no config, there's no apps manifest group, website/loaders/secret.ts can't decrypt, and the site editor encrypts Secret fields through an action the site serves.
Intended change: Define the client contract (a factory that takes its config from site code), and vendored loaders keep their old type names as aliases. No apps group in this version. Ship a built-in secret block: content holds only ciphertext, encrypted with a public key committed in .deco/ and decrypted on the server, and the site editor gets a write-only Secret field.
Site Editor and delivery services
The proposed editor transition depends on these control-plane changes. Their presence in a design document does not mean they have shipped.
Build the site editor's GitHub content backend
A ContentStorage inside the site editor's API that reads and writes .deco/blocks through the GitHub API, in the folder the project's "app root" setting names (a monorepo subfolder included). Every write is a commit, and all files of one blocks.apply go in one tree and one commit, with file contents inlined in the tree request. Clients poll on window focus and about every 30 seconds with one batched conditional request. Publishing, the draft pointer and ?__draft= links stay site editor routes outside the protocol. Drop the requirement for a deployed preview URL, so a project with no deployment can still be edited.Reuse the existing Fast Preview Git-provider and autosave machinery behind this adapter. Bind the editor endpoint to an automatically managed draft, normalize set precedence, preserve conditional guards and durable request receipts, and coordinate saves with synchronization and publication.Use the Studio implementation handoff for module ownership, durable state and APIs, operation sequencing, proposed defaults and acceptance scenarios; completion includes the documented failure and concurrency cases.
Move the site editor onto the protocol client
Projects with a committed .deco/schema.gen.json or .deco/meta.gen.json under their folder use the protocol client, so v7 projects that commit meta.gen.json move to it automatically, with no per-project switch. Fresh and Deno sites, whose schema exists only at runtime, stay on the legacy path. Features that need the site's code degrade: block previews become name cards or open the real page (the local dev app, or the deployed site with a ?__draft= link), dynamic pickers fall back to the schema's options, else free text, and Run and installing apps from the store are hidden. Secret fields keep working: the site editor encrypts them itself with the site's committed public key (see Encrypt Secret fields in the site editor and manage keys in Deco CMS). Autosave stays last-writer-wins. Add the connect flow for a local deco serve endpoint, with a one-line explainer before Chrome's local-network prompt.
Encrypt Secret fields in the site editor and manage keys in Deco CMS
The site editor shows a Secret field as a write-only password input: it encrypts the value in the browser with the public key committed in .deco/ and saves only the ciphertext as a secret block, never showing a saved value again. It needs no action from the site, so it works on protocol projects and with deco serve. The hosted Deco CMS adds key management: creating the key pair, storing the private key for the site's deployments and rotating it (re-encrypting every saved secret in one commit). Without the hosted Deco CMS, developers create the key pair by hand.
Add a play workspace for local editing
Let anyone edit the files on their machine in the site editor without a Deco account: a connect link from deco serve opens a play workspace in the site editor that talks only to that local server, with no site, team or sign-in. Hosted features (the site editor's GitHub backend, releases, drafts on your site, hosted asset storage and telemetry) stay with a connected site.
Store uploads in Deco's asset storage
With the hosted Deco CMS, the site editor's GitHub backend sends uploads to Deco's asset storage (backed by Amazon S3) instead of the repository, and saves each file's CDN address in the field, so images are served from a CDN and the repository doesn't grow. A field can hold either a CDN address or a path to a file in the repository, so sites that started with local uploads keep working.
Fix the Add Section gate
The site editor shows Add Section only when a preview server is configured. Gate it on having the schema and the blocks instead; otherwise adding blocks to a page disappears on protocol projects.
Read manifest groups for pages, redirects, content and apps
Support several page types and a content collection screen. Read flat redirect entries alongside the nested legacy shape, mapping temporary to status 307 and keeping discardQueryParameters.
Use manifest lookup instead of path heuristics
Replace the file-extension module-or-entry check and the site editor's legacy "/sections/" path heuristics, and refuse to save an entry whose name is a manifest key.
Build the Deco API release service
Separate GitHub ingestion and publication from a stable storage/CDN data plane: production reads, including misses and cold reads, never call GitHub. Materialize immutable, canonically hashed JSON snapshots before promoting small per-environment channel manifests. Keep authorization in a minimal independently deployed gateway when needed. Reconcile missed or out-of-order webhooks in the control plane, bound materialization memory and retain last-good releases. Publishing doesn't validate content: the runtime's route tie-break and CI's deco check are the safety net.Use a durable per-channel promotion coordinator and monotonic generations. Fast rollback selects a retained compatible snapshot without builds, deploys or GitHub reads, records an audit event and pauses automatic promotion until explicitly resumed. Prevent stale jobs from undoing it, define asset retention and garbage collection, notify rendered-page caches, and document actual propagation delays. Site token lifecycle and CI code/content compatibility remain required.Use the Studio implementation handoff for module ownership, durable state and APIs, operation sequencing, proposed defaults and acceptance scenarios; completion includes the documented failure and concurrency cases.Production assets stay self-contained; draft previews use versioned overlays over local production, without a base-revision fetch. See Draft overlays.
Keep editor drafts current automatically
Manage internal draft branches automatically; editors never create branches or rebase. Extend GitHub push intake and existing Studio event delivery: synchronize open drafts in the background, inactive drafts on reopen, and reconcile before saves and publishing. Coalesce updates and retain a slow reconciliation fallback. Use file-level draft wins: compare the draft with its incorporated production tree by blob identity; untouched files adopt production, edited or deleted files keep the entire draft version. Do not merge JSON properties or download conflict bodies. Reuse existing blobs for all file sizes.Serialize operations per draft, retry external head races without unconditional force updates, retain append-only history and recoverable incorporated-base metadata, and preserve persistence guards. Bound tree-metadata work and concurrency; schema checks remain in CI. Expose synchronization status and audited resolution summaries without overwriting unsaved form state. Publishing produces only the saved-content diff against current production.Use the Studio implementation handoff for module ownership, durable state and APIs, operation sequencing, proposed defaults and acceptance scenarios; completion includes the documented failure and concurrency cases.
Serve draft overlays over local production
Materialize saved draft changes as private immutable overlay manifests referencing changed-block blobs, with explicit deletion tombstones. Each manifest represents the cumulative draft overrides, not an incremental replay chain. The preview client captures whatever production snapshot it already has; no baseRevision or matching-production download. Fetch only missing changed blobs, share unchanged objects, and key composed views by local production revision plus overlay version. Old pointers fix old overrides but intentionally inherit current local content on later requests.Use saved write bodies and cached tree/blob identities; read only changed files during recovery, and handle truncated Git comparisons. Preserve exact overlay authorization, bounded memory, preview readiness and garbage collection of referenced blobs. Missing overlays fail the draft client. Production releases remain complete immutable snapshots.Use the Studio implementation handoff for module ownership, sequencing and acceptance scenarios.
Align the preview protocol
Keep ?__draft=off as the one documented way to end a draft preview, and force variants in the draft content. On protocol projects the canvas opens the real page with the draft pointer, and gallery thumbnails and in-place renders are replaced by name cards, since the protocol never runs site code.
Drop legacy names from the Blog tab and experiments
Detect the blog from the manifest, and key experiments on their explicit experiment id instead of the random matcher's entry name.
Label matchers from their schema and keep enum titles
Label short-key matchers from their schema, dedupe aliased matchers, and keep oneOf const titles.
Add a per-page-type catalog and a page settings form
Use the anyOf on a page type's sections list as the site editor's catalog, and render the remaining page props as a form.
Bring the site editor's SEO merge to parity with the kit
Run the site editor's mergeSeo (seo-editor.tsx) against the kit's mergeSiteSeo test suite. The site-wide template applies to titles only: descriptions are used as written, so descriptionTemplate never wraps them.
Add a content-live signal
Every response carries the served revision in x-deco-revision, and the CMS reports each revision it swaps in to the Deco API with the site token. The site editor polls the API and shows a publish as pending until a report for its revision arrives, then live.
Build the telemetry collector
An endpoint that accepts aggregated metrics and sampled error logs, authenticated by site ID and site token, for sites that set telemetry: { site, token }. Separately, it receives page views in the One Dollar Stats format from analytics blocks left on the default collector, telling sites apart by hostname and counting only sites connected to the hosted Deco CMS. Switching a site's telemetry off needs no special channel: it's a commit to the site's Telemetry saved block, from the site editor or by hand, like any content edit.
Update the injected agent rules
Replace the two wrong rules for next-major sites. Content edits go only in .deco/blocks/<encodeURIComponent(key)>.json. .deco/index.ts and .deco/blocks are the site's; two files are generated and never edited by hand: .deco/schema.gen.json, which deco schema rewrites after any change to a block's types, and .deco/blocks.gen.ts, which deco content writes and git ignores. A new type needs a block-map entry. remoteLoader picks up prepared releases on its next background check, not on save, and with DECO_SITE and DECO_SITE_TOKEN set the dev server serves the API release, not local edits.
Historical handoff note for the befb394 snapshot: The development-source instruction above conflicts with the accompanying hosted CMS design, which makes local files win for ordinary development requests even when site credentials are set; an explicit draft link loads the remote draft. Preserve this assessment as a historical snapshot, but follow that development contract when updating agent rules. Release checks and production delivery remain separate from local editing.
Assessment data
The complete source assessment retains all 111 feature statuses, site migration steps and work-item relationships. The engineering handoff records the proposed acceptance scenarios.
Import reconciliations
The source snapshot describes the next API in the present tense even though its quickstart marks it unreleased. Every next-framework page here is labeled preview. The unavailable @decocms/blocks@^8.1 installation and missing migration skill were removed from runnable instructions. Built-in counts were reconciled to the nine functions listed in the reference.