@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,75 @@
1
+ # Viewports
2
+
3
+ The Puck preview renders in a same-origin iframe that can be resized to simulate different viewports.
4
+
5
+ ## Default viewports
6
+
7
+ Puck provides 4 viewports [by default](/docs/api-reference/components/puck#default-viewports):
8
+
9
+ 1. Small: 360px wide
10
+ 2. Medium: 768px wide
11
+ 3. Large: 1280px wide
12
+ 4. Full-width: Fit the container
13
+
14
+ Each of the default viewports have 100% height, filling the available space (via the `auto` height parameter).
15
+
16
+ ## Customizing viewports
17
+
18
+ Customizing the available viewports using the [`viewports` API](/docs/api-reference/components/puck#viewports):
19
+
20
+ ```tsx
21
+ export function Editor() {
22
+ return (
23
+ <Puck
24
+ viewports={[
25
+ {
26
+ width: 1440,
27
+ height: "auto", // Optional height. Can be numeric or "auto". Defaults to "auto".
28
+ label: "My Viewport", // Optional. Shown in tooltip.
29
+ icon: <svg />, // Optional. Use lucide-icons to align with Puck UI.
30
+ },
31
+ ]}
32
+ // ...
33
+ />
34
+ );
35
+ }
36
+ ```
37
+
38
+ ## Disable viewports
39
+
40
+ Disable viewport behavior by disabling iframes with [`iframe.enabled`](/docs/api-reference/components/puck#enabled):
41
+
42
+ ```tsx
43
+ export function Editor() {
44
+ return (
45
+ <Puck
46
+ iframe={{
47
+ enabled: false,
48
+ }}
49
+ // ...
50
+ />
51
+ );
52
+ }
53
+ ```
54
+
55
+ Note that this will also disable [style isolation](/docs/integrating-puck/styling#style-isolation).
56
+
57
+ ## Controlling viewports with compositional interfaces
58
+
59
+ When implementing a [compositional interface](/docs/extending-puck/composition), the `viewports` API will have no effect. Instead, the viewport size can be controlled by the dimensions of the wrapping element that contains [`<Puck.Preview />`](/docs/api-reference/components/puck-preview).
60
+
61
+ CSS transforms can be used to zoom the viewport without impacting drag-and-drop behaviour.
62
+
63
+ ```tsx
64
+ import { Puck } from "@puckeditor/core";
65
+
66
+ export function Editor() {
67
+ return (
68
+ <Puck>
69
+ <div style={{ transform: "scale(0.5)", width: 1280 }}>
70
+ <Puck.Preview />
71
+ </div>
72
+ </Puck>
73
+ );
74
+ }
75
+ ```
@@ -0,0 +1,52 @@
1
+ # Puck + Astro recipe
2
+
3
+ [Puck](https://puckeditor.com) is the open-source visual editor for React.
4
+
5
+ This recipe adds Puck to an [Astro](https://astro.build) site. The editor runs as a React island, published pages are rendered on the server, and the [Node adapter](https://docs.astro.build/en/guides/integrations-guide/node/) serves Puck's API routes on demand while the rest of the site can stay static.
6
+
7
+ ## Run the recipe
8
+
9
+ ### 1. Start the development server
10
+
11
+ Run:
12
+
13
+ ```sh
14
+ npm run dev
15
+ ```
16
+
17
+ Once the server is running, navigate to [http://localhost:4321](http://localhost:4321) to view the home page, or [http://localhost:4321/edit](http://localhost:4321/edit) to edit it with Puck.
18
+
19
+ ### 2. Publish a page
20
+
21
+ Open the `Blocks` tab in the left sidebar and drag components onto the canvas. Once your page is ready, select **Publish** in the header to save it, then navigate to [http://localhost:4321](http://localhost:4321) to view it.
22
+
23
+ You can also create a page at any path by navigating to `/your/path/edit` and publishing it.
24
+
25
+ ## How it works
26
+
27
+ `src/pages/[...puckPath].astro` handles every URL without its own page. When a URL ends in `/edit`, it renders the editor for that path as a client-only React island. Otherwise it loads the published page and renders it with [`<Render>`](https://puckeditor.com/docs/api-reference/components/render) on the server, so no editor code is sent to visitors.
28
+
29
+ | File | Purpose |
30
+ | ------------------------------- | -------------------------------------------------------------------------------------------------- |
31
+ | `src/puck.config.tsx` | Defines the components, fields, and default props available to Puck. Add your own components here. |
32
+ | `src/pages/[...puckPath].astro` | Renders the editor at `/edit` URLs, and published pages everywhere else. |
33
+ | `src/pages/api/pages.ts` | Loads and saves pages for the editor. |
34
+ | `src/puck/editor.tsx` | Loads the page being edited and publishes changes. |
35
+ | `src/puck/render.tsx` | Renders a published page. |
36
+ | `src/lib/pages.ts` | Reads and writes page data in `database.json`. Replace this with your own database. |
37
+ | `database.json` | Acts as a local database. Replace this with your own database solution. |
38
+
39
+ ## Before deploying to production
40
+
41
+ Before deploying this recipe, make sure to:
42
+
43
+ - **Protect the editor and APIs.** The `/edit` routes and `/api/pages` route are public by default. Add authentication and authorization.
44
+ - **Add your component library.** Replace the example `HeadingBlock` in `src/puck.config.tsx` with the components and fields your users need.
45
+ - **Use a real database.** Replace `database.json` and `src/lib/pages.ts`. Local files are not reliable across server instances or serverless deployments.
46
+
47
+ ## Learn more
48
+
49
+ - [Puck documentation](https://puckeditor.com/docs)
50
+ - [Integrating Puck](https://puckeditor.com/docs/integrating-puck/component-configuration)
51
+ - [Astro](https://docs.astro.build)
52
+ - [Puck Discord](https://discord.gg/D9e4E3MQVZ)
@@ -0,0 +1,24 @@
1
+ # build output
2
+ dist/
3
+ # generated types
4
+ .astro/
5
+
6
+ # dependencies
7
+ node_modules/
8
+
9
+ # logs
10
+ npm-debug.log*
11
+ yarn-debug.log*
12
+ yarn-error.log*
13
+ pnpm-debug.log*
14
+
15
+
16
+ # environment variables
17
+ .env
18
+ .env.production
19
+
20
+ # macOS-specific files
21
+ .DS_Store
22
+
23
+ # jetbrains setting folder
24
+ .idea/
@@ -0,0 +1,14 @@
1
+ // @ts-check
2
+ import { defineConfig } from "astro/config";
3
+
4
+ import react from "@astrojs/react";
5
+ import node from "@astrojs/node";
6
+
7
+ // https://astro.build/config
8
+ export default defineConfig({
9
+ integrations: [react()],
10
+
11
+ adapter: node({
12
+ mode: "standalone",
13
+ }),
14
+ });
@@ -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,25 @@
1
+ {
2
+ "name": "astro-recipe",
3
+ "version": "1.0.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "astro dev",
8
+ "build": "astro build",
9
+ "preview": "astro preview",
10
+ "start": "node dist/server/entry.mjs",
11
+ "astro": "astro"
12
+ },
13
+ "dependencies": {
14
+ "@astrojs/node": "^11.1.6",
15
+ "@astrojs/react": "^7.0.0",
16
+ "@puckeditor/core": "workspace:*",
17
+ "astro": "^7.3.5",
18
+ "react": "^19.2.0",
19
+ "react-dom": "^19.2.0"
20
+ },
21
+ "devDependencies": {
22
+ "@types/react": "^19.2.0",
23
+ "@types/react-dom": "^19.2.0"
24
+ }
25
+ }
@@ -0,0 +1,9 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 128 128">
2
+ <path d="M50.4 78.5a75.1 75.1 0 0 0-28.5 6.9l24.2-65.7c.7-2 1.9-3.2 3.4-3.2h29c1.5 0 2.7 1.2 3.4 3.2l24.2 65.7s-11.6-7-28.5-7L67 45.5c-.4-1.7-1.6-2.8-2.9-2.8-1.3 0-2.5 1.1-2.9 2.7L50.4 78.5Zm-1.1 28.2Zm-4.2-20.2c-2 6.6-.6 15.8 4.2 20.2a17.5 17.5 0 0 1 .2-.7 5.5 5.5 0 0 1 5.7-4.5c2.8.1 4.3 1.5 4.7 4.7.2 1.1.2 2.3.2 3.5v.4c0 2.7.7 5.2 2.2 7.4a13 13 0 0 0 5.7 4.9v-.3l-.2-.3c-1.8-5.6-.5-9.5 4.4-12.8l1.5-1a73 73 0 0 0 3.2-2.2 16 16 0 0 0 6.8-11.4c.3-2 .1-4-.6-6l-.8.6-1.6 1a37 37 0 0 1-22.4 2.7c-5-.7-9.7-2-13.2-6.2Z" />
3
+ <style>
4
+ path { fill: #000; }
5
+ @media (prefers-color-scheme: dark) {
6
+ path { fill: #FFF; }
7
+ }
8
+ </style>
9
+ </svg>
@@ -0,0 +1,21 @@
1
+ import fs from "node:fs/promises";
2
+ import type { Data } from "@puckeditor/core";
3
+
4
+ // Replace this with your own database
5
+ const databasePath = "database.json";
6
+
7
+ const readPages = async (): Promise<Record<string, Data>> => {
8
+ try {
9
+ return JSON.parse(await fs.readFile(databasePath, "utf-8"));
10
+ } catch {
11
+ return {};
12
+ }
13
+ };
14
+
15
+ export const getPage = async (path: string) => (await readPages())[path];
16
+
17
+ export const savePage = async (path: string, data: Data) => {
18
+ const pages = await readPages();
19
+ pages[path] = data;
20
+ await fs.writeFile(databasePath, JSON.stringify(pages));
21
+ };
@@ -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,25 @@
1
+ ---
2
+ import { getPage } from "../lib/pages";
3
+ import { resolvePuckPath } from "../lib/resolve-puck-path";
4
+ import Editor from "../puck/editor";
5
+ import PuckRender from "../puck/render";
6
+
7
+ // Pages are loaded when requested, so published changes show up immediately
8
+ export const prerender = false;
9
+
10
+ const { isEditorRoute, path } = resolvePuckPath(Astro.url.pathname);
11
+ const page = isEditorRoute ? null : await getPage(path);
12
+
13
+ if (!isEditorRoute && !page) return new Response(null, { status: 404 });
14
+ ---
15
+
16
+ <html lang="en">
17
+ <head>
18
+ <meta charset="utf-8" />
19
+ <meta name="viewport" content="width=device-width" />
20
+ <title>{isEditorRoute ? `Edit: ${path}` : page?.root.props?.title}</title>
21
+ </head>
22
+ <body style={isEditorRoute ? "margin: 0" : undefined}>
23
+ {isEditorRoute ? <Editor client:only="react" path={path} /> : <PuckRender data={page!} />}
24
+ </body>
25
+ </html>
@@ -0,0 +1,18 @@
1
+ // Loads and saves Puck pages for the editor
2
+ import type { APIRoute } from "astro";
3
+ import { getPage, savePage } from "../../lib/pages";
4
+
5
+ export const prerender = false;
6
+
7
+ export const GET: APIRoute = async ({ url }) => {
8
+ const page = await getPage(url.searchParams.get("path") ?? "/");
9
+ return page
10
+ ? Response.json(page)
11
+ : Response.json({ error: "Not found" }, { status: 404 });
12
+ };
13
+
14
+ export const POST: APIRoute = async ({ request }) => {
15
+ const { path, data } = await request.json();
16
+ await savePage(path, data);
17
+ return Response.json({ status: "ok" });
18
+ };
@@ -0,0 +1,32 @@
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
+ // e.g. /edit?path=/about, where there are no server routes for each page
13
+ const pathFromQuery = () =>
14
+ new URLSearchParams(window.location.search).get("path") ?? "/";
15
+
16
+ export default function Editor({ path = pathFromQuery() }: { path?: string }) {
17
+ const [data, setData] = useState<Data | null>(null);
18
+
19
+ useEffect(() => {
20
+ loadPage(path).then((page) => setData(page ?? emptyPage));
21
+ }, [path]);
22
+
23
+ if (!data) return null;
24
+
25
+ return (
26
+ <Puck
27
+ config={config}
28
+ data={data}
29
+ onPublish={(data) => savePage(path, data)}
30
+ />
31
+ );
32
+ }
@@ -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,9 @@
1
+ import type { Data } from "@puckeditor/core";
2
+ import { Render } from "@puckeditor/core";
3
+
4
+ import { config } from "../puck.config";
5
+
6
+ // Rendered on the server, without shipping the editor to the browser
7
+ export default function PuckRender({ data }: { data: Data }) {
8
+ return <Render config={config} data={data} />;
9
+ }
@@ -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,14 @@
1
+ {
2
+ "extends": "astro/tsconfigs/strict",
3
+ "include": [
4
+ ".astro/types.d.ts",
5
+ "**/*"
6
+ ],
7
+ "exclude": [
8
+ "dist"
9
+ ],
10
+ "compilerOptions": {
11
+ "jsx": "react-jsx",
12
+ "jsxImportSource": "react"
13
+ }
14
+ }
@@ -0,0 +1,64 @@
1
+ # Puck AI + Astro 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 an [Astro](https://astro.build) site. The editor runs as a React island, published pages are rendered on the server, and the [Node adapter](https://docs.astro.build/en/guides/integrations-guide/node/) serves Puck's API routes on demand while the rest of the site can stay static.
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:4321](http://localhost:4321) to view the home page, or [http://localhost:4321/edit](http://localhost:4321/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:4321](http://localhost:4321) 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
+ `src/pages/[...puckPath].astro` handles every URL without its own page. When a URL ends in `/edit`, it renders the editor for that path as a client-only React island. Otherwise it loads the published page and renders it with [`<Render>`](https://puckeditor.com/docs/api-reference/components/render) on the server, so no editor code is sent to visitors.
36
+
37
+ | File | Purpose |
38
+ | -------------------------------- | -------------------------------------------------------------------------------------------------- |
39
+ | `src/puck.config.tsx` | Defines the components, fields, and default props available to Puck. Add your own components here. |
40
+ | `src/pages/[...puckPath].astro` | Renders the editor at `/edit` URLs, and published pages everywhere else. |
41
+ | `src/pages/api/pages.ts` | Loads and saves pages for the editor. |
42
+ | `src/pages/api/puck/[...all].ts` | Handles requests from the AI plugin and configures AI generation. |
43
+ | `src/puck/editor.tsx` | Loads the page being edited and publishes changes. |
44
+ | `src/puck/render.tsx` | Renders a published page. |
45
+ | `src/lib/pages.ts` | Reads and writes page data in `database.json`. Replace this with your own database. |
46
+ | `database.json` | Acts as a local database. Replace this with your own database solution. |
47
+
48
+ ## Before deploying to production
49
+
50
+ Before deploying this recipe, make sure to:
51
+
52
+ - **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.
53
+ - **Add your component library.** Replace the example `HeadingBlock` in `src/puck.config.tsx` with the components and fields your users need.
54
+ - **Set your business context.** Replace the example Google context in `src/pages/api/puck/[...all].ts` with clear information about your product, audience, and content rules.
55
+ - **Set `PUCK_API_KEY` in production.** `.env.local` is only loaded in development, so set it in the environment wherever the server runs.
56
+ - **Use a real database.** Replace `database.json` and `src/lib/pages.ts`. Local files are not reliable across server instances or serverless deployments.
57
+
58
+ ## Learn more
59
+
60
+ - [Puck documentation](https://puckeditor.com/docs)
61
+ - [Integrating Puck](https://puckeditor.com/docs/integrating-puck/component-configuration)
62
+ - [Puck AI documentation](https://puckeditor.com/docs/ai/overview)
63
+ - [Astro](https://docs.astro.build)
64
+ - [Puck Discord](https://discord.gg/D9e4E3MQVZ)
@@ -0,0 +1,24 @@
1
+ # build output
2
+ dist/
3
+ # generated types
4
+ .astro/
5
+
6
+ # dependencies
7
+ node_modules/
8
+
9
+ # logs
10
+ npm-debug.log*
11
+ yarn-debug.log*
12
+ yarn-error.log*
13
+ pnpm-debug.log*
14
+
15
+
16
+ # environment variables
17
+ .env
18
+ .env.production
19
+
20
+ # macOS-specific files
21
+ .DS_Store
22
+
23
+ # jetbrains setting folder
24
+ .idea/
@@ -0,0 +1,21 @@
1
+ // @ts-check
2
+ import { defineConfig } from "astro/config";
3
+
4
+ import react from "@astrojs/react";
5
+ import node from "@astrojs/node";
6
+
7
+ // https://astro.build/config
8
+ export default defineConfig({
9
+ integrations: [react()],
10
+
11
+ adapter: node({
12
+ mode: "standalone",
13
+ }),
14
+
15
+ // Pre-bundle Puck together, so the AI plugin and the editor share one copy
16
+ vite: {
17
+ optimizeDeps: {
18
+ include: ["@puckeditor/core", "@puckeditor/plugin-ai"],
19
+ },
20
+ },
21
+ });
@@ -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,27 @@
1
+ {
2
+ "name": "astro-ai-recipe",
3
+ "version": "1.0.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "astro dev",
8
+ "build": "astro build",
9
+ "preview": "astro preview",
10
+ "start": "node dist/server/entry.mjs",
11
+ "astro": "astro"
12
+ },
13
+ "dependencies": {
14
+ "@astrojs/node": "^11.1.6",
15
+ "@astrojs/react": "^7.0.0",
16
+ "@puckeditor/cloud-client": "^0",
17
+ "@puckeditor/core": "workspace:*",
18
+ "@puckeditor/plugin-ai": "^0",
19
+ "astro": "^7.3.5",
20
+ "react": "^19.2.0",
21
+ "react-dom": "^19.2.0"
22
+ },
23
+ "devDependencies": {
24
+ "@types/react": "^19.2.0",
25
+ "@types/react-dom": "^19.2.0"
26
+ }
27
+ }
@@ -0,0 +1,9 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 128 128">
2
+ <path d="M50.4 78.5a75.1 75.1 0 0 0-28.5 6.9l24.2-65.7c.7-2 1.9-3.2 3.4-3.2h29c1.5 0 2.7 1.2 3.4 3.2l24.2 65.7s-11.6-7-28.5-7L67 45.5c-.4-1.7-1.6-2.8-2.9-2.8-1.3 0-2.5 1.1-2.9 2.7L50.4 78.5Zm-1.1 28.2Zm-4.2-20.2c-2 6.6-.6 15.8 4.2 20.2a17.5 17.5 0 0 1 .2-.7 5.5 5.5 0 0 1 5.7-4.5c2.8.1 4.3 1.5 4.7 4.7.2 1.1.2 2.3.2 3.5v.4c0 2.7.7 5.2 2.2 7.4a13 13 0 0 0 5.7 4.9v-.3l-.2-.3c-1.8-5.6-.5-9.5 4.4-12.8l1.5-1a73 73 0 0 0 3.2-2.2 16 16 0 0 0 6.8-11.4c.3-2 .1-4-.6-6l-.8.6-1.6 1a37 37 0 0 1-22.4 2.7c-5-.7-9.7-2-13.2-6.2Z" />
3
+ <style>
4
+ path { fill: #000; }
5
+ @media (prefers-color-scheme: dark) {
6
+ path { fill: #FFF; }
7
+ }
8
+ </style>
9
+ </svg>
@@ -0,0 +1,21 @@
1
+ import fs from "node:fs/promises";
2
+ import type { Data } from "@puckeditor/core";
3
+
4
+ // Replace this with your own database
5
+ const databasePath = "database.json";
6
+
7
+ const readPages = async (): Promise<Record<string, Data>> => {
8
+ try {
9
+ return JSON.parse(await fs.readFile(databasePath, "utf-8"));
10
+ } catch {
11
+ return {};
12
+ }
13
+ };
14
+
15
+ export const getPage = async (path: string) => (await readPages())[path];
16
+
17
+ export const savePage = async (path: string, data: Data) => {
18
+ const pages = await readPages();
19
+ pages[path] = data;
20
+ await fs.writeFile(databasePath, JSON.stringify(pages));
21
+ };
@@ -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,25 @@
1
+ ---
2
+ import { getPage } from "../lib/pages";
3
+ import { resolvePuckPath } from "../lib/resolve-puck-path";
4
+ import Editor from "../puck/editor";
5
+ import PuckRender from "../puck/render";
6
+
7
+ // Pages are loaded when requested, so published changes show up immediately
8
+ export const prerender = false;
9
+
10
+ const { isEditorRoute, path } = resolvePuckPath(Astro.url.pathname);
11
+ const page = isEditorRoute ? null : await getPage(path);
12
+
13
+ if (!isEditorRoute && !page) return new Response(null, { status: 404 });
14
+ ---
15
+
16
+ <html lang="en">
17
+ <head>
18
+ <meta charset="utf-8" />
19
+ <meta name="viewport" content="width=device-width" />
20
+ <title>{isEditorRoute ? `Edit: ${path}` : page?.root.props?.title}</title>
21
+ </head>
22
+ <body style={isEditorRoute ? "margin: 0" : undefined}>
23
+ {isEditorRoute ? <Editor client:only="react" path={path} /> : <PuckRender data={page!} />}
24
+ </body>
25
+ </html>
@@ -0,0 +1,18 @@
1
+ // Loads and saves Puck pages for the editor
2
+ import type { APIRoute } from "astro";
3
+ import { getPage, savePage } from "../../lib/pages";
4
+
5
+ export const prerender = false;
6
+
7
+ export const GET: APIRoute = async ({ url }) => {
8
+ const page = await getPage(url.searchParams.get("path") ?? "/");
9
+ return page
10
+ ? Response.json(page)
11
+ : Response.json({ error: "Not found" }, { status: 404 });
12
+ };
13
+
14
+ export const POST: APIRoute = async ({ request }) => {
15
+ const { path, data } = await request.json();
16
+ await savePage(path, data);
17
+ return Response.json({ status: "ok" });
18
+ };