Json-render next
Next.js renderer for json-render that turns JSON specs into full Next.js applications with routes, layouts, SSR, and metadata. Use when working with @json-render/next, building Next.js apps from JSON specs, or creating AI-generated multi-page applications.
install
source · Clone the upstream repo
git clone https://github.com/vercel-labs/json-render
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/vercel-labs/json-render "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/next" ~/.claude/skills/vercel-labs-json-render-next && rm -rf "$T"
manifest:
skills/next/SKILL.mdsource content
@json-render/next
Next.js renderer that converts JSON specs into full Next.js applications with routes, pages, layouts, metadata, and SSR support.
Quick Start
npm install @json-render/core @json-render/react @json-render/next
1. Define Your Spec
// lib/spec.ts import type { NextAppSpec } from "@json-render/next"; export const spec: NextAppSpec = { metadata: { title: { default: "My App", template: "%s | My App" }, description: "A json-render Next.js application", }, layouts: { main: { root: "shell", elements: { shell: { type: "Container", props: {}, children: ["nav", "slot"] }, nav: { type: "NavBar", props: { links: [ { href: "/", label: "Home" }, { href: "/about", label: "About" }, ]}, children: [] }, slot: { type: "Slot", props: {}, children: [] }, }, }, }, routes: { "/": { layout: "main", metadata: { title: "Home" }, page: { root: "hero", elements: { hero: { type: "Card", props: { title: "Welcome" }, children: [] }, }, }, }, "/about": { layout: "main", metadata: { title: "About" }, page: { root: "content", elements: { content: { type: "Card", props: { title: "About Us" }, children: [] }, }, }, }, }, };
2. Create the App
// lib/app.ts import { createNextApp } from "@json-render/next/server"; import { spec } from "./spec"; export const { Page, generateMetadata, generateStaticParams } = createNextApp({ spec, loaders: { // Server-side data loaders (optional) loadPost: async ({ slug }) => { const post = await getPost(slug as string); return { post }; }, }, });
3. Wire Up Route Files
// app/[[...slug]]/page.tsx export { Page as default, generateMetadata, generateStaticParams } from "@/lib/app";
// app/[[...slug]]/layout.tsx import { NextAppProvider } from "@json-render/next"; import { registry, handlers } from "@/lib/registry"; export default function Layout({ children }: { children: React.ReactNode }) { return ( <html lang="en"> <body> <NextAppProvider registry={registry} handlers={handlers}> {children} </NextAppProvider> </body> </html> ); }
Key Concepts
NextAppSpec
The top-level spec defines an entire Next.js application:
- metadata: Root-level SEO metadata (title template, description, OpenGraph)
- layouts: Reusable layout element trees (each must include a
component)Slot - routes: Route definitions keyed by URL pattern
- state: Global initial state shared across all routes
Route Patterns
Routes use Next.js URL conventions:
-- home page"/"
-- static route"/about"
-- dynamic segment"/blog/[slug]"
-- catch-all segment"/docs/[...path]"
-- optional catch-all segment"/settings/[[...path]]"
Layouts
Layouts wrap page content. Every layout MUST include a
Slot component where page content will be rendered. Layouts are defined once in spec.layouts and referenced by routes via the layout field.
Built-in Components
- Slot: Placeholder in layouts where page content is rendered
- Link: Client-side navigation link (wraps
)next/link
Built-in Actions
- setState: Update state value. Params:
{ statePath, value } - pushState: Append to array. Params:
{ statePath, value, clearStatePath? } - removeState: Remove from array by index. Params:
{ statePath, index } - navigate: Client-side navigation. Params:
{ href }
Data Loaders
Server-side async functions that run in the Server Component before rendering. Results are merged into the page's initial state.
createNextApp({ spec, loaders: { loadPost: async ({ slug }) => { const post = await db.post.findUnique({ where: { slug } }); return { post }; }, }, });
SSR
Pages are server-rendered automatically. The
createNextApp Page component is an async Server Component that:
- Matches the route from the spec
- Runs server-side data loaders
- Generates metadata
- Passes the resolved spec to the client renderer for hydration
Entry Points
-- Client components (NextAppProvider, PageRenderer, Link)@json-render/next
-- Server utilities (createNextApp, matchRoute, schema)@json-render/next/server
API Reference
Server Exports (@json-render/next/server
)
@json-render/next/server
-- Create Page, generateMetadata, generateStaticParamscreateNextApp(options)
-- Custom schema for Next.js apps (for AI catalog generation)schema
-- Match a URL to a route specmatchRoute(spec, pathname)
-- Resolve metadata for a routeresolveMetadata(spec, route)
-- Convert catch-all slug array to pathnameslugToPath(slug)
-- Collect static params for all routescollectStaticParams(spec)
Client Exports (@json-render/next
)
@json-render/next
-- Context provider for registry and handlersNextAppProvider
-- Renders a page spec with optional layoutPageRenderer
-- Error boundary componentNextErrorBoundary
-- Loading state componentNextLoading
-- Not-found componentNextNotFound
-- Built-in navigation component (wraps next/link)Link