feat(start): add @json-render/start — TanStack Start support - #309
Open
brunorodmoreira wants to merge 8 commits into
Open
feat(start): add @json-render/start — TanStack Start support#309brunorodmoreira wants to merge 8 commits into
brunorodmoreira wants to merge 8 commits into
Conversation
Sets up the TanStack Start renderer package with dual client/server entry points, tsup build config, and workspace wiring mirroring @json-render/next conventions.
Ports the app spec schema, route matcher, and metadata resolver from @json-render/next, adapted to TanStack conventions: - Route patterns use $slug dynamic segments and $ splat (catch-all) instead of [slug]/[...path]; splat params captured under _splat - resolveMetadata keeps Next-style merging semantics (title templates, shallow-merged openGraph/twitter); new metadataToHead compiles the result into TanStack Start head() meta/link descriptors - collectStaticPaths returns concrete pathnames for prerender.pages - Prompt template teaches TanStack Router URL patterns
Ports the app factory and React components from @json-render/next,
adapted to TanStack Start / TanStack Router:
- createStartApp returns getPageData({pathname}) / getHead({pathname})
/ getStaticPaths() for use in a $ splat catch-all route's loader,
head() option, and prerender.pages config
- StartAppProvider/useStartApp hold registry + handlers and expose a
navigate function backed by router.navigate({ to })
- PageRenderer wires State/Visibility/Validation/Action providers and
injects page content into layout Slot components (same as next)
- Link wraps @tanstack/react-router Link; href→to, prefetch→preload
- StartErrorBoundary/StartLoading/StartNotFound map to the route's
errorComponent/pendingComponent/notFoundComponent options
- No "use client" directives — TanStack Start is Vite-based, not RSC
- schema.test.ts mirrors @json-render/next's suite (validation shape, optional metadata, required children, inferred optional fields) - router.test.ts covers $slug/$ splat extraction, _splat arrays, specificity ordering (static > dynamic > splat), and static path collection with staticParams expansion - metadata.test.ts covers title templates, shallow og/twitter merging, and metadataToHead descriptor compilation (meta/links) - create-app.test.ts covers state merge order (global < page < loader), loader params, layout resolution, async spec factories, getHead, and getStaticPaths
Replaces the hand-rolled StateProvider/VisibilityProvider/ValidationProvider/ ActionProvider stack (duplicated across the layout and no-layout branches) with the combined JSONUIProvider from @json-render/react. Also picks up FunctionsContext, DirectivesContext, and ConfirmationDialogManager, so $computed functions, custom directives, and confirm-gated actions now work on Start pages.
- Apply the global title template to route titles declared as
{ default: ... } objects, not just string titles (previously the raw
object was returned and titleToString dropped the template entirely).
- Replace every %s occurrence in the template (Next.js uses a global
replace), and use a function replacement so titles containing
$-replacement patterns (e.g. "Cash $& Carry") are inserted verbatim.
- Add regression tests for all three behaviors.
Port of next-website-builder to TanStack Start, demonstrating @json-render/start in a Start app: - Catch-all `$.tsx` route SSR-rendering pages from the JSON spec via createStartApp + PageRenderer, with head() wired to getHead() - /builder split-pane editor: JSON spec tree + live preview iframe - GET/PUT /api/spec through route server.handlers backed by an in-memory spec store - createServerFn (fetchSitePage) so client-side navigations read the live server spec store; wire-typed as JsonValue to satisfy Start's server-fn serializability check (Spec props are Record<string, unknown>)
Contributor
|
@brunorodmoreira is attempting to deploy a commit to the Vercel Labs Team on Vercel. A member of the Team first needs to authorize it. |
brunorodmoreira
force-pushed
the
feat/tanstack-start
branch
from
July 13, 2026 23:48
adadcdf to
e8fe239
Compare
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds
@json-render/start, a TanStack Start integration that mirrors the@json-render/nextAPI, plus astart-website-builderexample.The schema/router/metadata core is ported from the next package and kept framework-agnostic.
createStartAppwires routes, loaders and head descriptors into TanStack Router, and pages render through the sameJSONUIProvideras the other integrations. Specs are serialized as plain JSON in loaders so they survive Start's SSR serialization.The example is a port of next-website-builder running on Start: same website component catalog, resizable editor with live preview, and spec persistence through a server route.
Tested with the new vitest suites (schema, router, metadata, create-app),
tsc --noEmitacross the package and example, and manually in the browser (SSR, client navigation, head/metadata resolution).