page.mdx 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. export const metadata = { title: "Quick Start" }
  2. # Quick Start
  3. Get up and running with json-render in 5 minutes.
  4. ## 1. Define your catalog
  5. Create a catalog that defines what components AI can use:
  6. ```typescript
  7. // lib/catalog.ts
  8. import { defineCatalog } from '@json-render/core';
  9. import { schema } from '@json-render/react';
  10. import { z } from 'zod';
  11. export const catalog = defineCatalog(schema, {
  12. components: {
  13. Card: {
  14. props: z.object({
  15. title: z.string(),
  16. description: z.string().nullable(),
  17. }),
  18. slots: ["default"],
  19. description: "Container card with optional title",
  20. },
  21. Button: {
  22. props: z.object({
  23. label: z.string(),
  24. action: z.string().nullable(),
  25. }),
  26. description: "Clickable button that triggers an action",
  27. },
  28. Text: {
  29. props: z.object({
  30. content: z.string(),
  31. }),
  32. description: "Text paragraph",
  33. },
  34. },
  35. actions: {
  36. submit: {
  37. params: z.object({ formId: z.string() }),
  38. description: "Submit a form",
  39. },
  40. navigate: {
  41. params: z.object({ url: z.string() }),
  42. description: "Navigate to a URL",
  43. },
  44. },
  45. });
  46. ```
  47. ## 2. Define your components
  48. Use `defineRegistry` to map catalog types to React components. Each component receives type-safe `props`, `children`, and `emit`:
  49. ```tsx
  50. // lib/registry.tsx
  51. import { defineRegistry } from '@json-render/react';
  52. import { catalog } from './catalog';
  53. export const { registry } = defineRegistry(catalog, {
  54. components: {
  55. Card: ({ props, children }) => (
  56. <div className="p-4 border rounded-lg">
  57. <h2 className="font-bold">{props.title}</h2>
  58. {props.description && (
  59. <p className="text-gray-600">{props.description}</p>
  60. )}
  61. {children}
  62. </div>
  63. ),
  64. Button: ({ props, emit }) => (
  65. <button
  66. className="px-4 py-2 bg-blue-500 text-white rounded"
  67. onClick={() => emit("press")}
  68. >
  69. {props.label}
  70. </button>
  71. ),
  72. Text: ({ props }) => (
  73. <p>{props.content}</p>
  74. ),
  75. },
  76. });
  77. ```
  78. ## 3. Create an API route
  79. Set up a streaming API route for AI generation:
  80. ```typescript
  81. // app/api/generate/route.ts
  82. import { streamText } from 'ai';
  83. import { catalog } from '@/lib/catalog';
  84. export async function POST(req: Request) {
  85. const { prompt } = await req.json();
  86. // Generate system prompt from catalog
  87. const systemPrompt = catalog.prompt();
  88. const result = streamText({
  89. model: 'anthropic/claude-haiku-4.5',
  90. system: systemPrompt,
  91. prompt,
  92. });
  93. return result.toTextStreamResponse();
  94. }
  95. ```
  96. ## 4. Render the UI
  97. Use providers and the `Renderer` with your registry to display AI-generated UI:
  98. ```tsx
  99. // app/page.tsx
  100. 'use client';
  101. import { Renderer, StateProvider, ActionProvider, VisibilityProvider, ValidationProvider, useUIStream } from '@json-render/react';
  102. import { registry } from '@/lib/registry';
  103. export default function Page() {
  104. const { spec, isStreaming, send } = useUIStream({
  105. api: '/api/generate',
  106. });
  107. const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
  108. e.preventDefault();
  109. const formData = new FormData(e.currentTarget);
  110. send(formData.get('prompt') as string);
  111. };
  112. return (
  113. <StateProvider initialState={{}}>
  114. <VisibilityProvider>
  115. <ActionProvider handlers={{
  116. submit: (params) => console.log('Submit:', params),
  117. navigate: (params) => console.log('Navigate:', params),
  118. }}>
  119. <ValidationProvider customFunctions={{}}>
  120. <form onSubmit={handleSubmit}>
  121. <input
  122. name="prompt"
  123. placeholder="Describe what you want..."
  124. className="border p-2 rounded"
  125. />
  126. <button type="submit" disabled={isStreaming}>
  127. Generate
  128. </button>
  129. </form>
  130. <div className="mt-8">
  131. <Renderer spec={spec} registry={registry} loading={isStreaming} />
  132. </div>
  133. </ValidationProvider>
  134. </ActionProvider>
  135. </VisibilityProvider>
  136. </StateProvider>
  137. );
  138. }
  139. ```
  140. ## Quick Start with shadcn/ui
  141. If you want to skip defining components from scratch, use `@json-render/shadcn` for 36 pre-built components:
  142. ```typescript
  143. // lib/catalog.ts
  144. import { defineCatalog } from '@json-render/core';
  145. import { schema } from '@json-render/react/schema';
  146. import { shadcnComponentDefinitions } from '@json-render/shadcn/catalog';
  147. export const catalog = defineCatalog(schema, {
  148. components: {
  149. Card: shadcnComponentDefinitions.Card,
  150. Stack: shadcnComponentDefinitions.Stack,
  151. Heading: shadcnComponentDefinitions.Heading,
  152. Button: shadcnComponentDefinitions.Button,
  153. Input: shadcnComponentDefinitions.Input,
  154. },
  155. actions: {},
  156. });
  157. ```
  158. ```tsx
  159. // lib/registry.tsx
  160. import { defineRegistry } from '@json-render/react';
  161. import { shadcnComponents } from '@json-render/shadcn';
  162. import { catalog } from './catalog';
  163. export const { registry } = defineRegistry(catalog, {
  164. components: {
  165. Card: shadcnComponents.Card,
  166. Stack: shadcnComponents.Stack,
  167. Heading: shadcnComponents.Heading,
  168. Button: shadcnComponents.Button,
  169. Input: shadcnComponents.Input,
  170. },
  171. });
  172. ```
  173. See the [@json-render/shadcn API reference](/docs/api/shadcn) for the full component list.
  174. ## Next steps
  175. - Learn about [catalogs](/docs/catalog) in depth
  176. - Explore [data binding](/docs/data-binding) for dynamic values
  177. - Add [action handlers](/docs/registry#action-handlers) for interactivity
  178. - Implement [conditional visibility](/docs/visibility)
  179. - Use [pre-built shadcn/ui components](/docs/api/shadcn) for fast prototyping