From 014527bd2079b39586e0557c87051e2bce90fdad Mon Sep 17 00:00:00 2001 From: gimenes Date: Tue, 10 Nov 2026 13:25:58 -0300 Subject: [PATCH 1/3] feat(nextjs,tanstack): let Studio's HTML swap re-render the page through its router After a save, Studio's HTML swap replaced the whole document. React kept the old nodes and the new HTML's scripts never ran, so every client component stopped at its server markup: a footer revealed on scroll stayed hidden, a carousel stopped. The protocol now names a window hook, STUDIO_PAGE_REFRESH, that a binding sets so Studio shows a save through the page's router instead: - @decocms/nextjs: StudioBridge renders StudioRefresh ("use client"), which calls router.refresh() for the page's URL, or router.replace() for a moved draft pointer, and resolves when the transition is over. - @decocms/tanstack: DecoDocument renders StudioRefresh, which reruns the loaders with router.invalidate(). A moved draft pointer is first fetched as a document, for the draft cookie the loaders' server functions carry. A page without the hook keeps the document swap. Co-Authored-By: Claude Opus 5.5 --- CLAUDE.md | 6 +- packages/blocks/src/protocol/channel.ts | 18 +++++ packages/blocks/src/protocol/index.ts | 2 + packages/nextjs/src/StudioBridge.ts | 6 ++ packages/nextjs/src/StudioRefresh.test.tsx | 72 +++++++++++++++++ packages/nextjs/src/StudioRefresh.tsx | 63 +++++++++++++++ packages/nextjs/src/components.test.tsx | 2 + packages/nextjs/src/studio.test.ts | 9 +++ packages/nextjs/src/studio.ts | 6 ++ packages/tanstack/src/react/DecoDocument.tsx | 5 ++ .../tanstack/src/react/StudioRefresh.test.tsx | 79 +++++++++++++++++++ packages/tanstack/src/react/StudioRefresh.ts | 57 +++++++++++++ packages/tanstack/src/studio.test.ts | 9 +++ packages/tanstack/src/studio.ts | 6 ++ tests/studio-shortcut.test.ts | 4 + 15 files changed, 341 insertions(+), 3 deletions(-) create mode 100644 packages/nextjs/src/StudioRefresh.test.tsx create mode 100644 packages/nextjs/src/StudioRefresh.tsx create mode 100644 packages/tanstack/src/react/StudioRefresh.test.tsx create mode 100644 packages/tanstack/src/react/StudioRefresh.ts diff --git a/CLAUDE.md b/CLAUDE.md index 7cc66dfe..993aaa52 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -92,7 +92,7 @@ Each export is built from the source file below (`dist/.js`, see abov | `@decocms/blocks/metrics` | `src/v8/metrics.ts` — `recordServerRequest`, for the framework bindings (`createDecoWorker`, `@decocms/nextjs/instrumentation`): `http.server.request.duration` on the CMS's telemetry; sites don't import it. Resolves without calling the route function with telemetry off; never rejects | | `@decocms/blocks/preview` | `src/v8/preview/index.ts` — `DraftBadge` (the "Preview mode" badge: a `"use client"` component, renders nothing without a pointer or inside a frame) and `StudioBridge` (a hook-free inline `