create-nextblock 0.14.1 → 0.14.4

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 (263) hide show
  1. package/docker-template/.dockerignore +23 -23
  2. package/docker-template/.env.docker.example +69 -69
  3. package/docker-template/docker/db/init/99-jwt.sql +6 -6
  4. package/docker-template/docker/db/init/99-roles.sql +25 -25
  5. package/docker-template/docker/kong/kong.yml +112 -112
  6. package/docker-template/scripts/docker-setup.mjs +310 -310
  7. package/libs/db/tsconfig.lib.json +3 -3
  8. package/libs/editor/tsconfig.lib.json +3 -3
  9. package/libs/ui/tsconfig.lib.json +3 -3
  10. package/libs/utils/tsconfig.json +3 -3
  11. package/package.json +1 -1
  12. package/project.json +19 -19
  13. package/templates/nextblock-template/.browserslistrc +11 -11
  14. package/templates/nextblock-template/.dockerignore +23 -23
  15. package/templates/nextblock-template/README.md +34 -34
  16. package/templates/nextblock-template/app/(auth-pages)/layout.tsx +9 -9
  17. package/templates/nextblock-template/app/(auth-pages)/post-sign-in/page.tsx +27 -27
  18. package/templates/nextblock-template/app/(auth-pages)/sign-up/page.tsx +46 -46
  19. package/templates/nextblock-template/app/(auth-pages)/two-factor/page.tsx +51 -51
  20. package/templates/nextblock-template/app/ToasterProvider.tsx +17 -17
  21. package/templates/nextblock-template/app/[slug]/pageClientActions.ts +7 -7
  22. package/templates/nextblock-template/app/actions/consent.ts +57 -57
  23. package/templates/nextblock-template/app/actions/postActions.ts +146 -146
  24. package/templates/nextblock-template/app/actions/twoFactorEmail.ts +22 -22
  25. package/templates/nextblock-template/app/api/ai/cortex/build-widget/route.ts +153 -153
  26. package/templates/nextblock-template/app/api/ai/generate-blocks/route.ts +96 -96
  27. package/templates/nextblock-template/app/api/brand/email-logo/route.ts +48 -48
  28. package/templates/nextblock-template/app/api/cms/check-updates/route.ts +44 -44
  29. package/templates/nextblock-template/app/api/cms/full-backup/export/route.ts +33 -33
  30. package/templates/nextblock-template/app/api/cms/full-backup/restore/route.ts +63 -63
  31. package/templates/nextblock-template/app/api/cron/reset-sandbox/route.ts +3490 -3490
  32. package/templates/nextblock-template/app/api/cron/reset-sandbox/sandboxResetSql.ts +5881 -5623
  33. package/templates/nextblock-template/app/api/cron/sync-currencies/route.ts +39 -39
  34. package/templates/nextblock-template/app/api/custom-blocks/db-relations/route.ts +92 -92
  35. package/templates/nextblock-template/app/api/custom-blocks/editor-definitions/route.ts +43 -43
  36. package/templates/nextblock-template/app/api/media/library/route.ts +69 -69
  37. package/templates/nextblock-template/app/api/media/r2-presigned/route.ts +53 -53
  38. package/templates/nextblock-template/app/api/media/record/route.ts +160 -160
  39. package/templates/nextblock-template/app/api/search/route.ts +43 -43
  40. package/templates/nextblock-template/app/article/[slug]/PostClientContent.tsx +441 -441
  41. package/templates/nextblock-template/app/auth/callback/route.ts +31 -31
  42. package/templates/nextblock-template/app/cart/page.tsx +7 -7
  43. package/templates/nextblock-template/app/cms/CmsClientLayout.tsx +2 -2
  44. package/templates/nextblock-template/app/cms/blocks/components/ColumnEditor.tsx +17 -22
  45. package/templates/nextblock-template/app/cms/blocks/components/CustomBlockEditorPreview.tsx +160 -160
  46. package/templates/nextblock-template/app/cms/blocks/components/EditableBlock.tsx +13 -19
  47. package/templates/nextblock-template/app/cms/blocks/components/MediaLibraryModal.tsx +149 -149
  48. package/templates/nextblock-template/app/cms/blocks/editors/DynamicCustomBlockEditor.tsx +167 -167
  49. package/templates/nextblock-template/app/cms/blocks/editors/HeadingBlockEditor.tsx +45 -34
  50. package/templates/nextblock-template/app/cms/blocks/editors/ImageBlockEditor.tsx +4 -2
  51. package/templates/nextblock-template/app/cms/blocks/editors/TextBlockEditor.tsx +90 -90
  52. package/templates/nextblock-template/app/cms/components/ConnectGitHubButton.tsx +122 -122
  53. package/templates/nextblock-template/app/cms/components/CortexAiPageContext.tsx +58 -58
  54. package/templates/nextblock-template/app/cms/components/FeedbackModal.tsx +36 -36
  55. package/templates/nextblock-template/app/cms/components/SystemAlertsBanner.tsx +112 -112
  56. package/templates/nextblock-template/app/cms/components/TwoFactorReminderBanner.tsx +45 -45
  57. package/templates/nextblock-template/app/cms/components/github-connect-actions.ts +102 -102
  58. package/templates/nextblock-template/app/cms/components/system-alerts-actions.ts +31 -31
  59. package/templates/nextblock-template/app/cms/custom-blocks/[id]/edit/page.tsx +66 -66
  60. package/templates/nextblock-template/app/cms/custom-blocks/actions.ts +519 -519
  61. package/templates/nextblock-template/app/cms/custom-blocks/components/BlocksLibraryTransferControls.tsx +256 -256
  62. package/templates/nextblock-template/app/cms/custom-blocks/components/DBRelationSelect.tsx +384 -384
  63. package/templates/nextblock-template/app/cms/custom-blocks/components/ImageR2Picker.tsx +221 -221
  64. package/templates/nextblock-template/app/cms/custom-blocks/new/page.tsx +12 -12
  65. package/templates/nextblock-template/app/cms/custom-blocks/page.tsx +438 -438
  66. package/templates/nextblock-template/app/cms/dashboard/actions.ts +228 -228
  67. package/templates/nextblock-template/app/cms/dashboard/components/DashboardOnboarding.tsx +130 -130
  68. package/templates/nextblock-template/app/cms/import-export/actions.ts +226 -226
  69. package/templates/nextblock-template/app/cms/layout.tsx +73 -73
  70. package/templates/nextblock-template/app/cms/media/components/FolderNavigator.tsx +273 -273
  71. package/templates/nextblock-template/app/cms/media/components/FolderTree.tsx +122 -122
  72. package/templates/nextblock-template/app/cms/media/components/MediaEditForm.tsx +26 -26
  73. package/templates/nextblock-template/app/cms/media/components/MediaGridClient.tsx +69 -69
  74. package/templates/nextblock-template/app/cms/navigation/components/NavigationMenuDnd.tsx +3 -3
  75. package/templates/nextblock-template/app/cms/products/attributes/page.tsx +12 -12
  76. package/templates/nextblock-template/app/cms/products/categories/page.tsx +12 -12
  77. package/templates/nextblock-template/app/cms/products/inventory/page.tsx +13 -13
  78. package/templates/nextblock-template/app/cms/products/new/page.tsx +135 -135
  79. package/templates/nextblock-template/app/cms/products/productFormData.ts +133 -133
  80. package/templates/nextblock-template/app/cms/products/settings/page.tsx +5 -5
  81. package/templates/nextblock-template/app/cms/promotions/PromotionsWorkspace.tsx +456 -456
  82. package/templates/nextblock-template/app/cms/promotions/actions.ts +115 -115
  83. package/templates/nextblock-template/app/cms/promotions/page.tsx +31 -31
  84. package/templates/nextblock-template/app/cms/revisions/service.ts +19 -19
  85. package/templates/nextblock-template/app/cms/revisions/utils.ts +132 -132
  86. package/templates/nextblock-template/app/cms/settings/backup-restore/BackupRestoreWorkspace.tsx +1004 -1004
  87. package/templates/nextblock-template/app/cms/settings/backup-restore/page.tsx +29 -29
  88. package/templates/nextblock-template/app/cms/settings/bot-protection/page.tsx +24 -24
  89. package/templates/nextblock-template/app/cms/settings/cortex-ai/SandboxCortexAiSettingsClient.tsx +688 -688
  90. package/templates/nextblock-template/app/cms/settings/currencies/actions.ts +331 -331
  91. package/templates/nextblock-template/app/cms/settings/currencies/page.tsx +494 -494
  92. package/templates/nextblock-template/app/cms/settings/email/page.tsx +28 -28
  93. package/templates/nextblock-template/app/cms/settings/extra-translations/ExtraTranslationsWorkspace.tsx +767 -767
  94. package/templates/nextblock-template/app/cms/settings/extra-translations/page.tsx +93 -93
  95. package/templates/nextblock-template/app/cms/settings/global-css/components/ThemeEditor.tsx +382 -0
  96. package/templates/nextblock-template/app/cms/settings/global-css/components/ThemeManager.tsx +267 -0
  97. package/templates/nextblock-template/app/cms/settings/global-css/page.tsx +40 -24
  98. package/templates/nextblock-template/app/cms/settings/global-css/theme-actions.ts +259 -0
  99. package/templates/nextblock-template/app/cms/settings/google-analytics/page.tsx +26 -26
  100. package/templates/nextblock-template/app/cms/settings/logos/[id]/edit/page.tsx +7 -7
  101. package/templates/nextblock-template/app/cms/settings/logos/components/BrandingSettingsForm.tsx +339 -339
  102. package/templates/nextblock-template/app/cms/settings/logos/components/DeleteLogoButton.tsx +21 -21
  103. package/templates/nextblock-template/app/cms/settings/logos/components/LogoForm.tsx +23 -21
  104. package/templates/nextblock-template/app/cms/settings/logos/components/SetActiveLogoButton.tsx +42 -42
  105. package/templates/nextblock-template/app/cms/settings/logos/components/SiteSeoSettingsForm.tsx +133 -133
  106. package/templates/nextblock-template/app/cms/settings/logos/new/page.tsx +8 -8
  107. package/templates/nextblock-template/app/cms/settings/packages/package-card.tsx +122 -122
  108. package/templates/nextblock-template/app/cms/settings/privacy/page.tsx +27 -27
  109. package/templates/nextblock-template/app/cms/settings/registration/page.tsx +27 -27
  110. package/templates/nextblock-template/app/cms/settings/security/components/SecurityPanel.tsx +9 -7
  111. package/templates/nextblock-template/app/cms/settings/security/page.tsx +33 -33
  112. package/templates/nextblock-template/app/cms/settings/taxes/page.tsx +21 -21
  113. package/templates/nextblock-template/app/cms/shipping/page.tsx +20 -20
  114. package/templates/nextblock-template/app/cms/users/components/DeleteUserButton.tsx +12 -12
  115. package/templates/nextblock-template/app/layout.tsx +49 -0
  116. package/templates/nextblock-template/app/lib/site-settings.ts +105 -105
  117. package/templates/nextblock-template/app/profile/ProfilePageHeader.tsx +16 -16
  118. package/templates/nextblock-template/app/profile/ProfilePageMissingState.tsx +9 -9
  119. package/templates/nextblock-template/app/profile/account-links.ts +22 -22
  120. package/templates/nextblock-template/app/profile/orders/CustomerOrdersPageClient.tsx +124 -124
  121. package/templates/nextblock-template/app/profile/orders/page.tsx +19 -19
  122. package/templates/nextblock-template/app/profile/password/PasswordSettingsPageClient.tsx +128 -128
  123. package/templates/nextblock-template/app/profile/password/actions.ts +59 -59
  124. package/templates/nextblock-template/app/profile/password/page.tsx +27 -27
  125. package/templates/nextblock-template/app/providers.tsx +16 -4
  126. package/templates/nextblock-template/app/setup/SetupWizard.tsx +678 -678
  127. package/templates/nextblock-template/app/setup/layout.tsx +13 -13
  128. package/templates/nextblock-template/app/setup/page.tsx +111 -111
  129. package/templates/nextblock-template/app/sitemap.ts +130 -130
  130. package/templates/nextblock-template/components/CartDrawerLoader.tsx +7 -7
  131. package/templates/nextblock-template/components/DeferredCartDrawer.tsx +23 -23
  132. package/templates/nextblock-template/components/DeferredGoogleAnalytics.tsx +70 -70
  133. package/templates/nextblock-template/components/DeferredGoogleTagManager.tsx +70 -70
  134. package/templates/nextblock-template/components/DeferredSpeedInsights.tsx +69 -69
  135. package/templates/nextblock-template/components/FeatureImageHero.tsx +47 -47
  136. package/templates/nextblock-template/components/FooterNavigation.tsx +32 -32
  137. package/templates/nextblock-template/components/HtmlScriptExecutor.tsx +47 -47
  138. package/templates/nextblock-template/components/LanguageSwitcher.tsx +2 -2
  139. package/templates/nextblock-template/components/PublicEnvBootstrap.tsx +30 -30
  140. package/templates/nextblock-template/components/ResponsiveNav.tsx +14 -14
  141. package/templates/nextblock-template/components/auth/AuthBotProtection.tsx +182 -182
  142. package/templates/nextblock-template/components/blocks/PostCardSkeleton.tsx +12 -12
  143. package/templates/nextblock-template/components/blocks/PostsGridBlock.tsx +12 -12
  144. package/templates/nextblock-template/components/blocks/ecommerceRendererLoaders.ts +23 -23
  145. package/templates/nextblock-template/components/blocks/renderers/FormBlockRenderer.tsx +249 -249
  146. package/templates/nextblock-template/components/blocks/renderers/HeadingBlockRenderer.tsx +7 -10
  147. package/templates/nextblock-template/components/blocks/types.ts +7 -7
  148. package/templates/nextblock-template/components/env-var-warning.tsx +3 -3
  149. package/templates/nextblock-template/components/form-message.tsx +32 -32
  150. package/templates/nextblock-template/components/media/YouTubeFacade.tsx +105 -105
  151. package/templates/nextblock-template/components/media/youtube-embed-replace.tsx +32 -32
  152. package/templates/nextblock-template/components/privacy/ConsentBanner.tsx +170 -170
  153. package/templates/nextblock-template/components/privacy/ConsentGatedAnalytics.tsx +70 -70
  154. package/templates/nextblock-template/components/renderers/CachedDynamicLayoutEngine.tsx +28 -28
  155. package/templates/nextblock-template/components/renderers/DynamicLayoutEngine.test.tsx +166 -166
  156. package/templates/nextblock-template/components/renderers/DynamicLayoutEngine.tsx +471 -471
  157. package/templates/nextblock-template/components/submit-button.tsx +23 -23
  158. package/templates/nextblock-template/components/theme-icon.tsx +78 -0
  159. package/templates/nextblock-template/components/theme-switcher.tsx +77 -82
  160. package/templates/nextblock-template/components/visual-editing/DeferredVisualEditing.tsx +21 -21
  161. package/templates/nextblock-template/context/AuthContext.tsx +23 -23
  162. package/templates/nextblock-template/context/ThemeCatalogContext.tsx +44 -0
  163. package/templates/nextblock-template/context/language-rest-client.ts +32 -32
  164. package/templates/nextblock-template/docker/db/init/99-jwt.sql +6 -6
  165. package/templates/nextblock-template/docker/db/init/99-roles.sql +25 -25
  166. package/templates/nextblock-template/docker/kong/kong.yml +112 -112
  167. package/templates/nextblock-template/docs/01-PROJECT-OVERVIEW.md +94 -94
  168. package/templates/nextblock-template/docs/02-ECOMMERCE-CAPABILITIES.md +364 -364
  169. package/templates/nextblock-template/docs/03-CMS-AND-EDITOR.md +279 -202
  170. package/templates/nextblock-template/docs/04-DATABASE-AND-AUTH.md +246 -246
  171. package/templates/nextblock-template/docs/06-CLI-AND-SCAFFOLDING.md +176 -176
  172. package/templates/nextblock-template/docs/07-BLOCK-SDK-AND-EXTENSIBILITY.md +146 -146
  173. package/templates/nextblock-template/docs/10-CUSTOM-BLOCKS.md +222 -222
  174. package/templates/nextblock-template/docs/11-SELF-HOSTED-DOCKER.md +173 -173
  175. package/templates/nextblock-template/docs/12-VERCEL-DEPLOYMENT.md +170 -170
  176. package/templates/nextblock-template/docs/13-STAYING-UP-TO-DATE.md +151 -151
  177. package/templates/nextblock-template/docs/README.md +39 -39
  178. package/templates/nextblock-template/hooks/use-hotkeys.ts +21 -21
  179. package/templates/nextblock-template/hooks/useGlobalSearch.ts +101 -101
  180. package/templates/nextblock-template/index.d.ts +7 -7
  181. package/templates/nextblock-template/lib/app-secrets.ts +39 -39
  182. package/templates/nextblock-template/lib/auth/cookies.ts +47 -47
  183. package/templates/nextblock-template/lib/auth/crypto.ts +45 -45
  184. package/templates/nextblock-template/lib/auth/trustedDevices.ts +92 -92
  185. package/templates/nextblock-template/lib/auth-redirects.ts +46 -46
  186. package/templates/nextblock-template/lib/blocks/README.md +13 -13
  187. package/templates/nextblock-template/lib/blocks/blockColors.test.ts +114 -0
  188. package/templates/nextblock-template/lib/blocks/blockColors.ts +132 -0
  189. package/templates/nextblock-template/lib/blocks/blockRegistry.ts +17 -1
  190. package/templates/nextblock-template/lib/botProtection/verify.ts +134 -134
  191. package/templates/nextblock-template/lib/cms-transfer/server.ts +2243 -2243
  192. package/templates/nextblock-template/lib/cms-transfer/types.ts +145 -145
  193. package/templates/nextblock-template/lib/custom-block-definitions.ts +87 -87
  194. package/templates/nextblock-template/lib/custom-block-r2-upload-shared.ts +178 -178
  195. package/templates/nextblock-template/lib/custom-block-r2-upload.test.ts +140 -140
  196. package/templates/nextblock-template/lib/custom-block-r2-upload.ts +88 -88
  197. package/templates/nextblock-template/lib/custom-block-relations.test.ts +227 -227
  198. package/templates/nextblock-template/lib/custom-block-relations.ts +279 -279
  199. package/templates/nextblock-template/lib/custom-block-safelist.ts +14 -14
  200. package/templates/nextblock-template/lib/editor/dynamic-extension-core.test.ts +172 -172
  201. package/templates/nextblock-template/lib/editor/dynamic-extension-core.ts +213 -213
  202. package/templates/nextblock-template/lib/editor/dynamic-extension-loader.ts +22 -22
  203. package/templates/nextblock-template/lib/editor/dynamic-extensions.tsx +193 -193
  204. package/templates/nextblock-template/lib/email/branding-format.test.ts +133 -133
  205. package/templates/nextblock-template/lib/email/branding-format.ts +123 -123
  206. package/templates/nextblock-template/lib/email/branding.ts +76 -76
  207. package/templates/nextblock-template/lib/full-backup/manifest.test.ts +121 -121
  208. package/templates/nextblock-template/lib/full-backup/manifest.ts +206 -206
  209. package/templates/nextblock-template/lib/full-backup/server.ts +743 -743
  210. package/templates/nextblock-template/lib/logos/active-logo.ts +53 -53
  211. package/templates/nextblock-template/lib/media/resolveMediaUrl.ts +54 -54
  212. package/templates/nextblock-template/lib/media/youtube.ts +99 -99
  213. package/templates/nextblock-template/lib/onboarding/actions.ts +31 -31
  214. package/templates/nextblock-template/lib/onboarding/status.ts +222 -222
  215. package/templates/nextblock-template/lib/posts/readTime.ts +60 -60
  216. package/templates/nextblock-template/lib/privacy/consent-client.ts +57 -57
  217. package/templates/nextblock-template/lib/privacy/contact-emails.ts +64 -64
  218. package/templates/nextblock-template/lib/privacy/settings.ts +115 -115
  219. package/templates/nextblock-template/lib/privacy/types.ts +69 -69
  220. package/templates/nextblock-template/lib/promotions/server.test.ts +74 -74
  221. package/templates/nextblock-template/lib/promotions/server.ts +741 -741
  222. package/templates/nextblock-template/lib/resolve-block-relations.test.ts +142 -142
  223. package/templates/nextblock-template/lib/resolve-block-relations.ts +255 -255
  224. package/templates/nextblock-template/lib/search/types.ts +27 -27
  225. package/templates/nextblock-template/lib/setup/actions.ts +460 -460
  226. package/templates/nextblock-template/lib/setup/env-status.ts +125 -125
  227. package/templates/nextblock-template/lib/setup/env-write.ts +111 -111
  228. package/templates/nextblock-template/lib/setup/migrations-bundle.ts +15 -10
  229. package/templates/nextblock-template/lib/setup/provisioning.ts +59 -59
  230. package/templates/nextblock-template/lib/setup/schema-apply.ts +408 -408
  231. package/templates/nextblock-template/lib/setup/system-config.ts +105 -105
  232. package/templates/nextblock-template/lib/setup/types.ts +18 -18
  233. package/templates/nextblock-template/lib/site-url.ts +48 -48
  234. package/templates/nextblock-template/lib/storage/provider.ts +66 -66
  235. package/templates/nextblock-template/lib/storage/supabase-storage.ts +103 -103
  236. package/templates/nextblock-template/lib/themes/buildThemeCss.test.ts +163 -0
  237. package/templates/nextblock-template/lib/themes/buildThemeCss.ts +124 -0
  238. package/templates/nextblock-template/lib/themes/tokenColor.ts +31 -0
  239. package/templates/nextblock-template/lib/themes/tokens.ts +143 -0
  240. package/templates/nextblock-template/lib/updates/check-upstream.ts +441 -441
  241. package/templates/nextblock-template/lib/updates/github-device.ts +206 -206
  242. package/templates/nextblock-template/lib/updates/repo-identity.ts +56 -56
  243. package/templates/nextblock-template/next-env.d.ts +2 -2
  244. package/templates/nextblock-template/package.json +1 -1
  245. package/templates/nextblock-template/postcss.config.js +6 -6
  246. package/templates/nextblock-template/scripts/backup.js +115 -115
  247. package/templates/nextblock-template/scripts/docker-setup.mjs +310 -310
  248. package/templates/nextblock-template/scripts/restore.js +385 -385
  249. package/templates/nextblock-template/scripts/verify-cortex-ai-build-widget.tsx +98 -98
  250. package/templates/nextblock-template/scripts/verify-cortex-ai-generate-blocks.ts +62 -62
  251. package/templates/nextblock-template/scripts/verify-cortex-ai-global-tools.ts +537 -537
  252. package/templates/nextblock-template/scripts/verify-cortex-ai-routing.ts +58 -58
  253. package/templates/nextblock-template/scripts/verify-custom-block-definitions.ts +188 -188
  254. package/templates/nextblock-template/scripts/verify-dynamic-custom-block-extensions.ts +123 -123
  255. package/templates/nextblock-template/scripts/verify-dynamic-layout-engine.tsx +133 -133
  256. package/templates/nextblock-template/scripts/verify-milestone-2-custom-blocks.ts +65 -65
  257. package/templates/nextblock-template/scripts/verify-site-themes.ts +63 -0
  258. package/templates/nextblock-template/tailwind.config.js +25 -25
  259. package/templates/nextblock-template/tools/build-migrate.mjs +209 -209
  260. package/templates/nextblock-template/tools/configure-supabase-auth.js +282 -282
  261. package/templates/nextblock-template/tsconfig.tsbuildinfo +1 -1
  262. package/templates/nextblock-template/types/jsdom.d.ts +6 -6
  263. package/tsconfig.base.json +3 -3
@@ -1,170 +1,170 @@
1
- # 12 · Cloud Deployment (Deploy to Vercel)
2
-
3
- NextBlock ships a one-click **Deploy to Vercel** button (see the README) that brings
4
- up a production instance already connected to a managed Supabase project. From there,
5
- the in-app **First-Boot Setup Wizard** (`/setup`) finishes configuration in the
6
- browser — there is no terminal step.
7
-
8
- ## How the button works
9
-
10
- The badge links to `https://vercel.com/new/clone` with these query parameters:
11
-
12
- | Parameter | Purpose |
13
- | :--- | :--- |
14
- | `repository-url` | The NextBlock repo to clone into the user's Git provider. |
15
- | `project-name` / `repository-name` | Pre-fill the new Vercel project and Git repo names. |
16
- | `stores=[{"type":"integration","integrationSlug":"supabase","productSlug":"supabase"}]` | Vercel's **native Supabase Marketplace integration**. During import you're prompted to **create a Supabase database** (name + region); Vercel **provisions it, connects it to the project, and injects the env vars before the first build**. |
17
-
18
- There is deliberately **no `env=` parameter** — the deploy prompts for **zero** values you
19
- have to type (see "No environment variables required" below). The only interaction is the
20
- Supabase integration's "create database" step, which can't be skipped because provisioning
21
- a Postgres DB requires choosing a region/plan.
22
-
23
- > **Why `stores`, not `integration-ids`?** The legacy `integration-ids=oac_…` parameter
24
- > triggers an OAuth integration that *creates* a Supabase project but leaves it
25
- > **disconnected** — it injects **no** environment variables into the Vercel project, so
26
- > the app boots unconfigured and you have to wire the keys up by hand. The modern `stores`
27
- > parameter is the native Marketplace path that actually **connects the store and injects
28
- > credentials before the build**. ([Vercel Deploy Button docs](https://vercel.com/docs/deploy-button/source))
29
-
30
- ## Connect the database (Supabase integration)
31
-
32
- The `stores` parameter makes Vercel prompt you to create a Supabase database during import.
33
- Pick a **name** and **region**, and Vercel **automatically injects** the integration's
34
- environment variables into the project — you never copy a value. The native integration
35
- injects the **new-style** Supabase key names, e.g.:
36
-
37
- `NEXT_PUBLIC_SUPABASE_URL` / `SUPABASE_URL`, `NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY` /
38
- `SUPABASE_PUBLISHABLE_KEY` (the anon-equivalent), `SUPABASE_SECRET_KEY` (the
39
- service-role-equivalent), and `POSTGRES_URL` (+ the other `POSTGRES_*` parts).
40
-
41
- NextBlock reads **all** of these aliases (see `apps/nextblock/lib/setup/env-status.ts`):
42
- it accepts `NEXT_PUBLIC_SUPABASE_URL` *or* `SUPABASE_URL`; anon *or* `PUBLISHABLE_KEY`;
43
- `SUPABASE_SERVICE_ROLE_KEY` *or* `SUPABASE_SECRET_KEY`. So the wizard's connection step
44
- auto-skips no matter which copy the integration set, and the browser client gets the
45
- publishable key bridged in as the anon key at build time.
46
-
47
- > If the database step still appears after a deploy that connected the store, the env vars
48
- > landed **after** that build — **Redeploy** once (Vercel binds env vars at deploy time).
49
- > With the `stores` flow they're injected *before* the first build, so this is rarely needed.
50
-
51
- On that deploy the wizard skips the database-connection step, **auto-applies the schema**
52
- (the migrations are embedded in the build — see `lib/setup/migrations-bundle.ts` — and run
53
- via the injected `POSTGRES_URL`), uses the connected Supabase project for media storage,
54
- and goes straight to creating the first administrator.
55
-
56
- > Until the schema is applied and the first admin exists, **every route redirects to
57
- > `/setup`** (the homepage does *not* 404). The middleware treats a "schema not applied yet"
58
- > database error as *unprovisioned* and funnels traffic to the wizard.
59
-
60
- ## Build configuration (Nx monorepo)
61
-
62
- NextBlock is an Nx monorepo — the Next.js app lives at `apps/nextblock`, not the repo
63
- root — so a bare `next build` at the root fails with *"Couldn't find any `pages` or
64
- `app` directory."* The root [`vercel.json`](../vercel.json) pins the correct build, so
65
- the one-click deploy needs **no manual dashboard configuration**:
66
-
67
- ```json
68
- {
69
- "buildCommand": "npx nx build nextblock --prod",
70
- "outputDirectory": "apps/nextblock/.next",
71
- "framework": "nextjs"
72
- }
73
- ```
74
-
75
- - **`buildCommand`** runs the Nx target from the repo root, which resolves the
76
- workspace libraries (`@nextblock-cms/*` via the TS path aliases) and builds the app.
77
- - **`outputDirectory`** points at the app's `.next`. This `@nx/next` version emits it
78
- to `apps/nextblock/.next` — **not** `dist/apps/nextblock/.next` (which only receives
79
- the deploy wrapper: `package.json`, `next.config.js`, `public/`). Verify with
80
- `npx nx build nextblock --prod` then check `apps/nextblock/.next/BUILD_ID`.
81
- - **`framework: nextjs`** keeps Vercel's first-class Next.js runtime (SSR/ISR
82
- functions, image optimization, the `proxy.ts` middleware).
83
-
84
- Leave the Vercel project's **Root Directory unset** (the repo root) — the build command
85
- already targets the app. Do **not** set Root Directory to `apps/nextblock`: the app
86
- imports the workspace libraries one level up, which a custom Root Directory would hide
87
- (Vercel forbids `..` above a custom root).
88
-
89
- ## No environment variables required
90
-
91
- A Deploy-Button URL can only carry variable **names**, never values — so secrets can
92
- never be pre-filled through it. Rather than make you paste random strings, NextBlock
93
- resolves everything in-app, and the button prompts for nothing:
94
-
95
- - **`NEXT_PUBLIC_URL`** — optional. When unset the app falls back to Vercel's
96
- production URL (`VERCEL_PROJECT_PRODUCTION_URL` server-side /
97
- `NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL` in the browser), i.e. your
98
- `*.vercel.app` domain. Sitemap, robots, and canonical links use it automatically.
99
- Add a custom domain later, set `NEXT_PUBLIC_URL=https://yourdomain.com` in the
100
- Vercel project, and redeploy (it is inlined at build time).
101
- - **`DRAFT_MODE_SECRET`** and **`REVALIDATE_SECRET_TOKEN`** — optional. When unset they
102
- are derived deterministically from the Supabase service-role key (HMAC-SHA256), so
103
- Draft Mode and on-demand revalidation work out of the box. Setting either env var
104
- overrides the derived value — do this if you want a fixed `REVALIDATE_SECRET_TOKEN`
105
- to paste into a Supabase revalidation webhook. (See `apps/nextblock/lib/app-secrets.ts`.)
106
- - **`CRON_SECRET`** — optional. The cron endpoints enforce the `Authorization: Bearer`
107
- header **only when it is set**. Leave it unset for a frictionless deploy, or set it
108
- in the Vercel project to lock the cron endpoints down. The destructive
109
- `/api/cron/reset-sandbox` job is independently gated to sandbox-mode only (404
110
- otherwise), so it never runs on a normal deploy.
111
-
112
- ## What the wizard does on Vercel
113
-
114
- 1. **Database** — already connected (integration-injected). The wizard verifies a
115
- first admin doesn't exist yet, otherwise it redirects to `/cms/dashboard`. The
116
- connection step is **auto-skipped**.
117
- 2. **Schema** — applied **automatically**. The Supabase integration creates the project
118
- but does **not** run NextBlock's migrations, so the wizard applies them itself on the
119
- final step: it runs the build-embedded migration bundle over the injected
120
- `POSTGRES_URL` (no CLI, no manual SQL). Idempotent — a re-run is a no-op. See
121
- [docs/04](./04-DATABASE-AND-AUTH.md) and [docs/05](./05-DEVELOPER-GUIDE.md).
122
- 3. **Storage** — **skipped on Vercel; nothing to configure.** Media uses **native
123
- Supabase Storage** through the already-connected project: the injected
124
- `SUPABASE_SECRET_KEY` authenticates uploads/downloads/deletes via the Supabase client
125
- (no S3 access keys required), a public `media` bucket is auto-created, and images are
126
- served from `<project>/storage/v1/object/public/media/…`. The storage backend is
127
- selected automatically (`apps/nextblock/lib/storage/provider.ts`): if S3/R2 keys are
128
- present it uses them; otherwise it falls back to native Supabase Storage. (Cloudflare
129
- R2 remains the default for non-Vercel installs — it has a more generous free storage
130
- tier; set the `R2_*` env vars to use it on Vercel instead.)
131
-
132
- > **Upload size:** the CMS media uploader proxies the file through a serverless
133
- > function (`/api/upload/proxy`), which is subject to Vercel's ~4.5 MB request-body
134
- > limit — larger single images fail on the Hobby/Pro serverless runtime regardless of
135
- > storage backend. This is a platform constraint, not a NextBlock one.
136
- 4. **Email / Bot protection / Sign-ups** — optional steps; bot-protection and the
137
- sign-up policy persist to the database and work immediately. SMTP, if used, is set
138
- as Vercel environment variables.
139
- 5. **Administrator** — create the first admin. The account is created already
140
- confirmed (`email_confirm: true`), so no verification email is required.
141
-
142
- > Filesystem is read-only on Vercel, so the wizard never writes `.env.local` there —
143
- > all configuration is environment variables (platform-managed) plus the database.
144
-
145
- ## Cron jobs and the Hobby plan
146
-
147
- `vercel.json` declares two crons (`/api/cron/reset-sandbox` at 03:00 and
148
- `/api/cron/sync-currencies` at 18:00). Vercel's **Hobby (free) tier allows up to 100
149
- cron jobs, each running at most once per day** — both jobs are daily, so they deploy
150
- fine on the free tier. (Hobby timing is approximate, ±59 min, which is irrelevant for
151
- daily jobs; only sub-daily schedules like `0 * * * *` are rejected on Hobby.)
152
-
153
- `reset-sandbox` only does work in sandbox mode — it returns 404 otherwise — so on a
154
- normal deploy it is a harmless no-op. Delete it from `vercel.json` if you'd rather not
155
- see it scheduled.
156
-
157
- ## After deploy
158
-
159
- Visit the deployment URL — it redirects to `/setup` until the first admin exists.
160
- Complete the wizard, then sign in at `/cms/dashboard`.
161
-
162
- **Automatic updates.** The 1-click deploy creates a **new repository you own** (a copy —
163
- *not* a GitHub fork) and ships a daily upstream-sync GitHub Action. Because it's your own
164
- repo, **Actions are enabled by default — there's nothing to turn on**; the workflow runs
165
- once it's on your **default branch**, and the dashboard onboarding step completes
166
- automatically when GitHub registers it. We recommend keeping the repo **public** (fully
167
- zero-config); a **private** repo additionally needs a `NEXTBLOCK_GITHUB_TOKEN` env var for
168
- the in-CMS conflict banner. (Only a *manually-created GitHub fork* has Actions disabled
169
- until you enable them on the Actions tab.) Full details — both tracks, conflict handling,
170
- and build-time migrations — are in [docs/13](./13-STAYING-UP-TO-DATE.md).
1
+ # 12 · Cloud Deployment (Deploy to Vercel)
2
+
3
+ NextBlock ships a one-click **Deploy to Vercel** button (see the README) that brings
4
+ up a production instance already connected to a managed Supabase project. From there,
5
+ the in-app **First-Boot Setup Wizard** (`/setup`) finishes configuration in the
6
+ browser — there is no terminal step.
7
+
8
+ ## How the button works
9
+
10
+ The badge links to `https://vercel.com/new/clone` with these query parameters:
11
+
12
+ | Parameter | Purpose |
13
+ | :--- | :--- |
14
+ | `repository-url` | The NextBlock repo to clone into the user's Git provider. |
15
+ | `project-name` / `repository-name` | Pre-fill the new Vercel project and Git repo names. |
16
+ | `stores=[{"type":"integration","integrationSlug":"supabase","productSlug":"supabase"}]` | Vercel's **native Supabase Marketplace integration**. During import you're prompted to **create a Supabase database** (name + region); Vercel **provisions it, connects it to the project, and injects the env vars before the first build**. |
17
+
18
+ There is deliberately **no `env=` parameter** — the deploy prompts for **zero** values you
19
+ have to type (see "No environment variables required" below). The only interaction is the
20
+ Supabase integration's "create database" step, which can't be skipped because provisioning
21
+ a Postgres DB requires choosing a region/plan.
22
+
23
+ > **Why `stores`, not `integration-ids`?** The legacy `integration-ids=oac_…` parameter
24
+ > triggers an OAuth integration that *creates* a Supabase project but leaves it
25
+ > **disconnected** — it injects **no** environment variables into the Vercel project, so
26
+ > the app boots unconfigured and you have to wire the keys up by hand. The modern `stores`
27
+ > parameter is the native Marketplace path that actually **connects the store and injects
28
+ > credentials before the build**. ([Vercel Deploy Button docs](https://vercel.com/docs/deploy-button/source))
29
+
30
+ ## Connect the database (Supabase integration)
31
+
32
+ The `stores` parameter makes Vercel prompt you to create a Supabase database during import.
33
+ Pick a **name** and **region**, and Vercel **automatically injects** the integration's
34
+ environment variables into the project — you never copy a value. The native integration
35
+ injects the **new-style** Supabase key names, e.g.:
36
+
37
+ `NEXT_PUBLIC_SUPABASE_URL` / `SUPABASE_URL`, `NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY` /
38
+ `SUPABASE_PUBLISHABLE_KEY` (the anon-equivalent), `SUPABASE_SECRET_KEY` (the
39
+ service-role-equivalent), and `POSTGRES_URL` (+ the other `POSTGRES_*` parts).
40
+
41
+ NextBlock reads **all** of these aliases (see `apps/nextblock/lib/setup/env-status.ts`):
42
+ it accepts `NEXT_PUBLIC_SUPABASE_URL` *or* `SUPABASE_URL`; anon *or* `PUBLISHABLE_KEY`;
43
+ `SUPABASE_SERVICE_ROLE_KEY` *or* `SUPABASE_SECRET_KEY`. So the wizard's connection step
44
+ auto-skips no matter which copy the integration set, and the browser client gets the
45
+ publishable key bridged in as the anon key at build time.
46
+
47
+ > If the database step still appears after a deploy that connected the store, the env vars
48
+ > landed **after** that build — **Redeploy** once (Vercel binds env vars at deploy time).
49
+ > With the `stores` flow they're injected *before* the first build, so this is rarely needed.
50
+
51
+ On that deploy the wizard skips the database-connection step, **auto-applies the schema**
52
+ (the migrations are embedded in the build — see `lib/setup/migrations-bundle.ts` — and run
53
+ via the injected `POSTGRES_URL`), uses the connected Supabase project for media storage,
54
+ and goes straight to creating the first administrator.
55
+
56
+ > Until the schema is applied and the first admin exists, **every route redirects to
57
+ > `/setup`** (the homepage does *not* 404). The middleware treats a "schema not applied yet"
58
+ > database error as *unprovisioned* and funnels traffic to the wizard.
59
+
60
+ ## Build configuration (Nx monorepo)
61
+
62
+ NextBlock is an Nx monorepo — the Next.js app lives at `apps/nextblock`, not the repo
63
+ root — so a bare `next build` at the root fails with *"Couldn't find any `pages` or
64
+ `app` directory."* The root [`vercel.json`](../vercel.json) pins the correct build, so
65
+ the one-click deploy needs **no manual dashboard configuration**:
66
+
67
+ ```json
68
+ {
69
+ "buildCommand": "npx nx build nextblock --prod",
70
+ "outputDirectory": "apps/nextblock/.next",
71
+ "framework": "nextjs"
72
+ }
73
+ ```
74
+
75
+ - **`buildCommand`** runs the Nx target from the repo root, which resolves the
76
+ workspace libraries (`@nextblock-cms/*` via the TS path aliases) and builds the app.
77
+ - **`outputDirectory`** points at the app's `.next`. This `@nx/next` version emits it
78
+ to `apps/nextblock/.next` — **not** `dist/apps/nextblock/.next` (which only receives
79
+ the deploy wrapper: `package.json`, `next.config.js`, `public/`). Verify with
80
+ `npx nx build nextblock --prod` then check `apps/nextblock/.next/BUILD_ID`.
81
+ - **`framework: nextjs`** keeps Vercel's first-class Next.js runtime (SSR/ISR
82
+ functions, image optimization, the `proxy.ts` middleware).
83
+
84
+ Leave the Vercel project's **Root Directory unset** (the repo root) — the build command
85
+ already targets the app. Do **not** set Root Directory to `apps/nextblock`: the app
86
+ imports the workspace libraries one level up, which a custom Root Directory would hide
87
+ (Vercel forbids `..` above a custom root).
88
+
89
+ ## No environment variables required
90
+
91
+ A Deploy-Button URL can only carry variable **names**, never values — so secrets can
92
+ never be pre-filled through it. Rather than make you paste random strings, NextBlock
93
+ resolves everything in-app, and the button prompts for nothing:
94
+
95
+ - **`NEXT_PUBLIC_URL`** — optional. When unset the app falls back to Vercel's
96
+ production URL (`VERCEL_PROJECT_PRODUCTION_URL` server-side /
97
+ `NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL` in the browser), i.e. your
98
+ `*.vercel.app` domain. Sitemap, robots, and canonical links use it automatically.
99
+ Add a custom domain later, set `NEXT_PUBLIC_URL=https://yourdomain.com` in the
100
+ Vercel project, and redeploy (it is inlined at build time).
101
+ - **`DRAFT_MODE_SECRET`** and **`REVALIDATE_SECRET_TOKEN`** — optional. When unset they
102
+ are derived deterministically from the Supabase service-role key (HMAC-SHA256), so
103
+ Draft Mode and on-demand revalidation work out of the box. Setting either env var
104
+ overrides the derived value — do this if you want a fixed `REVALIDATE_SECRET_TOKEN`
105
+ to paste into a Supabase revalidation webhook. (See `apps/nextblock/lib/app-secrets.ts`.)
106
+ - **`CRON_SECRET`** — optional. The cron endpoints enforce the `Authorization: Bearer`
107
+ header **only when it is set**. Leave it unset for a frictionless deploy, or set it
108
+ in the Vercel project to lock the cron endpoints down. The destructive
109
+ `/api/cron/reset-sandbox` job is independently gated to sandbox-mode only (404
110
+ otherwise), so it never runs on a normal deploy.
111
+
112
+ ## What the wizard does on Vercel
113
+
114
+ 1. **Database** — already connected (integration-injected). The wizard verifies a
115
+ first admin doesn't exist yet, otherwise it redirects to `/cms/dashboard`. The
116
+ connection step is **auto-skipped**.
117
+ 2. **Schema** — applied **automatically**. The Supabase integration creates the project
118
+ but does **not** run NextBlock's migrations, so the wizard applies them itself on the
119
+ final step: it runs the build-embedded migration bundle over the injected
120
+ `POSTGRES_URL` (no CLI, no manual SQL). Idempotent — a re-run is a no-op. See
121
+ [docs/04](./04-DATABASE-AND-AUTH.md) and [docs/05](./05-DEVELOPER-GUIDE.md).
122
+ 3. **Storage** — **skipped on Vercel; nothing to configure.** Media uses **native
123
+ Supabase Storage** through the already-connected project: the injected
124
+ `SUPABASE_SECRET_KEY` authenticates uploads/downloads/deletes via the Supabase client
125
+ (no S3 access keys required), a public `media` bucket is auto-created, and images are
126
+ served from `<project>/storage/v1/object/public/media/…`. The storage backend is
127
+ selected automatically (`apps/nextblock/lib/storage/provider.ts`): if S3/R2 keys are
128
+ present it uses them; otherwise it falls back to native Supabase Storage. (Cloudflare
129
+ R2 remains the default for non-Vercel installs — it has a more generous free storage
130
+ tier; set the `R2_*` env vars to use it on Vercel instead.)
131
+
132
+ > **Upload size:** the CMS media uploader proxies the file through a serverless
133
+ > function (`/api/upload/proxy`), which is subject to Vercel's ~4.5 MB request-body
134
+ > limit — larger single images fail on the Hobby/Pro serverless runtime regardless of
135
+ > storage backend. This is a platform constraint, not a NextBlock one.
136
+ 4. **Email / Bot protection / Sign-ups** — optional steps; bot-protection and the
137
+ sign-up policy persist to the database and work immediately. SMTP, if used, is set
138
+ as Vercel environment variables.
139
+ 5. **Administrator** — create the first admin. The account is created already
140
+ confirmed (`email_confirm: true`), so no verification email is required.
141
+
142
+ > Filesystem is read-only on Vercel, so the wizard never writes `.env.local` there —
143
+ > all configuration is environment variables (platform-managed) plus the database.
144
+
145
+ ## Cron jobs and the Hobby plan
146
+
147
+ `vercel.json` declares two crons (`/api/cron/reset-sandbox` at 03:00 and
148
+ `/api/cron/sync-currencies` at 18:00). Vercel's **Hobby (free) tier allows up to 100
149
+ cron jobs, each running at most once per day** — both jobs are daily, so they deploy
150
+ fine on the free tier. (Hobby timing is approximate, ±59 min, which is irrelevant for
151
+ daily jobs; only sub-daily schedules like `0 * * * *` are rejected on Hobby.)
152
+
153
+ `reset-sandbox` only does work in sandbox mode — it returns 404 otherwise — so on a
154
+ normal deploy it is a harmless no-op. Delete it from `vercel.json` if you'd rather not
155
+ see it scheduled.
156
+
157
+ ## After deploy
158
+
159
+ Visit the deployment URL — it redirects to `/setup` until the first admin exists.
160
+ Complete the wizard, then sign in at `/cms/dashboard`.
161
+
162
+ **Automatic updates.** The 1-click deploy creates a **new repository you own** (a copy —
163
+ *not* a GitHub fork) and ships a daily upstream-sync GitHub Action. Because it's your own
164
+ repo, **Actions are enabled by default — there's nothing to turn on**; the workflow runs
165
+ once it's on your **default branch**, and the dashboard onboarding step completes
166
+ automatically when GitHub registers it. We recommend keeping the repo **public** (fully
167
+ zero-config); a **private** repo additionally needs a `NEXTBLOCK_GITHUB_TOKEN` env var for
168
+ the in-CMS conflict banner. (Only a *manually-created GitHub fork* has Actions disabled
169
+ until you enable them on the Actions tab.) Full details — both tracks, conflict handling,
170
+ and build-time migrations — are in [docs/13](./13-STAYING-UP-TO-DATE.md).