@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,28 @@
1
+ import { useEffect, useState } from "react";
2
+ import type { Data } from "@puckeditor/core";
3
+ import { Puck } from "@puckeditor/core";
4
+ import "@puckeditor/core/puck.css";
5
+
6
+ import { config } from "../puck.config";
7
+ import { loadPage, savePage } from "./pages";
8
+
9
+ // Empty shell for new pages
10
+ const emptyPage: Data = { content: [], root: { props: { title: "" } } };
11
+
12
+ export default function Editor({ path }: { path: string }) {
13
+ const [data, setData] = useState<Data | null>(null);
14
+
15
+ useEffect(() => {
16
+ loadPage(path).then((page) => setData(page ?? emptyPage));
17
+ }, [path]);
18
+
19
+ if (!data) return null;
20
+
21
+ return (
22
+ <Puck
23
+ config={config}
24
+ data={data}
25
+ onPublish={(data) => savePage(path, data)}
26
+ />
27
+ );
28
+ }
@@ -0,0 +1,27 @@
1
+ import { useEffect, useState } from "react";
2
+ import type { ReactNode } from "react";
3
+ import type { Data } from "@puckeditor/core";
4
+ import { Render } from "@puckeditor/core";
5
+
6
+ import { config } from "../puck.config";
7
+ import { loadPage } from "./pages";
8
+
9
+ /** Renders the published Puck page for a path, or `fallback` if there isn't one */
10
+ export function PuckPage({
11
+ path,
12
+ fallback = null,
13
+ }: {
14
+ path: string;
15
+ fallback?: ReactNode;
16
+ }) {
17
+ const [data, setData] = useState<Data | null>();
18
+
19
+ useEffect(() => {
20
+ loadPage(path).then(setData);
21
+ }, [path]);
22
+
23
+ if (data === undefined) return null;
24
+ if (data === null) return fallback;
25
+
26
+ return <Render config={config} data={data} />;
27
+ }
@@ -0,0 +1,15 @@
1
+ import type { Data } from "@puckeditor/core";
2
+
3
+ // Loads and saves pages with the pages API in server/puck/pages.ts
4
+ export const loadPage = async (path: string): Promise<Data | null> => {
5
+ const response = await fetch(`/api/pages?path=${encodeURIComponent(path)}`);
6
+ return response.ok ? response.json() : null;
7
+ };
8
+
9
+ export const savePage = async (path: string, data: Data) => {
10
+ await fetch("/api/pages", {
11
+ method: "POST",
12
+ headers: { "Content-Type": "application/json" },
13
+ body: JSON.stringify({ path, data }),
14
+ });
15
+ };
@@ -0,0 +1,27 @@
1
+ import { lazy, Suspense } from "react";
2
+ import type { ReactNode } from "react";
3
+
4
+ // Loaded only when editing, so the editor stays out of your app's bundle
5
+ const Editor = lazy(() => import("./editor"));
6
+
7
+ /** The path being edited for URLs ending in /edit, e.g. /about/edit */
8
+ export const editorPath = (pathname: string) => {
9
+ const segments = pathname.split("/");
10
+ if (segments.at(-1) !== "edit") return null;
11
+ return segments.slice(0, -1).join("/") || "/";
12
+ };
13
+
14
+ /** Renders the Puck editor at /edit URLs, and your app everywhere else */
15
+ export function PuckRoot({ children }: { children: ReactNode }) {
16
+ const path = editorPath(window.location.pathname);
17
+ if (path === null) return children;
18
+
19
+ return (
20
+ // Fill the window, whatever layout styles your app gives its root
21
+ <div style={{ position: "fixed", inset: 0, textAlign: "initial" }}>
22
+ <Suspense>
23
+ <Editor path={path} />
24
+ </Suspense>
25
+ </div>
26
+ );
27
+ }
@@ -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
+ };
@@ -0,0 +1,26 @@
1
+ {
2
+ "compilerOptions": {
3
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
4
+ "target": "es2023",
5
+ "lib": ["ES2023", "DOM"],
6
+ "module": "esnext",
7
+ "types": ["vite/client"],
8
+ "allowArbitraryExtensions": true,
9
+ "skipLibCheck": true,
10
+
11
+ /* Bundler mode */
12
+ "moduleResolution": "bundler",
13
+ "allowImportingTsExtensions": true,
14
+ "verbatimModuleSyntax": true,
15
+ "moduleDetection": "force",
16
+ "noEmit": true,
17
+ "jsx": "react-jsx",
18
+
19
+ /* Linting */
20
+ "noUnusedLocals": true,
21
+ "noUnusedParameters": true,
22
+ "erasableSyntaxOnly": true,
23
+ "noFallthroughCasesInSwitch": true
24
+ },
25
+ "include": ["src"]
26
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "files": [],
3
+ "references": [
4
+ { "path": "./tsconfig.app.json" },
5
+ { "path": "./tsconfig.node.json" }
6
+ ]
7
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "compilerOptions": {
3
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
4
+ "target": "es2023",
5
+ "lib": ["ES2023"],
6
+ "types": ["node"],
7
+ "skipLibCheck": true,
8
+
9
+ /* Bundler mode */
10
+ "module": "nodenext",
11
+ "allowImportingTsExtensions": true,
12
+ "verbatimModuleSyntax": true,
13
+ "moduleDetection": "force",
14
+ "noEmit": true,
15
+
16
+ /* Linting */
17
+ "noUnusedLocals": true,
18
+ "noUnusedParameters": true,
19
+ "erasableSyntaxOnly": true,
20
+ "noFallthroughCasesInSwitch": true
21
+ },
22
+ "include": ["vite.config.ts", "server"]
23
+ }
@@ -0,0 +1,14 @@
1
+ import react from "@vitejs/plugin-react";
2
+ import { defineConfig } from "vite";
3
+ import devServer from "@hono/vite-dev-server";
4
+
5
+ // https://vite.dev/config/
6
+ export default defineConfig({
7
+ plugins: [
8
+ react(),
9
+ devServer({ entry: "server/index.ts", exclude: [/^(?!\/api\/).*/] }),
10
+ ],
11
+ optimizeDeps: {
12
+ include: ["@puckeditor/core"],
13
+ },
14
+ });
@@ -0,0 +1,67 @@
1
+ # Puck AI + Vite recipe
2
+
3
+ [Puck](https://puckeditor.com) is the open-source visual editor for React.
4
+
5
+ This recipe adds Puck and Puck AI to a [Vite](https://vite.dev) React app. A small [Hono](https://hono.dev) server in `server/` stores pages and serves Puck AI. Vite runs it in development with [`@hono/vite-dev-server`](https://github.com/honojs/vite-plugins/tree/main/packages/dev-server), and `npm start` serves it with the built app in production.
6
+
7
+ ## Run the recipe
8
+
9
+ ### 1. Add a Puck API key
10
+
11
+ Start by creating an account, [generating an API key](https://cloud.puckeditor.com/api-keys), and adding it to an `.env.local` file:
12
+
13
+ ```sh
14
+ PUCK_API_KEY=your-api-key
15
+ ```
16
+
17
+ ### 2. Start the development server
18
+
19
+ Run:
20
+
21
+ ```sh
22
+ npm run dev
23
+ ```
24
+
25
+ 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.
26
+
27
+ ### 3. Publish a page
28
+
29
+ Click the **AI** button in the left sidebar, enter a prompt, and press Enter. Once your page is ready, select **Publish** in the header to save it, then navigate to [http://localhost:5173](http://localhost:5173) to view it.
30
+
31
+ You can also create a page at any path by navigating to `/your/path/edit` and publishing it.
32
+
33
+ ## How it works
34
+
35
+ `PuckRoot` (`src/puck/root.tsx`) wraps the app in `src/main.tsx`. When a URL ends in `/edit`, it renders the editor for that path instead of the app. The editor is loaded on demand, so it stays out of the app's bundle.
36
+
37
+ Selecting **Publish** sends the page to `POST /api/pages`, which writes it to `database.json`. `<PuckPage>` (`src/puck/page.tsx`) loads a published page from `GET /api/pages` and renders it with [`<Render>`](https://puckeditor.com/docs/api-reference/components/render). Put it wherever your app renders pages; this recipe's `App` renders it for every URL.
38
+
39
+ | File | Purpose |
40
+ | ---------------------- | -------------------------------------------------------------------------------------------------- |
41
+ | `src/puck.config.tsx` | Defines the components, fields, and default props available to Puck. Add your own components here. |
42
+ | `src/puck/root.tsx` | Renders the editor at `/edit` URLs, and your app everywhere else. |
43
+ | `src/puck/editor.tsx` | Loads the page being edited and publishes changes. |
44
+ | `src/puck/page.tsx` | Loads and renders a published page. |
45
+ | `src/puck/pages.ts` | Calls the pages API. |
46
+ | `server/index.ts` | The Hono app serving Puck's APIs. |
47
+ | `server/puck/pages.ts` | Reads and writes page data in `database.json`. Replace this with your own database. |
48
+ | `server/puck/cloud.ts` | Handles requests from the AI plugin and configures AI generation. |
49
+ | `server/prod.ts` | Serves the built app and the APIs in production. |
50
+ | `database.json` | Acts as a local database. Replace this with your own database solution. |
51
+
52
+ ## Before deploying to production
53
+
54
+ Before deploying this recipe, make sure to:
55
+
56
+ - **Protect the editor and APIs.** The `/edit` routes and `/api/pages` and `/api/puck` routes are public by default. Add authentication, authorization, and rate limits.
57
+ - **Add your component library.** Replace the example `HeadingBlock` in `src/puck.config.tsx` with the components and fields your users need.
58
+ - **Set your business context.** Replace the example Google context in `server/puck/cloud.ts` with clear information about your product, audience, and content rules.
59
+ - **Use a real database.** Replace `database.json` and `server/puck/pages.ts`. Local files are not reliable across server instances or serverless deployments.
60
+
61
+ ## Learn more
62
+
63
+ - [Puck documentation](https://puckeditor.com/docs)
64
+ - [Integrating Puck](https://puckeditor.com/docs/integrating-puck/component-configuration)
65
+ - [Puck AI documentation](https://puckeditor.com/docs/ai/overview)
66
+ - [Vite](https://vite.dev)
67
+ - [Puck Discord](https://discord.gg/D9e4E3MQVZ)
@@ -0,0 +1,24 @@
1
+ # Logs
2
+ logs
3
+ *.log
4
+ npm-debug.log*
5
+ yarn-debug.log*
6
+ yarn-error.log*
7
+ pnpm-debug.log*
8
+ lerna-debug.log*
9
+
10
+ node_modules
11
+ dist
12
+ dist-ssr
13
+ *.local
14
+
15
+ # Editor directories and files
16
+ .vscode/*
17
+ !.vscode/extensions.json
18
+ .idea
19
+ .DS_Store
20
+ *.suo
21
+ *.ntvs*
22
+ *.njsproj
23
+ *.sln
24
+ *.sw?
@@ -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,12 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Puck + Vite</title>
7
+ </head>
8
+ <body>
9
+ <div id="root"></div>
10
+ <script type="module" src="/src/main.tsx"></script>
11
+ </body>
12
+ </html>
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "vite-ai-recipe",
3
+ "version": "1.0.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vite",
8
+ "build": "tsc -b && vite build",
9
+ "preview": "vite preview",
10
+ "start": "tsx server/prod.ts"
11
+ },
12
+ "dependencies": {
13
+ "@hono/node-server": "^2.1.1",
14
+ "@puckeditor/cloud-client": "^0",
15
+ "@puckeditor/core": "workspace:*",
16
+ "@puckeditor/plugin-ai": "^0",
17
+ "hono": "^4.13.9",
18
+ "react": "^19.2.0",
19
+ "react-dom": "^19.2.0"
20
+ },
21
+ "devDependencies": {
22
+ "@hono/vite-dev-server": "^0.26.1",
23
+ "@types/node": "^22.10.2",
24
+ "@types/react": "^19.2.0",
25
+ "@types/react-dom": "^19.2.0",
26
+ "@vitejs/plugin-react": "^6.0.1",
27
+ "tsx": "^4.23.0",
28
+ "typescript": "^5.9.3",
29
+ "vite": "^8.0.0"
30
+ }
31
+ }
@@ -0,0 +1,15 @@
1
+ // Puck's APIs, served by Vite in development and by server/prod.ts in production
2
+ import fs from "node:fs";
3
+ import { Hono } from "hono";
4
+ import { puckPages } from "./puck/pages.js";
5
+ import { puckCloud } from "./puck/cloud.js";
6
+
7
+ // Vite doesn't give server code .env.local, which holds PUCK_API_KEY
8
+ if (fs.existsSync(".env.local")) process.loadEnvFile(".env.local");
9
+
10
+ const app = new Hono();
11
+
12
+ app.route("/", puckPages);
13
+ app.route("/", puckCloud);
14
+
15
+ export default app;
@@ -0,0 +1,18 @@
1
+ // Serves the built app and Puck's APIs in production
2
+ import { serve } from "@hono/node-server";
3
+ import { serveStatic } from "@hono/node-server/serve-static";
4
+ import { Hono } from "hono";
5
+ import api from "./index.js";
6
+
7
+ const app = new Hono();
8
+
9
+ app.route("/", api);
10
+ app.use("/*", serveStatic({ root: "./dist" }));
11
+ // Every other path loads the app, which decides what to render
12
+ app.get("*", serveStatic({ path: "./dist/index.html" }));
13
+
14
+ const port = Number(process.env.PORT ?? 3000);
15
+
16
+ serve({ fetch: app.fetch, port }, () => {
17
+ console.log(`Server is running on http://localhost:${port}`);
18
+ });
@@ -0,0 +1,30 @@
1
+ // Handles all requests for Puck AI
2
+ // Learn more: https://puckeditor.com/docs/ai/getting-started
3
+ import { Hono } from "hono";
4
+ import type { PuckCloudOptions } from "@puckeditor/cloud-client";
5
+ import { puckHandler } from "@puckeditor/cloud-client";
6
+
7
+ const options: PuckCloudOptions = {
8
+ ai: {
9
+ // Replace with your business context
10
+ context: "We are Google. You create Google landing pages.",
11
+ designMode: {
12
+ // Allow AI to generate new components using "design mode"
13
+ // Learn more: https://puckeditor.com/docs/ai/design-mode
14
+ allowed: true,
15
+ // Constrain component generation, replace with your own instructions
16
+ instructions: `
17
+ #### Color Palette
18
+
19
+ Always use the following colors:
20
+
21
+ * Primary: \`#1976d2\`
22
+ * Secondary: \`#9c27b0\`
23
+ `,
24
+ },
25
+ },
26
+ };
27
+
28
+ export const puckCloud = new Hono().all("/api/puck/*", (c) =>
29
+ puckHandler(c.req.raw, options)
30
+ );
@@ -0,0 +1,32 @@
1
+ // Loads and saves Puck pages for the editor
2
+ // Learn more: https://puckeditor.com/docs/cli
3
+ import fs from "node:fs/promises";
4
+ import { Hono } from "hono";
5
+
6
+ // Replace this with your own database
7
+ const databasePath = "database.json";
8
+
9
+ const readPages = async (): Promise<Record<string, unknown>> => {
10
+ try {
11
+ return JSON.parse(await fs.readFile(databasePath, "utf-8"));
12
+ } catch {
13
+ return {};
14
+ }
15
+ };
16
+
17
+ export const puckPages = new Hono()
18
+ .get("/api/pages", async (c) => {
19
+ const pages = await readPages();
20
+ const page = pages[c.req.query("path") ?? "/"];
21
+
22
+ return page ? c.json(page) : c.json({ error: "Not found" }, 404);
23
+ })
24
+ .post("/api/pages", async (c) => {
25
+ const { path, data } = await c.req.json();
26
+ const pages = await readPages();
27
+
28
+ pages[path] = data;
29
+ await fs.writeFile(databasePath, JSON.stringify(pages));
30
+
31
+ return c.json({ status: "ok" });
32
+ });
@@ -0,0 +1,11 @@
1
+ import { PuckPage } from "./puck/page";
2
+
3
+ // Renders the Puck page published at this URL
4
+ export default function App() {
5
+ return (
6
+ <PuckPage
7
+ path={window.location.pathname}
8
+ fallback={<h1>Page not found</h1>}
9
+ />
10
+ );
11
+ }
@@ -0,0 +1,12 @@
1
+ import { StrictMode } from "react";
2
+ import { createRoot } from "react-dom/client";
3
+ import App from "./App.tsx";
4
+ import { PuckRoot } from "./puck/root";
5
+
6
+ createRoot(document.getElementById("root")!).render(
7
+ <StrictMode>
8
+ <PuckRoot>
9
+ <App />
10
+ </PuckRoot>
11
+ </StrictMode>
12
+ );
@@ -0,0 +1,49 @@
1
+ import { useEffect, useMemo, useState } from "react";
2
+ import type { Data } from "@puckeditor/core";
3
+ import { Puck, blocksPlugin, outlinePlugin } from "@puckeditor/core";
4
+ import { createAiPlugin, withDynamicConfig } from "@puckeditor/plugin-ai";
5
+ import "@puckeditor/core/puck.css";
6
+ import "@puckeditor/plugin-ai/styles.css";
7
+
8
+ import { config } from "../puck.config";
9
+ import { loadPage, savePage } from "./pages";
10
+
11
+ const aiPlugin = createAiPlugin({
12
+ // Allow users to switch between design and assembly mode.
13
+ // Read more: https://puckeditor.com/docs/ai/design-mode
14
+ designMode: {
15
+ visible: true,
16
+ },
17
+ // Select design mode by default.
18
+ defaultMode: "design",
19
+ });
20
+
21
+ // Place the ai plugin in the first position in the side nav.
22
+ const plugins = [aiPlugin, blocksPlugin(), outlinePlugin()];
23
+
24
+ // Empty shell for new pages
25
+ const emptyPage: Data = { content: [], root: { props: { title: "" } } };
26
+
27
+ export default function Editor({ path }: { path: string }) {
28
+ const [data, setData] = useState<Data | null>(null);
29
+
30
+ useEffect(() => {
31
+ loadPage(path).then((page) => setData(page ?? emptyPage));
32
+ }, [path]);
33
+
34
+ const configWithDesignedComponents = useMemo(
35
+ () => (data ? withDynamicConfig(config, data) : config),
36
+ [data]
37
+ );
38
+
39
+ if (!data) return null;
40
+
41
+ return (
42
+ <Puck
43
+ plugins={plugins}
44
+ config={configWithDesignedComponents}
45
+ data={data}
46
+ onPublish={(data) => savePage(path, data)}
47
+ />
48
+ );
49
+ }
@@ -0,0 +1,28 @@
1
+ import { useEffect, useState } from "react";
2
+ import type { ReactNode } from "react";
3
+ import type { Data } from "@puckeditor/core";
4
+ import { Render } from "@puckeditor/core";
5
+ import { withDynamicConfig } from "@puckeditor/plugin-ai";
6
+
7
+ import { config } from "../puck.config";
8
+ import { loadPage } from "./pages";
9
+
10
+ /** Renders the published Puck page for a path, or `fallback` if there isn't one */
11
+ export function PuckPage({
12
+ path,
13
+ fallback = null,
14
+ }: {
15
+ path: string;
16
+ fallback?: ReactNode;
17
+ }) {
18
+ const [data, setData] = useState<Data | null>();
19
+
20
+ useEffect(() => {
21
+ loadPage(path).then(setData);
22
+ }, [path]);
23
+
24
+ if (data === undefined) return null;
25
+ if (data === null) return fallback;
26
+
27
+ return <Render config={withDynamicConfig(config, data)} data={data} />;
28
+ }
@@ -0,0 +1,15 @@
1
+ import type { Data } from "@puckeditor/core";
2
+
3
+ // Loads and saves pages with the pages API in server/puck/pages.ts
4
+ export const loadPage = async (path: string): Promise<Data | null> => {
5
+ const response = await fetch(`/api/pages?path=${encodeURIComponent(path)}`);
6
+ return response.ok ? response.json() : null;
7
+ };
8
+
9
+ export const savePage = async (path: string, data: Data) => {
10
+ await fetch("/api/pages", {
11
+ method: "POST",
12
+ headers: { "Content-Type": "application/json" },
13
+ body: JSON.stringify({ path, data }),
14
+ });
15
+ };
@@ -0,0 +1,27 @@
1
+ import { lazy, Suspense } from "react";
2
+ import type { ReactNode } from "react";
3
+
4
+ // Loaded only when editing, so the editor stays out of your app's bundle
5
+ const Editor = lazy(() => import("./editor"));
6
+
7
+ /** The path being edited for URLs ending in /edit, e.g. /about/edit */
8
+ export const editorPath = (pathname: string) => {
9
+ const segments = pathname.split("/");
10
+ if (segments.at(-1) !== "edit") return null;
11
+ return segments.slice(0, -1).join("/") || "/";
12
+ };
13
+
14
+ /** Renders the Puck editor at /edit URLs, and your app everywhere else */
15
+ export function PuckRoot({ children }: { children: ReactNode }) {
16
+ const path = editorPath(window.location.pathname);
17
+ if (path === null) return children;
18
+
19
+ return (
20
+ // Fill the window, whatever layout styles your app gives its root
21
+ <div style={{ position: "fixed", inset: 0, textAlign: "initial" }}>
22
+ <Suspense>
23
+ <Editor path={path} />
24
+ </Suspense>
25
+ </div>
26
+ );
27
+ }
@@ -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
+ };
@@ -0,0 +1,26 @@
1
+ {
2
+ "compilerOptions": {
3
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
4
+ "target": "es2023",
5
+ "lib": ["ES2023", "DOM"],
6
+ "module": "esnext",
7
+ "types": ["vite/client"],
8
+ "allowArbitraryExtensions": true,
9
+ "skipLibCheck": true,
10
+
11
+ /* Bundler mode */
12
+ "moduleResolution": "bundler",
13
+ "allowImportingTsExtensions": true,
14
+ "verbatimModuleSyntax": true,
15
+ "moduleDetection": "force",
16
+ "noEmit": true,
17
+ "jsx": "react-jsx",
18
+
19
+ /* Linting */
20
+ "noUnusedLocals": true,
21
+ "noUnusedParameters": true,
22
+ "erasableSyntaxOnly": true,
23
+ "noFallthroughCasesInSwitch": true
24
+ },
25
+ "include": ["src"]
26
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "files": [],
3
+ "references": [
4
+ { "path": "./tsconfig.app.json" },
5
+ { "path": "./tsconfig.node.json" }
6
+ ]
7
+ }