@puckeditor/cli 0.24.0-canary.301a0304

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (372) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +45 -0
  3. package/dist/bin.mjs +7304 -0
  4. package/dist/docs/api-reference/actions.md +63 -0
  5. package/dist/docs/api-reference/components/action-bar-action.md +35 -0
  6. package/dist/docs/api-reference/components/action-bar-group.md +24 -0
  7. package/dist/docs/api-reference/components/action-bar-label.md +25 -0
  8. package/dist/docs/api-reference/components/action-bar-separator.md +16 -0
  9. package/dist/docs/api-reference/components/action-bar.md +32 -0
  10. package/dist/docs/api-reference/components/auto-field.md +63 -0
  11. package/dist/docs/api-reference/components/drawer-item.md +75 -0
  12. package/dist/docs/api-reference/components/drawer.md +29 -0
  13. package/dist/docs/api-reference/components/drop-zone.md +232 -0
  14. package/dist/docs/api-reference/components/field-label.md +138 -0
  15. package/dist/docs/api-reference/components/inline-text-field.md +77 -0
  16. package/dist/docs/api-reference/components/puck-components.md +19 -0
  17. package/dist/docs/api-reference/components/puck-fields.md +39 -0
  18. package/dist/docs/api-reference/components/puck-layout.md +27 -0
  19. package/dist/docs/api-reference/components/puck-outline.md +19 -0
  20. package/dist/docs/api-reference/components/puck-preview.md +39 -0
  21. package/dist/docs/api-reference/components/puck.md +561 -0
  22. package/dist/docs/api-reference/components/render.md +94 -0
  23. package/dist/docs/api-reference/components/rich-text-menu-control.md +87 -0
  24. package/dist/docs/api-reference/components/rich-text-menu-group.md +27 -0
  25. package/dist/docs/api-reference/components/rich-text-menu.md +99 -0
  26. package/dist/docs/api-reference/components.md +32 -0
  27. package/dist/docs/api-reference/configuration/component-config.md +569 -0
  28. package/dist/docs/api-reference/configuration/config.md +108 -0
  29. package/dist/docs/api-reference/configuration.md +4 -0
  30. package/dist/docs/api-reference/data-model/app-state.md +168 -0
  31. package/dist/docs/api-reference/data-model/component-data.md +62 -0
  32. package/dist/docs/api-reference/data-model/data.md +95 -0
  33. package/dist/docs/api-reference/data-model/item-selector.md +34 -0
  34. package/dist/docs/api-reference/data-model/root-data.md +59 -0
  35. package/dist/docs/api-reference/data-model.md +8 -0
  36. package/dist/docs/api-reference/dictionary.md +172 -0
  37. package/dist/docs/api-reference/field-transforms.md +51 -0
  38. package/dist/docs/api-reference/fields/array.md +211 -0
  39. package/dist/docs/api-reference/fields/base.md +96 -0
  40. package/dist/docs/api-reference/fields/custom.md +193 -0
  41. package/dist/docs/api-reference/fields/external.md +413 -0
  42. package/dist/docs/api-reference/fields/number.md +132 -0
  43. package/dist/docs/api-reference/fields/object.md +78 -0
  44. package/dist/docs/api-reference/fields/radio.md +82 -0
  45. package/dist/docs/api-reference/fields/richtext.md +422 -0
  46. package/dist/docs/api-reference/fields/select.md +79 -0
  47. package/dist/docs/api-reference/fields/slot.md +302 -0
  48. package/dist/docs/api-reference/fields/text.md +93 -0
  49. package/dist/docs/api-reference/fields/textarea.md +93 -0
  50. package/dist/docs/api-reference/fields.md +16 -0
  51. package/dist/docs/api-reference/functions/migrate.md +204 -0
  52. package/dist/docs/api-reference/functions/register-overlay-portal.md +45 -0
  53. package/dist/docs/api-reference/functions/resolve-all-data.md +27 -0
  54. package/dist/docs/api-reference/functions/set-deep.md +55 -0
  55. package/dist/docs/api-reference/functions/transform-props.md +51 -0
  56. package/dist/docs/api-reference/functions/use-get-puck.md +24 -0
  57. package/dist/docs/api-reference/functions/use-puck.md +43 -0
  58. package/dist/docs/api-reference/functions/walk-tree.md +88 -0
  59. package/dist/docs/api-reference/functions.md +8 -0
  60. package/dist/docs/api-reference/overrides/action-bar.md +35 -0
  61. package/dist/docs/api-reference/overrides/component-overlay.md +41 -0
  62. package/dist/docs/api-reference/overrides/drawer-item.md +24 -0
  63. package/dist/docs/api-reference/overrides/drawer.md +19 -0
  64. package/dist/docs/api-reference/overrides/field-label.md +18 -0
  65. package/dist/docs/api-reference/overrides/field-types.md +51 -0
  66. package/dist/docs/api-reference/overrides/fields.md +19 -0
  67. package/dist/docs/api-reference/overrides/header-actions.md +24 -0
  68. package/dist/docs/api-reference/overrides/header.md +29 -0
  69. package/dist/docs/api-reference/overrides/iframe.md +32 -0
  70. package/dist/docs/api-reference/overrides/outline.md +19 -0
  71. package/dist/docs/api-reference/overrides/preview.md +19 -0
  72. package/dist/docs/api-reference/overrides/puck.md +19 -0
  73. package/dist/docs/api-reference/overrides.md +28 -0
  74. package/dist/docs/api-reference/permissions.md +55 -0
  75. package/dist/docs/api-reference/plugin.md +112 -0
  76. package/dist/docs/api-reference/plugins/blocks-plugin.md +57 -0
  77. package/dist/docs/api-reference/plugins/fields-plugin.md +68 -0
  78. package/dist/docs/api-reference/plugins/legacy-side-bar-plugin.md +54 -0
  79. package/dist/docs/api-reference/plugins/outline-plugin.md +57 -0
  80. package/dist/docs/api-reference/puck-api.md +278 -0
  81. package/dist/docs/api-reference/theming/action-bar.md +32 -0
  82. package/dist/docs/api-reference/theming/button.md +65 -0
  83. package/dist/docs/api-reference/theming/canvas.md +20 -0
  84. package/dist/docs/api-reference/theming/computed-values.md +194 -0
  85. package/dist/docs/api-reference/theming/drawer.md +34 -0
  86. package/dist/docs/api-reference/theming/fields.md +70 -0
  87. package/dist/docs/api-reference/theming/global.md +127 -0
  88. package/dist/docs/api-reference/theming/header.md +19 -0
  89. package/dist/docs/api-reference/theming/icon-button.md +28 -0
  90. package/dist/docs/api-reference/theming/outline.md +35 -0
  91. package/dist/docs/api-reference/theming/plugin-bar.md +24 -0
  92. package/dist/docs/api-reference/theming/sidebar.md +19 -0
  93. package/dist/docs/api-reference/theming/slot.md +27 -0
  94. package/dist/docs/cli.md +201 -0
  95. package/dist/docs/extending-puck/composition.md +54 -0
  96. package/dist/docs/extending-puck/custom-fields.md +133 -0
  97. package/dist/docs/extending-puck/field-transforms.md +89 -0
  98. package/dist/docs/extending-puck/internal-puck-api.md +96 -0
  99. package/dist/docs/extending-puck/plugins.md +159 -0
  100. package/dist/docs/extending-puck/theming.md +88 -0
  101. package/dist/docs/extending-puck/ui-overrides.md +134 -0
  102. package/dist/docs/getting-started.md +68 -0
  103. package/dist/docs/guides/migrations/dropzones-to-slots.md +138 -0
  104. package/dist/docs/index.json +466 -0
  105. package/dist/docs/index.md +37 -0
  106. package/dist/docs/integrating-puck/categories.md +92 -0
  107. package/dist/docs/integrating-puck/component-configuration.md +159 -0
  108. package/dist/docs/integrating-puck/data-migration.md +86 -0
  109. package/dist/docs/integrating-puck/dynamic-fields.md +86 -0
  110. package/dist/docs/integrating-puck/dynamic-props.md +137 -0
  111. package/dist/docs/integrating-puck/external-data-sources.md +149 -0
  112. package/dist/docs/integrating-puck/feature-toggling.md +121 -0
  113. package/dist/docs/integrating-puck/localization.md +228 -0
  114. package/dist/docs/integrating-puck/multi-column-layouts.md +226 -0
  115. package/dist/docs/integrating-puck/overlay-portals.md +25 -0
  116. package/dist/docs/integrating-puck/rich-text-editing.md +230 -0
  117. package/dist/docs/integrating-puck/root-configuration.md +171 -0
  118. package/dist/docs/integrating-puck/server-components.md +199 -0
  119. package/dist/docs/integrating-puck/styling.md +117 -0
  120. package/dist/docs/integrating-puck/viewports.md +75 -0
  121. package/dist/templates/astro/README.md +52 -0
  122. package/dist/templates/astro/_gitignore +24 -0
  123. package/dist/templates/astro/astro.config.mjs +14 -0
  124. package/dist/templates/astro/database.json +1 -0
  125. package/dist/templates/astro/package.json +25 -0
  126. package/dist/templates/astro/public/favicon.svg +9 -0
  127. package/dist/templates/astro/src/lib/pages.ts +21 -0
  128. package/dist/templates/astro/src/lib/resolve-puck-path.ts +19 -0
  129. package/dist/templates/astro/src/pages/[...puckPath].astro +25 -0
  130. package/dist/templates/astro/src/pages/api/pages.ts +18 -0
  131. package/dist/templates/astro/src/puck/editor.tsx +32 -0
  132. package/dist/templates/astro/src/puck/pages.ts +15 -0
  133. package/dist/templates/astro/src/puck/render.tsx +9 -0
  134. package/dist/templates/astro/src/puck.config.tsx +23 -0
  135. package/dist/templates/astro/tsconfig.json +14 -0
  136. package/dist/templates/astro-ai/README.md +64 -0
  137. package/dist/templates/astro-ai/_gitignore +24 -0
  138. package/dist/templates/astro-ai/astro.config.mjs +21 -0
  139. package/dist/templates/astro-ai/database.json +1 -0
  140. package/dist/templates/astro-ai/package.json +27 -0
  141. package/dist/templates/astro-ai/public/favicon.svg +9 -0
  142. package/dist/templates/astro-ai/src/lib/pages.ts +21 -0
  143. package/dist/templates/astro-ai/src/lib/resolve-puck-path.ts +19 -0
  144. package/dist/templates/astro-ai/src/pages/[...puckPath].astro +25 -0
  145. package/dist/templates/astro-ai/src/pages/api/pages.ts +18 -0
  146. package/dist/templates/astro-ai/src/pages/api/puck/[...all].ts +36 -0
  147. package/dist/templates/astro-ai/src/puck/editor.tsx +53 -0
  148. package/dist/templates/astro-ai/src/puck/pages.ts +15 -0
  149. package/dist/templates/astro-ai/src/puck/render.tsx +10 -0
  150. package/dist/templates/astro-ai/src/puck.config.tsx +23 -0
  151. package/dist/templates/astro-ai/tsconfig.json +14 -0
  152. package/dist/templates/express/README.md +66 -0
  153. package/dist/templates/express/_gitignore +16 -0
  154. package/dist/templates/express/database.json +1 -0
  155. package/dist/templates/express/package.json +20 -0
  156. package/dist/templates/express/src/index.ts +15 -0
  157. package/dist/templates/express/src/puck/pages.ts +39 -0
  158. package/dist/templates/express/tsconfig.json +12 -0
  159. package/dist/templates/express-ai/README.md +81 -0
  160. package/dist/templates/express-ai/_gitignore +16 -0
  161. package/dist/templates/express-ai/database.json +1 -0
  162. package/dist/templates/express-ai/package.json +22 -0
  163. package/dist/templates/express-ai/src/index.ts +17 -0
  164. package/dist/templates/express-ai/src/puck/cloud.ts +71 -0
  165. package/dist/templates/express-ai/src/puck/pages.ts +39 -0
  166. package/dist/templates/express-ai/tsconfig.json +12 -0
  167. package/dist/templates/hono/README.md +66 -0
  168. package/dist/templates/hono/_gitignore +32 -0
  169. package/dist/templates/hono/database.json +1 -0
  170. package/dist/templates/hono/package.json +20 -0
  171. package/dist/templates/hono/src/index.ts +21 -0
  172. package/dist/templates/hono/src/puck/pages.ts +32 -0
  173. package/dist/templates/hono/tsconfig.json +13 -0
  174. package/dist/templates/hono-ai/README.md +81 -0
  175. package/dist/templates/hono-ai/_gitignore +32 -0
  176. package/dist/templates/hono-ai/database.json +1 -0
  177. package/dist/templates/hono-ai/package.json +22 -0
  178. package/dist/templates/hono-ai/src/index.ts +23 -0
  179. package/dist/templates/hono-ai/src/puck/cloud.ts +30 -0
  180. package/dist/templates/hono-ai/src/puck/pages.ts +32 -0
  181. package/dist/templates/hono-ai/tsconfig.json +13 -0
  182. package/dist/templates/manifest.json +4 -0
  183. package/dist/templates/next/README.md +112 -0
  184. package/dist/templates/next/_gitignore +35 -0
  185. package/dist/templates/next/app/[...puckPath]/client.tsx +9 -0
  186. package/dist/templates/next/app/[...puckPath]/page.tsx +49 -0
  187. package/dist/templates/next/app/favicon.ico +0 -0
  188. package/dist/templates/next/app/layout.tsx +13 -0
  189. package/dist/templates/next/app/page.tsx +1 -0
  190. package/dist/templates/next/app/puck/[...puckPath]/client.tsx +20 -0
  191. package/dist/templates/next/app/puck/[...puckPath]/page.tsx +55 -0
  192. package/dist/templates/next/app/puck/api/route.ts +25 -0
  193. package/dist/templates/next/app/puck/page.tsx +3 -0
  194. package/dist/templates/next/app/styles.css +3 -0
  195. package/dist/templates/next/database.json +1 -0
  196. package/dist/templates/next/lib/get-page.ts +11 -0
  197. package/dist/templates/next/next.config.js +3 -0
  198. package/dist/templates/next/package.json +25 -0
  199. package/dist/templates/next/proxy.ts +27 -0
  200. package/dist/templates/next/puck.config.tsx +25 -0
  201. package/dist/templates/next/tsconfig/base.json +20 -0
  202. package/dist/templates/next/tsconfig/nextjs.json +21 -0
  203. package/dist/templates/next/tsconfig.json +8 -0
  204. package/dist/templates/next-ai/README.md +169 -0
  205. package/dist/templates/next-ai/_gitignore +35 -0
  206. package/dist/templates/next-ai/app/[...puckPath]/client.tsx +12 -0
  207. package/dist/templates/next-ai/app/[...puckPath]/page.tsx +49 -0
  208. package/dist/templates/next-ai/app/api/pages/route.ts +26 -0
  209. package/dist/templates/next-ai/app/api/puck/[...all]/route.ts +31 -0
  210. package/dist/templates/next-ai/app/layout.tsx +13 -0
  211. package/dist/templates/next-ai/app/page.tsx +1 -0
  212. package/dist/templates/next-ai/app/puck/[...puckPath]/client.tsx +38 -0
  213. package/dist/templates/next-ai/app/puck/[...puckPath]/page.tsx +57 -0
  214. package/dist/templates/next-ai/app/puck/page.tsx +3 -0
  215. package/dist/templates/next-ai/app/styles.css +3 -0
  216. package/dist/templates/next-ai/database.json +1 -0
  217. package/dist/templates/next-ai/lib/get-page.ts +11 -0
  218. package/dist/templates/next-ai/next.config.js +3 -0
  219. package/dist/templates/next-ai/package.json +27 -0
  220. package/dist/templates/next-ai/proxy.ts +27 -0
  221. package/dist/templates/next-ai/public/favicon.ico +0 -0
  222. package/dist/templates/next-ai/puck.config.tsx +25 -0
  223. package/dist/templates/next-ai/tsconfig/base.json +20 -0
  224. package/dist/templates/next-ai/tsconfig/nextjs.json +21 -0
  225. package/dist/templates/next-ai/tsconfig.json +8 -0
  226. package/dist/templates/react-router/README.md +113 -0
  227. package/dist/templates/react-router/_gitignore +6 -0
  228. package/dist/templates/react-router/app/components/puck-render.tsx +8 -0
  229. package/dist/templates/react-router/app/lib/pages.server.ts +29 -0
  230. package/dist/templates/react-router/app/lib/resolve-puck-path.server.ts +19 -0
  231. package/dist/templates/react-router/app/root.tsx +65 -0
  232. package/dist/templates/react-router/app/routes/_index.tsx +31 -0
  233. package/dist/templates/react-router/app/routes/puck-splat.tsx +95 -0
  234. package/dist/templates/react-router/app/routes.ts +7 -0
  235. package/dist/templates/react-router/database.json +1 -0
  236. package/dist/templates/react-router/package.json +33 -0
  237. package/dist/templates/react-router/public/favicon.ico +0 -0
  238. package/dist/templates/react-router/puck.config.tsx +23 -0
  239. package/dist/templates/react-router/react-router.config.ts +7 -0
  240. package/dist/templates/react-router/tsconfig.json +29 -0
  241. package/dist/templates/react-router/vite.config.ts +10 -0
  242. package/dist/templates/react-router-ai/README.md +172 -0
  243. package/dist/templates/react-router-ai/_gitignore +6 -0
  244. package/dist/templates/react-router-ai/app/components/puck-render.tsx +11 -0
  245. package/dist/templates/react-router-ai/app/lib/pages.server.ts +29 -0
  246. package/dist/templates/react-router-ai/app/lib/resolve-puck-path.server.ts +19 -0
  247. package/dist/templates/react-router-ai/app/root.tsx +65 -0
  248. package/dist/templates/react-router-ai/app/routes/_index.tsx +31 -0
  249. package/dist/templates/react-router-ai/app/routes/api.puck.ts +34 -0
  250. package/dist/templates/react-router-ai/app/routes/puck-splat.tsx +119 -0
  251. package/dist/templates/react-router-ai/app/routes.ts +8 -0
  252. package/dist/templates/react-router-ai/database.json +1 -0
  253. package/dist/templates/react-router-ai/package.json +35 -0
  254. package/dist/templates/react-router-ai/public/favicon.ico +0 -0
  255. package/dist/templates/react-router-ai/puck.config.tsx +25 -0
  256. package/dist/templates/react-router-ai/react-router.config.ts +7 -0
  257. package/dist/templates/react-router-ai/tsconfig.json +29 -0
  258. package/dist/templates/react-router-ai/vite.config.ts +10 -0
  259. package/dist/templates/tanstack-start/README.md +113 -0
  260. package/dist/templates/tanstack-start/_gitignore +12 -0
  261. package/dist/templates/tanstack-start/database.json +1 -0
  262. package/dist/templates/tanstack-start/package.json +26 -0
  263. package/dist/templates/tanstack-start/puck.config.tsx +23 -0
  264. package/dist/templates/tanstack-start/src/components/puck-render.tsx +8 -0
  265. package/dist/templates/tanstack-start/src/lib/pages.server.ts +26 -0
  266. package/dist/templates/tanstack-start/src/lib/pages.ts +39 -0
  267. package/dist/templates/tanstack-start/src/lib/resolve-puck-path.ts +19 -0
  268. package/dist/templates/tanstack-start/src/routeTree.gen.ts +86 -0
  269. package/dist/templates/tanstack-start/src/router.tsx +19 -0
  270. package/dist/templates/tanstack-start/src/routes/$.tsx +41 -0
  271. package/dist/templates/tanstack-start/src/routes/__root.tsx +42 -0
  272. package/dist/templates/tanstack-start/src/routes/index.tsx +18 -0
  273. package/dist/templates/tanstack-start/src/styles.css +13 -0
  274. package/dist/templates/tanstack-start/tsconfig.json +24 -0
  275. package/dist/templates/tanstack-start/vite.config.ts +15 -0
  276. package/dist/templates/tanstack-start-ai/README.md +171 -0
  277. package/dist/templates/tanstack-start-ai/_gitignore +12 -0
  278. package/dist/templates/tanstack-start-ai/database.json +1 -0
  279. package/dist/templates/tanstack-start-ai/package.json +28 -0
  280. package/dist/templates/tanstack-start-ai/puck.config.tsx +23 -0
  281. package/dist/templates/tanstack-start-ai/src/components/puck-render.tsx +11 -0
  282. package/dist/templates/tanstack-start-ai/src/lib/pages.server.ts +26 -0
  283. package/dist/templates/tanstack-start-ai/src/lib/pages.ts +39 -0
  284. package/dist/templates/tanstack-start-ai/src/lib/resolve-puck-path.ts +19 -0
  285. package/dist/templates/tanstack-start-ai/src/routeTree.gen.ts +104 -0
  286. package/dist/templates/tanstack-start-ai/src/router.tsx +19 -0
  287. package/dist/templates/tanstack-start-ai/src/routes/$.tsx +73 -0
  288. package/dist/templates/tanstack-start-ai/src/routes/__root.tsx +42 -0
  289. package/dist/templates/tanstack-start-ai/src/routes/api/puck/$.ts +39 -0
  290. package/dist/templates/tanstack-start-ai/src/routes/index.tsx +18 -0
  291. package/dist/templates/tanstack-start-ai/src/styles.css +13 -0
  292. package/dist/templates/tanstack-start-ai/tsconfig.json +24 -0
  293. package/dist/templates/tanstack-start-ai/vite.config.ts +15 -0
  294. package/dist/templates/vinext/README.md +112 -0
  295. package/dist/templates/vinext/_gitignore +33 -0
  296. package/dist/templates/vinext/app/[...puckPath]/client.tsx +9 -0
  297. package/dist/templates/vinext/app/[...puckPath]/page.tsx +49 -0
  298. package/dist/templates/vinext/app/favicon.ico +0 -0
  299. package/dist/templates/vinext/app/layout.tsx +13 -0
  300. package/dist/templates/vinext/app/page.tsx +1 -0
  301. package/dist/templates/vinext/app/puck/[...puckPath]/client.tsx +20 -0
  302. package/dist/templates/vinext/app/puck/[...puckPath]/page.tsx +55 -0
  303. package/dist/templates/vinext/app/puck/api/route.ts +25 -0
  304. package/dist/templates/vinext/app/puck/page.tsx +3 -0
  305. package/dist/templates/vinext/app/styles.css +3 -0
  306. package/dist/templates/vinext/database.json +1 -0
  307. package/dist/templates/vinext/lib/get-page.ts +11 -0
  308. package/dist/templates/vinext/package.json +30 -0
  309. package/dist/templates/vinext/proxy.ts +27 -0
  310. package/dist/templates/vinext/puck.config.tsx +25 -0
  311. package/dist/templates/vinext/tsconfig.json +30 -0
  312. package/dist/templates/vinext/vite.config.ts +6 -0
  313. package/dist/templates/vinext-ai/README.md +169 -0
  314. package/dist/templates/vinext-ai/_gitignore +33 -0
  315. package/dist/templates/vinext-ai/app/[...puckPath]/client.tsx +12 -0
  316. package/dist/templates/vinext-ai/app/[...puckPath]/page.tsx +49 -0
  317. package/dist/templates/vinext-ai/app/api/pages/route.ts +26 -0
  318. package/dist/templates/vinext-ai/app/api/puck/[...all]/route.ts +31 -0
  319. package/dist/templates/vinext-ai/app/layout.tsx +13 -0
  320. package/dist/templates/vinext-ai/app/page.tsx +1 -0
  321. package/dist/templates/vinext-ai/app/puck/[...puckPath]/client.tsx +38 -0
  322. package/dist/templates/vinext-ai/app/puck/[...puckPath]/page.tsx +57 -0
  323. package/dist/templates/vinext-ai/app/puck/page.tsx +3 -0
  324. package/dist/templates/vinext-ai/app/styles.css +3 -0
  325. package/dist/templates/vinext-ai/database.json +1 -0
  326. package/dist/templates/vinext-ai/lib/get-page.ts +11 -0
  327. package/dist/templates/vinext-ai/package.json +32 -0
  328. package/dist/templates/vinext-ai/proxy.ts +27 -0
  329. package/dist/templates/vinext-ai/public/favicon.ico +0 -0
  330. package/dist/templates/vinext-ai/puck.config.tsx +25 -0
  331. package/dist/templates/vinext-ai/tsconfig.json +30 -0
  332. package/dist/templates/vinext-ai/vite.config.ts +9 -0
  333. package/dist/templates/vite/README.md +56 -0
  334. package/dist/templates/vite/_gitignore +24 -0
  335. package/dist/templates/vite/database.json +1 -0
  336. package/dist/templates/vite/index.html +12 -0
  337. package/dist/templates/vite/package.json +29 -0
  338. package/dist/templates/vite/server/index.ts +13 -0
  339. package/dist/templates/vite/server/prod.ts +18 -0
  340. package/dist/templates/vite/server/puck/pages.ts +32 -0
  341. package/dist/templates/vite/src/App.tsx +11 -0
  342. package/dist/templates/vite/src/main.tsx +12 -0
  343. package/dist/templates/vite/src/puck/editor.tsx +28 -0
  344. package/dist/templates/vite/src/puck/page.tsx +27 -0
  345. package/dist/templates/vite/src/puck/pages.ts +15 -0
  346. package/dist/templates/vite/src/puck/root.tsx +27 -0
  347. package/dist/templates/vite/src/puck.config.tsx +23 -0
  348. package/dist/templates/vite/tsconfig.app.json +26 -0
  349. package/dist/templates/vite/tsconfig.json +7 -0
  350. package/dist/templates/vite/tsconfig.node.json +23 -0
  351. package/dist/templates/vite/vite.config.ts +14 -0
  352. package/dist/templates/vite-ai/README.md +67 -0
  353. package/dist/templates/vite-ai/_gitignore +24 -0
  354. package/dist/templates/vite-ai/database.json +1 -0
  355. package/dist/templates/vite-ai/index.html +12 -0
  356. package/dist/templates/vite-ai/package.json +31 -0
  357. package/dist/templates/vite-ai/server/index.ts +15 -0
  358. package/dist/templates/vite-ai/server/prod.ts +18 -0
  359. package/dist/templates/vite-ai/server/puck/cloud.ts +30 -0
  360. package/dist/templates/vite-ai/server/puck/pages.ts +32 -0
  361. package/dist/templates/vite-ai/src/App.tsx +11 -0
  362. package/dist/templates/vite-ai/src/main.tsx +12 -0
  363. package/dist/templates/vite-ai/src/puck/editor.tsx +49 -0
  364. package/dist/templates/vite-ai/src/puck/page.tsx +28 -0
  365. package/dist/templates/vite-ai/src/puck/pages.ts +15 -0
  366. package/dist/templates/vite-ai/src/puck/root.tsx +27 -0
  367. package/dist/templates/vite-ai/src/puck.config.tsx +23 -0
  368. package/dist/templates/vite-ai/tsconfig.app.json +26 -0
  369. package/dist/templates/vite-ai/tsconfig.json +7 -0
  370. package/dist/templates/vite-ai/tsconfig.node.json +23 -0
  371. package/dist/templates/vite-ai/vite.config.ts +14 -0
  372. package/package.json +51 -0
@@ -0,0 +1,15 @@
1
+ import { defineConfig } from "vite";
2
+
3
+ import { tanstackStart } from "@tanstack/react-start/plugin/vite";
4
+
5
+ import viteReact from "@vitejs/plugin-react";
6
+
7
+ const config = defineConfig({
8
+ resolve: { tsconfigPaths: true },
9
+ plugins: [tanstackStart(), viteReact()],
10
+ optimizeDeps: {
11
+ include: ["@puckeditor/core", "@puckeditor/plugin-ai"],
12
+ },
13
+ });
14
+
15
+ export default config;
@@ -0,0 +1,112 @@
1
+ # Puck + vinext recipe
2
+
3
+ [Puck](https://puckeditor.com) is the open-source visual editor for React.
4
+
5
+ This recipe connects Puck to a [vinext](https://github.com/cloudflare/vinext) app, which runs the [Next.js App Router](https://nextjs.org/docs/app) API on Vite, so you can create and edit pages for any route in this app.
6
+
7
+ ## Core concepts
8
+
9
+ If you're new to Puck, this section introduces the core concepts you need to know.
10
+
11
+ ### Puck
12
+
13
+ The Puck visual editor has three main parts: a config, the editor, and the renderer.
14
+
15
+ #### Config
16
+
17
+ The [config](https://puckeditor.com/docs/integrating-puck/component-configuration) registers the components users can use to build pages in the editor and the fields they can edit.
18
+
19
+ ```tsx
20
+ const config = {
21
+ components: {
22
+ HeadingBlock: {
23
+ fields: {
24
+ title: { type: "text" },
25
+ },
26
+ render: ({ title }) => <h1>{title}</h1>,
27
+ },
28
+ },
29
+ };
30
+ ```
31
+
32
+ #### The editor
33
+
34
+ The [`<Puck>`](https://puckeditor.com/docs/api-reference/components/puck) component renders the editor. It uses a config, exports [pages as JSON](https://puckeditor.com/docs/api-reference/data-model/data), and accepts initial page data for editing existing pages.
35
+
36
+ ```tsx
37
+ <Puck
38
+ config={config} // The components available to the editor
39
+ data={data} // The page JSON to edit
40
+ onPublish={(data) => {
41
+ // Save data to your database
42
+ }}
43
+ />
44
+ ```
45
+
46
+ #### The renderer
47
+
48
+ The [`<Render>`](https://puckeditor.com/docs/api-reference/components/render) component renders pages. It expects the page JSON and the config used to create that page.
49
+
50
+ ```tsx
51
+ <Render
52
+ config={config} // The components used to create the page
53
+ data={data} // The page JSON to render
54
+ />
55
+ ```
56
+
57
+ ## Run the recipe
58
+
59
+ ### 1. Start the development server
60
+
61
+ Run:
62
+
63
+ ```sh
64
+ npm run dev
65
+ ```
66
+
67
+ Once the server is running, navigate to [http://localhost:3000](http://localhost:3000) to view the home page, or [http://localhost:3000/edit](http://localhost:3000/edit) to edit it with Puck.
68
+
69
+ ### 2. Create a page
70
+
71
+ Navigate to [http://localhost:3000/edit](http://localhost:3000/edit), open the `Blocks` tab in the left sidebar and build your page by dragging components onto the canvas.
72
+
73
+ ### 3. Publish the page
74
+
75
+ Once your page is ready, select **Publish** in the header to save the result, then navigate to [http://localhost:3000](http://localhost:3000) to view the published page.
76
+
77
+ You can also create a page at any path by navigating to `/your/path/edit` and publishing it. The route `/your/path` will render the page.
78
+
79
+ ## How it works
80
+
81
+ When a URL ends in `/edit`, [`proxy.ts`](https://nextjs.org/docs/app/api-reference/file-conventions/proxy) sends the request to the Puck editor route (`app/puck/[...puckPath]/page.tsx`). The editor loads the saved page, or starts with an empty page if the path is new.
82
+
83
+ Selecting **Publish** sends the page data to the `/puck/api` endpoint (`app/puck/api/route.ts`). The handler writes the JSON to `database.json` and clears the cached page. The catch-all route (`app/[...puckPath]/page.tsx`) then loads the same data and renders it with [`<Render>`](https://puckeditor.com/docs/api-reference/components/render).
84
+
85
+ The table below shows the files that implement this flow.
86
+
87
+ | File | Purpose |
88
+ | ----------------------------------- | -------------------------------------------------------------------------------------------------- |
89
+ | `puck.config.tsx` | Defines the components, fields, and default props available to Puck. Add your own components here. |
90
+ | `app/puck/[...puckPath]/page.tsx` | Loads page data for the editor. |
91
+ | `app/puck/[...puckPath]/client.tsx` | Renders the editor and publishes changes. |
92
+ | `app/[...puckPath]/page.tsx` | Loads and renders published pages. |
93
+ | `app/puck/api/route.ts` | Saves published pages. |
94
+ | `proxy.ts` | Routes URLs ending in `/edit` to `/puck/[...puckPath]/page.tsx`. |
95
+ | `lib/get-page.ts` | Reads page data from `database.json`. Replace this with your own data fetching logic. |
96
+ | `database.json` | Acts as a local database. Replace this with your own database solution. |
97
+
98
+ ## Before deploying to production
99
+
100
+ Before deploying this recipe, make sure to:
101
+
102
+ - **Protect the editor and API.** The `/edit` routes and `/puck/api` endpoint are public by default. Add authentication and authorization so only trusted users can edit or publish pages.
103
+ - **Add your component library.** Replace the example `HeadingBlock` in `puck.config.tsx` with the components and fields your users need.
104
+ - **Use a real database.** Replace `database.json` in `lib/get-page.ts` and `app/puck/api/route.ts`. Local files are not reliable across server instances, and aren't available on Cloudflare Workers.
105
+ - **Choose a rendering strategy.** `app/[...puckPath]/page.tsx` uses `force-static`. Remove it if a page needs request-time data such as headers, cookies, or user sessions.
106
+
107
+ ## Learn more
108
+
109
+ - [Puck documentation](https://puckeditor.com/docs)
110
+ - [Getting started with Puck](https://puckeditor.com/docs/getting-started)
111
+ - [Integrating Puck](https://puckeditor.com/docs/integrating-puck/component-configuration)
112
+ - [Puck Discord](https://discord.gg/D9e4E3MQVZ)
@@ -0,0 +1,33 @@
1
+ # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2
+
3
+ # dependencies
4
+ /node_modules
5
+ /.pnp
6
+ .pnp.js
7
+
8
+ # testing
9
+ /coverage
10
+
11
+ # vinext
12
+ /dist/
13
+
14
+ # production
15
+ /build
16
+
17
+ # misc
18
+ .DS_Store
19
+ *.pem
20
+
21
+ # debug
22
+ npm-debug.log*
23
+ yarn-debug.log*
24
+ yarn-error.log*
25
+
26
+ # local env files
27
+ .env.local
28
+ .env.development.local
29
+ .env.test.local
30
+ .env.production.local
31
+
32
+ # vercel
33
+ .vercel
@@ -0,0 +1,9 @@
1
+ "use client";
2
+
3
+ import type { Data } from "@puckeditor/core";
4
+ import { Render } from "@puckeditor/core";
5
+ import config from "../../puck.config";
6
+
7
+ export function Client({ data }: { data: Data }) {
8
+ return <Render config={config} data={data} />;
9
+ }
@@ -0,0 +1,49 @@
1
+ /**
2
+ * This file implements a catch-all route that renders the user-facing pages
3
+ * generated by Puck. For any route visited (with exception of other hardcoded
4
+ * pages in /app), it will check your database (via `getPage`) for a Puck page
5
+ * and render it using <Render>.
6
+ *
7
+ * All routes produced by this page are statically rendered using incremental
8
+ * static site generation. After the first visit, the page will be cached as
9
+ * a static file. Subsequent visits will receive the cache. Publishing a page
10
+ * will invalidate the cache as the page is written in /api/puck/route.ts
11
+ */
12
+
13
+ import { Client } from "./client";
14
+ import { notFound } from "next/navigation";
15
+ import { Metadata } from "next";
16
+ import { getPage } from "../../lib/get-page";
17
+
18
+ export async function generateMetadata({
19
+ params,
20
+ }: {
21
+ params: Promise<{ puckPath: string[] }>;
22
+ }): Promise<Metadata> {
23
+ const { puckPath = [] } = await params;
24
+ const path = `/${puckPath.join("/")}`;
25
+
26
+ return {
27
+ title: getPage(path)?.root.props?.title,
28
+ };
29
+ }
30
+
31
+ export default async function Page({
32
+ params,
33
+ }: {
34
+ params: Promise<{ puckPath: string[] }>;
35
+ }) {
36
+ const { puckPath = [] } = await params;
37
+ const path = `/${puckPath.join("/")}`;
38
+ const data = getPage(path);
39
+
40
+ if (!data) {
41
+ return notFound();
42
+ }
43
+
44
+ return <Client data={data} />;
45
+ }
46
+
47
+ // Force Next.js to produce static pages: https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config#dynamic
48
+ // Delete this if you need dynamic rendering, such as access to headers or cookies
49
+ export const dynamic = "force-static";
@@ -0,0 +1,13 @@
1
+ import "./styles.css";
2
+
3
+ export default function RootLayout({
4
+ children,
5
+ }: {
6
+ children: React.ReactNode;
7
+ }) {
8
+ return (
9
+ <html lang="en">
10
+ <body>{children}</body>
11
+ </html>
12
+ );
13
+ }
@@ -0,0 +1 @@
1
+ export { default, generateMetadata } from "./[...puckPath]/page";
@@ -0,0 +1,20 @@
1
+ "use client";
2
+
3
+ import type { Data } from "@puckeditor/core";
4
+ import { Puck } from "@puckeditor/core";
5
+ import config from "../../../puck.config";
6
+
7
+ export function Client({ path, data }: { path: string; data: Data }) {
8
+ return (
9
+ <Puck
10
+ config={config}
11
+ data={data}
12
+ onPublish={async (data) => {
13
+ await fetch("/puck/api", {
14
+ method: "post",
15
+ body: JSON.stringify({ data, path }),
16
+ });
17
+ }}
18
+ />
19
+ );
20
+ }
@@ -0,0 +1,55 @@
1
+ /**
2
+ * This file implements a *magic* catch-all route that renders the Puck editor.
3
+ *
4
+ * This route exposes /puck/[...puckPath], but is disabled by middleware.ts. The middleware
5
+ * then rewrites all URL requests ending in `/edit` to this route, allowing you to visit any
6
+ * page in your application and add /edit to the end to spin up a Puck editor.
7
+ *
8
+ * This approach enables public pages to be statically rendered whilst the /puck route can
9
+ * remain dynamic.
10
+ *
11
+ * NB this route is public, and you will need to add authentication
12
+ */
13
+
14
+ import "@puckeditor/core/puck.css";
15
+ import type { Data } from "@puckeditor/core";
16
+ import { Metadata } from "next";
17
+ import { Client } from "./client";
18
+ import { getPage } from "../../../lib/get-page";
19
+
20
+ // Empty data for new pages.
21
+ const EMPTY_PAGE_DATA: Data = {
22
+ content: [],
23
+ root: {
24
+ props: {
25
+ title: "",
26
+ },
27
+ },
28
+ };
29
+
30
+ export async function generateMetadata({
31
+ params,
32
+ }: {
33
+ params: Promise<{ puckPath: string[] }>;
34
+ }): Promise<Metadata> {
35
+ const { puckPath = [] } = await params;
36
+ const path = `/${puckPath.join("/")}`;
37
+
38
+ return {
39
+ title: "Puck: " + path,
40
+ };
41
+ }
42
+
43
+ export default async function Page({
44
+ params,
45
+ }: {
46
+ params: Promise<{ puckPath: string[] }>;
47
+ }) {
48
+ const { puckPath = [] } = await params;
49
+ const path = `/${puckPath.join("/")}`;
50
+ const data = getPage(path);
51
+
52
+ return <Client path={path} data={data || EMPTY_PAGE_DATA} />;
53
+ }
54
+
55
+ export const dynamic = "force-dynamic";
@@ -0,0 +1,25 @@
1
+ import { revalidatePath } from "next/cache";
2
+ import { NextResponse } from "next/server";
3
+ import fs from "fs";
4
+
5
+ export async function POST(request: Request) {
6
+ const payload = await request.json();
7
+
8
+ const existingData = JSON.parse(
9
+ fs.existsSync("database.json")
10
+ ? fs.readFileSync("database.json", "utf-8")
11
+ : "{}"
12
+ );
13
+
14
+ const updatedData = {
15
+ ...existingData,
16
+ [payload.path]: payload.data,
17
+ };
18
+
19
+ fs.writeFileSync("database.json", JSON.stringify(updatedData));
20
+
21
+ // Purge Next.js cache
22
+ revalidatePath(payload.path);
23
+
24
+ return NextResponse.json({ status: "ok" });
25
+ }
@@ -0,0 +1,3 @@
1
+ export { default, generateMetadata } from "./[...puckPath]/page";
2
+
3
+ export const dynamic = "force-dynamic";
@@ -0,0 +1,3 @@
1
+ body {
2
+ margin: 0;
3
+ }
@@ -0,0 +1 @@
1
+ {"/":{"content":[{"type":"HeadingBlock","props":{"title":"Edit this page by adding /edit to the end of the URL","id":"HeadingBlock-1694032984497"}}],"root":{"props": {"title":""}}}}
@@ -0,0 +1,11 @@
1
+ import { Data } from "@puckeditor/core";
2
+ import fs from "fs";
3
+
4
+ // Replace with call to your database
5
+ export const getPage = (path: string) => {
6
+ const allData: Record<string, Data> | null = fs.existsSync("database.json")
7
+ ? JSON.parse(fs.readFileSync("database.json", "utf-8"))
8
+ : null;
9
+
10
+ return allData ? allData[path] : null;
11
+ };
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "vinext-recipe",
3
+ "version": "1.0.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vinext dev",
8
+ "build": "vinext build",
9
+ "start": "vinext start",
10
+ "lint": "eslint"
11
+ },
12
+ "dependencies": {
13
+ "@puckeditor/core": "workspace:*",
14
+ "classnames": "^2.3.2",
15
+ "react": "^19.2.6",
16
+ "react-dom": "^19.2.6",
17
+ "react-server-dom-webpack": "^19.2.6",
18
+ "vinext": "^1.0.0-beta.13"
19
+ },
20
+ "devDependencies": {
21
+ "@types/node": "^22.0.0",
22
+ "@types/react": "^19.2.7",
23
+ "@types/react-dom": "^19.2.3",
24
+ "@vitejs/plugin-react": "^6.0.0",
25
+ "@vitejs/plugin-rsc": "^0.5.34",
26
+ "eslint-config-custom": "workspace:*",
27
+ "typescript": "^5.5.4",
28
+ "vite": "^8.0.0"
29
+ }
30
+ }
@@ -0,0 +1,27 @@
1
+ import { NextResponse } from "next/server";
2
+
3
+ import type { NextRequest } from "next/server";
4
+
5
+ export async function proxy(req: NextRequest) {
6
+ const res = NextResponse.next({ request: req });
7
+
8
+ if (req.method === "GET") {
9
+ // Rewrite routes that match "/[...puckPath]/edit" to "/puck/[...puckPath]"
10
+ if (req.nextUrl.pathname.endsWith("/edit")) {
11
+ const pathWithoutEdit = req.nextUrl.pathname.slice(
12
+ 0,
13
+ req.nextUrl.pathname.length - 5
14
+ );
15
+ const pathWithEditPrefix = `/puck${pathWithoutEdit}`;
16
+
17
+ return NextResponse.rewrite(new URL(pathWithEditPrefix, req.url));
18
+ }
19
+
20
+ // Disable "/puck/[...puckPath]"
21
+ if (req.nextUrl.pathname.startsWith("/puck")) {
22
+ return NextResponse.redirect(new URL("/", req.url));
23
+ }
24
+ }
25
+
26
+ return res;
27
+ }
@@ -0,0 +1,25 @@
1
+ import type { Config } from "@puckeditor/core";
2
+
3
+ type Props = {
4
+ HeadingBlock: { title: string };
5
+ };
6
+
7
+ export const config: Config<Props> = {
8
+ components: {
9
+ HeadingBlock: {
10
+ fields: {
11
+ title: { type: "text" },
12
+ },
13
+ defaultProps: {
14
+ title: "Heading",
15
+ },
16
+ render: ({ title }) => (
17
+ <div style={{ padding: 64 }}>
18
+ <h1>{title}</h1>
19
+ </div>
20
+ ),
21
+ },
22
+ },
23
+ };
24
+
25
+ export default config;
@@ -0,0 +1,30 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "lib": [
5
+ "dom",
6
+ "dom.iterable",
7
+ "esnext"
8
+ ],
9
+ "module": "esnext",
10
+ "moduleResolution": "bundler",
11
+ "jsx": "react-jsx",
12
+ "strict": true,
13
+ "skipLibCheck": true,
14
+ "noEmit": true,
15
+ "esModuleInterop": true,
16
+ "resolveJsonModule": true,
17
+ "isolatedModules": true,
18
+ "types": [
19
+ "vinext/types"
20
+ ]
21
+ },
22
+ "include": [
23
+ "**/*.ts",
24
+ "**/*.tsx"
25
+ ],
26
+ "exclude": [
27
+ "node_modules",
28
+ "dist"
29
+ ]
30
+ }
@@ -0,0 +1,6 @@
1
+ import { defineConfig } from "vite";
2
+ import vinext from "vinext";
3
+
4
+ export default defineConfig({
5
+ plugins: [vinext()],
6
+ });
@@ -0,0 +1,169 @@
1
+ # Puck AI + vinext recipe
2
+
3
+ [Puck](https://puckeditor.com) is the open-source visual editor for React. It lets you create page builders that use your own components.
4
+
5
+ [Puck AI](https://puckeditor.com/docs/ai/overview) builds on the same principles to let you generate pages by assembling your existing components or creating new ones on the fly, either as a copilot in the editor or headlessly.
6
+
7
+ This recipe connects Puck and Puck AI to a [vinext](https://github.com/cloudflare/vinext) app, which runs the [Next.js App Router](https://nextjs.org/docs/app) API on Vite, so you can create and edit pages for any route in this app.
8
+
9
+ ## Core concepts
10
+
11
+ If you're new to Puck, this section introduces the core concepts you need to know.
12
+
13
+ ### Puck
14
+
15
+ The Puck visual editor has three main parts: a config, the editor, and the renderer.
16
+
17
+ #### Config
18
+
19
+ The [config](https://puckeditor.com/docs/integrating-puck/component-configuration) registers the components users can use to build pages in the editor and the fields they can edit.
20
+
21
+ ```tsx
22
+ const config = {
23
+ components: {
24
+ HeadingBlock: {
25
+ fields: {
26
+ title: { type: "text" },
27
+ },
28
+ render: ({ title }) => <h1>{title}</h1>,
29
+ },
30
+ },
31
+ };
32
+ ```
33
+
34
+ #### The editor
35
+
36
+ The [`<Puck>`](https://puckeditor.com/docs/api-reference/components/puck) component renders the editor. It uses a config, exports [pages as JSON](https://puckeditor.com/docs/api-reference/data-model/data), and accepts initial page data for editing existing pages.
37
+
38
+ ```tsx
39
+ <Puck
40
+ config={config} // The components available to the editor
41
+ data={data} // The page JSON to edit
42
+ onPublish={(data) => {
43
+ // Save data to your database
44
+ }}
45
+ />
46
+ ```
47
+
48
+ #### The renderer
49
+
50
+ The [`<Render>`](https://puckeditor.com/docs/api-reference/components/render) component renders pages. It expects the page JSON and the config used to create that page.
51
+
52
+ ```tsx
53
+ <Render
54
+ config={config} // The components used to create the page
55
+ data={data} // The page JSON to render
56
+ />
57
+ ```
58
+
59
+ ### Puck AI
60
+
61
+ This recipe adds Puck AI as a copilot. It has two parts: the AI plugin (browser) and the Cloud Client (server).
62
+
63
+ #### The AI plugin
64
+
65
+ The [AI plugin](https://puckeditor.com/docs/api-reference/ai/ai-plugin/installation) renders the chat in the editor and sends each message to the Cloud Client on your server.
66
+
67
+ ```tsx
68
+ const aiPlugin = createAiPlugin();
69
+
70
+ function Editor() {
71
+ return <Puck plugins={[aiPlugin]} config={config} data={data} />;
72
+ }
73
+ ```
74
+
75
+ #### The Cloud Client
76
+
77
+ The [Cloud Client](https://puckeditor.com/docs/api-reference/ai/cloud-client/installation) provides APIs for connecting your server to the Puck cloud. This recipe uses its [`puckHandler`](https://puckeditor.com/docs/api-reference/ai/cloud-client/puck-handler) API, which receives each chat message, forwards it to the Puck cloud, and streams the response back to the plugin in the browser.
78
+
79
+ ```ts
80
+ const handleRequest = (request: NextRequest) => {
81
+ return puckHandler(request, {
82
+ ai: {
83
+ context: "We are Google. You create Google landing pages.",
84
+ },
85
+ });
86
+ };
87
+
88
+ export const DELETE = handleRequest;
89
+ export const GET = handleRequest;
90
+ export const POST = handleRequest;
91
+ ```
92
+
93
+ #### Puck AI modes
94
+
95
+ Puck AI can build pages in two ways:
96
+
97
+ - **Assembly mode** only builds pages using components from your config.
98
+ - **Design mode** can generate new components when needed.
99
+
100
+ This recipe comes with [Design mode](https://puckeditor.com/docs/api-reference/ai/cloud-client/puck-handler#aidesignmode) enabled out of the box.
101
+
102
+ ## Run the recipe
103
+
104
+ ### 1. Add a Puck API key
105
+
106
+ Start by creating an account, [generating an API key](https://cloud.puckeditor.com/api-keys), and adding it to a `.env.local` file:
107
+
108
+ ```sh
109
+ PUCK_API_KEY=your-api-key
110
+ ```
111
+
112
+ ### 2. Start the development server
113
+
114
+ Run:
115
+
116
+ ```sh
117
+ npm run dev
118
+ ```
119
+
120
+ Once the server is running, navigate to [http://localhost:3000](http://localhost:3000) to view the home page, or [http://localhost:3000/edit](http://localhost:3000/edit) to edit it with Puck.
121
+
122
+ ### 3. Create a page with Puck AI
123
+
124
+ Navigate to [http://localhost:3000/edit](http://localhost:3000/edit), click the **AI** button in the left sidebar, enter a prompt, and press Enter.
125
+
126
+ ### 4. Publish the page
127
+
128
+ Once your page is ready, select **Publish** in the header to save the result, then navigate to [http://localhost:3000](http://localhost:3000) to view the published page.
129
+
130
+ You can also create a page at any path by navigating to `/your/path/edit` and publishing it. The route `/your/path` will render the page.
131
+
132
+ ## How it works
133
+
134
+ When a URL ends in `/edit`, [`proxy.ts`](https://nextjs.org/docs/app/api-reference/file-conventions/proxy) sends the request to the Puck editor route (`app/puck/[...puckPath]/page.tsx`). The editor loads the saved page, or starts with an empty page if the path is new.
135
+
136
+ Selecting **Publish** sends the page data to the `/api/pages` endpoint (`app/api/pages/route.ts`). The handler writes the JSON to `database.json` and clears the cached page. The catch-all route (`app/[...puckPath]/page.tsx`) then loads the same data and renders it with [`<Render>`](https://puckeditor.com/docs/api-reference/components/render).
137
+
138
+ The table below shows the files that implement this flow.
139
+
140
+ | File | Purpose |
141
+ | ----------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
142
+ | `puck.config.tsx` | Defines the components, fields, and default props available to Puck and Assembly mode. Add your own components here. |
143
+ | `app/puck/[...puckPath]/page.tsx` | Loads page data for the editor. |
144
+ | `app/puck/[...puckPath]/client.tsx` | Renders the editor with the AI copilot, sends prompts to your server, and publishes changes. |
145
+ | `app/[...puckPath]/page.tsx` | Loads and renders published pages. |
146
+ | `app/api/pages/route.ts` | Saves published pages. |
147
+ | `app/api/puck/[...all]/route.ts` | Handles requests from the AI plugin and configures AI generation. |
148
+ | `proxy.ts` | Routes URLs ending in `/edit` to `/puck/[...puckPath]/page.tsx`. |
149
+ | `lib/get-page.ts` | Reads page data from `database.json`. Replace this with your own data fetching logic. |
150
+ | `database.json` | Acts as a local database. Replace this with your own database solution. |
151
+
152
+ ## Before deploying to production
153
+
154
+ Before deploying this recipe, make sure to:
155
+
156
+ - **Protect the editor and APIs.** The `/edit`, `/api/pages`, and `/api/puck` routes are public by default. Add authentication, authorization, and rate limits to protect page data and AI usage.
157
+ - **Add your component library.** Replace the example `HeadingBlock` in `puck.config.tsx` with the components and fields your users need.
158
+ - **Set your business context.** Replace the example Google context in `app/api/puck/[...all]/route.ts` with clear information about your product, audience, and content rules.
159
+ - **Use a real database.** Replace `database.json` in `lib/get-page.ts` and `app/api/pages/route.ts`. Local files are not reliable across server instances, and aren't available on Cloudflare Workers.
160
+ - **Choose a rendering strategy.** `app/[...puckPath]/page.tsx` uses `force-static`. Remove it if a page needs request-time data such as headers, cookies, or user sessions.
161
+
162
+ ## Learn more
163
+
164
+ - [Puck documentation](https://puckeditor.com/docs)
165
+ - [Getting started with Puck](https://puckeditor.com/docs/getting-started)
166
+ - [Integrating Puck](https://puckeditor.com/docs/integrating-puck/component-configuration)
167
+ - [Puck AI documentation](https://puckeditor.com/docs/ai/overview)
168
+ - [Getting started with Puck AI](https://puckeditor.com/docs/ai/getting-started)
169
+ - [Puck Discord](https://discord.gg/D9e4E3MQVZ)