@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,57 @@
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 "@puckeditor/plugin-ai/styles.css";
16
+ import type { Data } from "@puckeditor/core";
17
+ import { Metadata } from "next";
18
+ import { Client } from "./client";
19
+ import { getPage } from "../../../lib/get-page";
20
+
21
+ // Empty data for new pages
22
+ const EMPTY_PAGE_DATA: Data = {
23
+ content: [],
24
+ root: {
25
+ props: {
26
+ title: "",
27
+ },
28
+ },
29
+ };
30
+
31
+ export async function generateMetadata({
32
+ params,
33
+ }: {
34
+ params: Promise<{ puckPath: string[] }>;
35
+ }): Promise<Metadata> {
36
+ const { puckPath = [] } = await params;
37
+ const path = `/${puckPath.join("/")}`;
38
+
39
+ return {
40
+ title: "Puck: " + path,
41
+ };
42
+ }
43
+
44
+ export default async function Page({
45
+ params,
46
+ }: {
47
+ params: Promise<{ puckPath: string[] }>;
48
+ }) {
49
+ const { puckPath = [] } = await params;
50
+ const path = `/${puckPath.join("/")}`;
51
+
52
+ const data = getPage(path);
53
+
54
+ return <Client path={path} data={data || EMPTY_PAGE_DATA} />;
55
+ }
56
+
57
+ export const dynamic = "force-dynamic";
@@ -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 a 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,3 @@
1
+ module.exports = {
2
+ reactStrictMode: true,
3
+ };
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "next-ai-recipe",
3
+ "version": "1.0.0",
4
+ "private": true,
5
+ "scripts": {
6
+ "dev": "next dev --turbo",
7
+ "build": "next build",
8
+ "start": "next start",
9
+ "lint": "eslint"
10
+ },
11
+ "dependencies": {
12
+ "@puckeditor/cloud-client": "^0",
13
+ "@puckeditor/core": "workspace:*",
14
+ "@puckeditor/plugin-ai": "^0",
15
+ "classnames": "^2.3.2",
16
+ "next": "^16.2.11",
17
+ "react": "^19.2.1",
18
+ "react-dom": "^19.2.1"
19
+ },
20
+ "devDependencies": {
21
+ "@types/node": "^17.0.12",
22
+ "@types/react": "^19.2.7",
23
+ "@types/react-dom": "^19.2.3",
24
+ "eslint-config-custom": "workspace:*",
25
+ "typescript": "^5.5.4"
26
+ }
27
+ }
@@ -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,20 @@
1
+ {
2
+ "$schema": "https://json.schemastore.org/tsconfig",
3
+ "display": "Default",
4
+ "compilerOptions": {
5
+ "composite": false,
6
+ "declaration": true,
7
+ "declarationMap": true,
8
+ "esModuleInterop": true,
9
+ "forceConsistentCasingInFileNames": true,
10
+ "inlineSources": false,
11
+ "isolatedModules": true,
12
+ "moduleResolution": "node",
13
+ "noUnusedLocals": false,
14
+ "noUnusedParameters": false,
15
+ "preserveWatchOutput": true,
16
+ "skipLibCheck": true,
17
+ "strict": true
18
+ },
19
+ "exclude": ["node_modules"]
20
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "$schema": "https://json.schemastore.org/tsconfig",
3
+ "display": "Next.js",
4
+ "extends": "./base.json",
5
+ "compilerOptions": {
6
+ "plugins": [{ "name": "next" }],
7
+ "allowJs": true,
8
+ "declaration": false,
9
+ "declarationMap": false,
10
+ "incremental": true,
11
+ "jsx": "preserve",
12
+ "lib": ["dom", "dom.iterable", "esnext"],
13
+ "module": "esnext",
14
+ "noEmit": true,
15
+ "resolveJsonModule": true,
16
+ "strict": false,
17
+ "target": "es5"
18
+ },
19
+ "include": ["src", "next-env.d.ts"],
20
+ "exclude": ["node_modules"]
21
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "extends": "./tsconfig/nextjs.json",
3
+ "compilerOptions": {
4
+ "plugins": [{ "name": "next" }]
5
+ },
6
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
7
+ "exclude": ["node_modules"]
8
+ }
@@ -0,0 +1,113 @@
1
+ # Puck + React Router recipe
2
+
3
+ [Puck](https://puckeditor.com) is the open-source visual editor for React.
4
+
5
+ This recipe connects Puck to [React Router](https://reactrouter.com) in framework mode, 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:5173](http://localhost:5173) to view the home page, or [http://localhost:5173/edit](http://localhost:5173/edit) to edit it with Puck.
68
+
69
+ ### 2. Create a page
70
+
71
+ Navigate to [http://localhost:5173/edit](http://localhost:5173/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:5173](http://localhost:5173) 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`, `resolvePuckPath` (`app/lib/resolve-puck-path.server.ts`) returns the path of the page being edited. The loader in `app/routes/puck-splat.tsx` 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 action in `app/routes/puck-splat.tsx`. The action writes the JSON to `database.json`. The route 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/routes.ts` | Registers the home page and catch-all page route. |
91
+ | `app/routes/puck-splat.tsx` | Loads and saves page data, then renders the editor or published page. |
92
+ | `app/routes/_index.tsx` | Loads and renders the home page. |
93
+ | `app/lib/resolve-puck-path.server.ts` | Maps an `/edit` URL to the path of the page being edited. |
94
+ | `app/lib/pages.server.ts` | Reads and writes page data in `database.json`. Replace this with your own data fetching and saving logic. |
95
+ | `app/components/puck-render.tsx` | Renders saved page data with `<Render>`. |
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 publishing.** The `/edit` routes and publish action 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` and the functions in `app/lib/pages.server.ts`. Local files are not reliable across server instances or serverless deployments.
105
+ - **Choose a deployment strategy.** This recipe uses server-side rendering, loaders, and actions. Deploy it to a React Router-compatible server runtime.
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
+ - [React Router framework mode](https://reactrouter.com/start/framework/installation)
113
+ - [Puck Discord](https://discord.gg/D9e4E3MQVZ)
@@ -0,0 +1,6 @@
1
+ .DS_Store
2
+ /node_modules/
3
+
4
+ # React Router
5
+ /.react-router/
6
+ /build/
@@ -0,0 +1,8 @@
1
+ import type { Data } from "@puckeditor/core";
2
+ import { Render } from "@puckeditor/core";
3
+
4
+ import { config } from "../../puck.config";
5
+
6
+ export function PuckRender({ data }: { data: Data }) {
7
+ return <Render config={config} data={data} />;
8
+ }
@@ -0,0 +1,29 @@
1
+ import path from "path";
2
+ import { fileURLToPath } from "url";
3
+ import fs from "fs/promises";
4
+ import type { Data } from "@puckeditor/core";
5
+
6
+ const __filename = fileURLToPath(import.meta.url);
7
+ const __dirname = path.dirname(__filename);
8
+ const databasePath = path.join(__dirname, "..", "..", "database.json");
9
+
10
+ export async function getPage(path: string) {
11
+ const pages = await readDatabase();
12
+ return pages[path];
13
+ }
14
+
15
+ export async function savePage(path: string, data: Data) {
16
+ const pages = await readDatabase();
17
+ pages[path] = data;
18
+ await fs.writeFile(databasePath, JSON.stringify(pages), { encoding: "utf8" });
19
+ }
20
+
21
+ async function readDatabase() {
22
+ try {
23
+ const file = await fs.readFile(databasePath, "utf8");
24
+ return JSON.parse(file) as Record<string, Data>;
25
+ } catch (error: unknown) {
26
+ console.error(error);
27
+ return {};
28
+ }
29
+ }
@@ -0,0 +1,19 @@
1
+ export function resolvePuckPath(
2
+ path = "",
3
+ // `base` can be any valid origin, it is required for the URL constructor so
4
+ // we can return a pathname - you can change this if you want, but it isn't
5
+ // important
6
+ base = "https://placeholder.com/"
7
+ ) {
8
+ const url = new URL(path, base);
9
+ const segments = url.pathname.split("/");
10
+ const isEditorRoute = segments.at(-1) === "edit";
11
+ const pathname = isEditorRoute
12
+ ? segments.slice(0, -1).join("/")
13
+ : url.pathname;
14
+
15
+ return {
16
+ isEditorRoute,
17
+ path: new URL(pathname, base).pathname,
18
+ };
19
+ }
@@ -0,0 +1,65 @@
1
+ import {
2
+ isRouteErrorResponse,
3
+ Links,
4
+ Meta,
5
+ Outlet,
6
+ Scripts,
7
+ ScrollRestoration,
8
+ } from "react-router";
9
+
10
+ import type { Route } from "./+types/root";
11
+
12
+ export function Layout({ children }: { children: React.ReactNode }) {
13
+ return (
14
+ <html lang="en">
15
+ <head>
16
+ <meta charSet="utf-8" />
17
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
18
+ <Meta />
19
+ <Links />
20
+ </head>
21
+ <body>
22
+ {children}
23
+ <ScrollRestoration />
24
+ <Scripts />
25
+ </body>
26
+ </html>
27
+ );
28
+ }
29
+
30
+ export default function App() {
31
+ return <Outlet />;
32
+ }
33
+
34
+ export function ErrorBoundary({ error }: Route.ErrorBoundaryProps) {
35
+ let message = "Oops!";
36
+ let details = "An unexpected error occurred.";
37
+ let stack: string | undefined;
38
+
39
+ if (isRouteErrorResponse(error)) {
40
+ message = error.status === 404 ? "404" : "Error";
41
+ details =
42
+ error.status === 404
43
+ ? "The requested page could not be found."
44
+ : error.statusText || details;
45
+ } else if (
46
+ import.meta.env.NODE_ENV !== "production" &&
47
+ error &&
48
+ error instanceof Error
49
+ ) {
50
+ details = error.message;
51
+ stack = error.stack;
52
+ }
53
+
54
+ return (
55
+ <main>
56
+ <h1>{message}</h1>
57
+ <p>{details}</p>
58
+ {stack && (
59
+ <pre>
60
+ <code>{stack}</code>
61
+ </pre>
62
+ )}
63
+ </main>
64
+ );
65
+ }
@@ -0,0 +1,31 @@
1
+ import type { Route } from "./+types/_index";
2
+ import { PuckRender } from "~/components/puck-render";
3
+ import { resolvePuckPath } from "~/lib/resolve-puck-path.server";
4
+ import { getPage } from "~/lib/pages.server";
5
+
6
+ export async function loader() {
7
+ const { isEditorRoute, path } = resolvePuckPath("/");
8
+ let page = await getPage(path);
9
+
10
+ if (!page) {
11
+ throw new Response("Not Found", { status: 404 });
12
+ }
13
+
14
+ return {
15
+ isEditorRoute,
16
+ path,
17
+ data: page,
18
+ };
19
+ }
20
+
21
+ export function meta({ loaderData }: Route.MetaArgs) {
22
+ return [
23
+ {
24
+ title: loaderData.data.root.props?.title ?? "",
25
+ },
26
+ ];
27
+ }
28
+
29
+ export default function PuckSplatRoute({ loaderData }: Route.ComponentProps) {
30
+ return <PuckRender data={loaderData.data} />;
31
+ }
@@ -0,0 +1,95 @@
1
+ import { useFetcher, useLoaderData } from "react-router";
2
+ import type { Data } from "@puckeditor/core";
3
+ import { Puck, Render } from "@puckeditor/core";
4
+
5
+ import type { Route } from "./+types/puck-splat";
6
+ import { config } from "../../puck.config";
7
+ import { resolvePuckPath } from "~/lib/resolve-puck-path.server";
8
+ import { getPage, savePage } from "~/lib/pages.server";
9
+ import editorStyles from "@puckeditor/core/puck.css?url";
10
+
11
+ export async function loader({ params }: Route.LoaderArgs) {
12
+ const pathname = params["*"] ?? "/";
13
+ const { isEditorRoute, path } = resolvePuckPath(pathname);
14
+ let page = await getPage(path);
15
+
16
+ // Throw a 404 if we're not rendering the editor and data for the page does not exist
17
+ if (!isEditorRoute && !page) {
18
+ throw new Response("Not Found", { status: 404 });
19
+ }
20
+
21
+ // Empty shell for new pages
22
+ if (isEditorRoute && !page) {
23
+ page = {
24
+ content: [],
25
+ root: {
26
+ props: {
27
+ title: "",
28
+ },
29
+ },
30
+ };
31
+ }
32
+
33
+ return {
34
+ isEditorRoute,
35
+ path,
36
+ data: page,
37
+ };
38
+ }
39
+
40
+ export function meta({ loaderData }: Route.MetaArgs) {
41
+ return [
42
+ {
43
+ title: loaderData.isEditorRoute
44
+ ? `Edit: ${loaderData.path}`
45
+ : loaderData.data.root.props?.title ?? "",
46
+ },
47
+ ];
48
+ }
49
+
50
+ export async function action({ params, request }: Route.ActionArgs) {
51
+ const pathname = params["*"] ?? "/";
52
+ const { path } = resolvePuckPath(pathname);
53
+ const body = (await request.json()) as { data: Data };
54
+
55
+ await savePage(path, body.data);
56
+ }
57
+
58
+ function Editor() {
59
+ const loaderData = useLoaderData<typeof loader>();
60
+ const fetcher = useFetcher<typeof action>();
61
+
62
+ return (
63
+ <>
64
+ <link rel="stylesheet" href={editorStyles} id="puck-css" />
65
+ <Puck
66
+ config={config}
67
+ data={loaderData.data}
68
+ onPublish={async (data) => {
69
+ await fetcher.submit(
70
+ {
71
+ data,
72
+ },
73
+ {
74
+ action: "",
75
+ method: "post",
76
+ encType: "application/json",
77
+ }
78
+ );
79
+ }}
80
+ />
81
+ </>
82
+ );
83
+ }
84
+
85
+ export default function PuckSplatRoute({ loaderData }: Route.ComponentProps) {
86
+ return (
87
+ <div>
88
+ {loaderData.isEditorRoute ? (
89
+ <Editor />
90
+ ) : (
91
+ <Render config={config} data={loaderData.data} />
92
+ )}
93
+ </div>
94
+ );
95
+ }
@@ -0,0 +1,7 @@
1
+ import type { RouteConfig } from "@react-router/dev/routes";
2
+ import { route, index } from "@react-router/dev/routes";
3
+
4
+ export default [
5
+ index("routes/_index.tsx"),
6
+ route("*", "routes/puck-splat.tsx"),
7
+ ] satisfies RouteConfig;
@@ -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":"Puck + React Router 7 demo"}},"zones":{}}}
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "react-router-recipe",
3
+ "private": true,
4
+ "type": "module",
5
+ "version": "1.0.0",
6
+ "scripts": {
7
+ "build": "react-router build",
8
+ "dev": "react-router dev",
9
+ "start": "react-router-serve ./build/server/index.js",
10
+ "typecheck": "react-router typegen && tsc"
11
+ },
12
+ "dependencies": {
13
+ "@puckeditor/core": "workspace:*",
14
+ "@react-router/node": "^7.18.0",
15
+ "@react-router/serve": "^7.18.0",
16
+ "isbot": "^5",
17
+ "react": "^19.0.0",
18
+ "react-dom": "^19.0.0",
19
+ "react-router": "^7.18.0"
20
+ },
21
+ "devDependencies": {
22
+ "@react-router/dev": "^7.18.0",
23
+ "@types/node": "^20",
24
+ "@types/react": "^19.0.1",
25
+ "@types/react-dom": "^19.0.2",
26
+ "typescript": "^5.8.3",
27
+ "vite": "^7.3.2",
28
+ "vite-tsconfig-paths": "^5.1.4"
29
+ },
30
+ "engines": {
31
+ "node": ">=20.0.0"
32
+ }
33
+ }
@@ -0,0 +1,23 @@
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
+ };