create-nextblock 0.2.78 → 0.8.0
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.
- package/bin/create-nextblock.js +740 -459
- package/package.json +1 -2
- package/scripts/sync-template.js +18 -1
- package/templates/nextblock-template/.browserslistrc +11 -0
- package/templates/nextblock-template/.swcrc +30 -30
- package/templates/nextblock-template/README.md +23 -114
- package/templates/nextblock-template/app/(auth-pages)/post-sign-in/page.tsx +27 -28
- package/templates/nextblock-template/app/(auth-pages)/sign-in/page.tsx +50 -25
- package/templates/nextblock-template/app/(auth-pages)/sign-up/page.tsx +111 -56
- package/templates/nextblock-template/app/(auth-pages)/two-factor/actions.ts +91 -0
- package/templates/nextblock-template/app/(auth-pages)/two-factor/components/TwoFactorForm.tsx +118 -0
- package/templates/nextblock-template/app/(auth-pages)/two-factor/page.tsx +51 -0
- package/templates/nextblock-template/app/.well-known/ucp/route.ts +16 -0
- package/templates/nextblock-template/app/[slug]/PageClientContent.tsx +48 -28
- package/templates/nextblock-template/app/[slug]/page.tsx +63 -6
- package/templates/nextblock-template/app/[slug]/page.utils.ts +374 -157
- package/templates/nextblock-template/app/[slug]/pageClientActions.ts +7 -0
- package/templates/nextblock-template/app/actions/consent.ts +57 -0
- package/templates/nextblock-template/app/actions/formActions.ts +130 -11
- package/templates/nextblock-template/app/actions/languageActions.ts +31 -30
- package/templates/nextblock-template/app/actions/package-actions.ts +183 -0
- package/templates/nextblock-template/app/actions/postActions.ts +146 -48
- package/templates/nextblock-template/app/actions/twoFactorEmail.ts +21 -0
- package/templates/nextblock-template/app/actions/visualEditingActions.test.ts +179 -0
- package/templates/nextblock-template/app/actions/visualEditingActions.ts +345 -0
- package/templates/nextblock-template/app/actions.ts +67 -12
- package/templates/nextblock-template/app/api/ai/cortex/build-widget/route.ts +153 -0
- package/templates/nextblock-template/app/api/ai/generate-blocks/route.ts +96 -0
- package/templates/nextblock-template/app/api/ai/global-agent/route.ts +965 -0
- package/templates/nextblock-template/app/api/checkout/freemius/sync/route.ts +29 -0
- package/templates/nextblock-template/app/api/checkout/route.ts +146 -0
- package/templates/nextblock-template/app/api/cms/full-backup/export/route.ts +33 -0
- package/templates/nextblock-template/app/api/cms/full-backup/restore/route.ts +63 -0
- package/templates/nextblock-template/app/api/cron/reset-sandbox/route.ts +3413 -17
- package/templates/nextblock-template/app/api/cron/reset-sandbox/sandboxResetSql.ts +7830 -0
- package/templates/nextblock-template/app/api/cron/sync-currencies/route.ts +35 -0
- package/templates/nextblock-template/app/api/custom-blocks/db-relations/route.ts +92 -0
- package/templates/nextblock-template/app/api/custom-blocks/editor-definitions/route.ts +43 -0
- package/templates/nextblock-template/app/api/draft/disable/route.ts +25 -0
- package/templates/nextblock-template/app/api/draft/route.ts +93 -0
- package/templates/nextblock-template/app/api/draft/start/route.ts +77 -0
- package/templates/nextblock-template/app/api/media/library/route.ts +65 -0
- package/templates/nextblock-template/app/api/media/r2-presigned/route.ts +53 -0
- package/templates/nextblock-template/app/api/media/record/route.ts +160 -0
- package/templates/nextblock-template/app/api/search/route.ts +43 -0
- package/templates/nextblock-template/app/api/visual-editing/block-draft/route.ts +47 -0
- package/templates/nextblock-template/app/api/visual-editing/product-draft/route.ts +47 -0
- package/templates/nextblock-template/app/api/webhooks/freemius/route.ts +34 -0
- package/templates/nextblock-template/app/api/webhooks/stripe/route.ts +27 -0
- package/templates/nextblock-template/app/article/[slug]/PostClientContent.tsx +392 -128
- package/templates/nextblock-template/app/article/[slug]/page.tsx +179 -127
- package/templates/nextblock-template/app/article/[slug]/page.utils.ts +262 -77
- package/templates/nextblock-template/app/auth/callback/route.ts +31 -58
- package/templates/nextblock-template/app/cart/page.tsx +7 -0
- package/templates/nextblock-template/app/checkout/UcpCartHydrator.tsx +20 -0
- package/templates/nextblock-template/app/checkout/page.tsx +52 -0
- package/templates/nextblock-template/app/checkout/success/actions.ts +136 -0
- package/templates/nextblock-template/app/checkout/success/page.tsx +186 -0
- package/templates/nextblock-template/app/cms/CmsClientLayout.tsx +163 -33
- package/templates/nextblock-template/app/cms/blocks/actions.ts +424 -235
- package/templates/nextblock-template/app/cms/blocks/components/BackgroundSelector.tsx +212 -151
- package/templates/nextblock-template/app/cms/blocks/components/BlockEditorArea.tsx +41 -20
- package/templates/nextblock-template/app/cms/blocks/components/BlockEditorModal.tsx +152 -19
- package/templates/nextblock-template/app/cms/blocks/components/BlockTypeCard.tsx +25 -17
- package/templates/nextblock-template/app/cms/blocks/components/BlockTypeSelector.tsx +200 -18
- package/templates/nextblock-template/app/cms/blocks/components/ColumnEditor.tsx +33 -16
- package/templates/nextblock-template/app/cms/blocks/components/CustomBlockEditorPreview.tsx +160 -0
- package/templates/nextblock-template/app/cms/blocks/components/EditableBlock.tsx +37 -18
- package/templates/nextblock-template/app/cms/blocks/components/MediaLibraryModal.tsx +149 -67
- package/templates/nextblock-template/app/cms/blocks/components/SectionConfigPanel.tsx +108 -31
- package/templates/nextblock-template/app/cms/blocks/editors/DynamicCustomBlockEditor.tsx +167 -0
- package/templates/nextblock-template/app/cms/blocks/editors/FeaturedProductBlockEditor.tsx +31 -0
- package/templates/nextblock-template/app/cms/blocks/editors/FormBlockEditor.tsx +2 -2
- package/templates/nextblock-template/app/cms/blocks/editors/HeadingBlockEditor.tsx +1 -1
- package/templates/nextblock-template/app/cms/blocks/editors/ImageBlockEditor.tsx +29 -29
- package/templates/nextblock-template/app/cms/blocks/editors/PostsGridBlockEditor.tsx +14 -18
- package/templates/nextblock-template/app/cms/blocks/editors/ProductGridBlockEditor.tsx +41 -0
- package/templates/nextblock-template/app/cms/blocks/editors/SectionBlockEditor.tsx +318 -118
- package/templates/nextblock-template/app/cms/blocks/editors/TextBlockEditor.tsx +98 -21
- package/templates/nextblock-template/app/cms/blocks/editors/VideoEmbedBlockEditor.tsx +1 -1
- package/templates/nextblock-template/app/cms/components/ContentLanguageSwitcher.tsx +27 -9
- package/templates/nextblock-template/app/cms/components/CopyContentFromLanguage.tsx +1 -1
- package/templates/nextblock-template/app/cms/components/CortexAiActiveContext.tsx +23 -0
- package/templates/nextblock-template/app/cms/components/CortexAiPageContext.tsx +58 -0
- package/templates/nextblock-template/app/cms/components/CortexGlobalAgentChat.tsx +1507 -0
- package/templates/nextblock-template/app/cms/components/DraftStatusActions.tsx +145 -0
- package/templates/nextblock-template/app/cms/components/FeatureImageField.tsx +244 -0
- package/templates/nextblock-template/app/cms/components/FeedbackModal.tsx +38 -24
- package/templates/nextblock-template/app/cms/coupons/[id]/edit/page.tsx +16 -0
- package/templates/nextblock-template/app/cms/coupons/page.tsx +16 -0
- package/templates/nextblock-template/app/cms/custom-blocks/[id]/edit/page.tsx +66 -0
- package/templates/nextblock-template/app/cms/custom-blocks/actions.ts +519 -0
- package/templates/nextblock-template/app/cms/custom-blocks/components/BlockComposer.tsx +1522 -0
- package/templates/nextblock-template/app/cms/custom-blocks/components/BlocksLibraryTransferControls.tsx +256 -0
- package/templates/nextblock-template/app/cms/custom-blocks/components/DBRelationSelect.tsx +384 -0
- package/templates/nextblock-template/app/cms/custom-blocks/components/ImageR2Picker.tsx +221 -0
- package/templates/nextblock-template/app/cms/custom-blocks/new/page.tsx +12 -0
- package/templates/nextblock-template/app/cms/custom-blocks/page.tsx +438 -0
- package/templates/nextblock-template/app/cms/dashboard/actions.ts +228 -98
- package/templates/nextblock-template/app/cms/dashboard/components/DashboardComponents.tsx +200 -0
- package/templates/nextblock-template/app/cms/dashboard/page.tsx +182 -154
- package/templates/nextblock-template/app/cms/import-export/ContentTransferControls.tsx +391 -0
- package/templates/nextblock-template/app/cms/import-export/actions.ts +226 -0
- package/templates/nextblock-template/app/cms/layout.tsx +29 -10
- package/templates/nextblock-template/app/cms/media/UploadFolderContext.tsx +22 -22
- package/templates/nextblock-template/app/cms/media/actions.ts +45 -124
- package/templates/nextblock-template/app/cms/media/components/DeleteMediaButtonClient.tsx +1 -1
- package/templates/nextblock-template/app/cms/media/components/MediaEditForm.tsx +26 -26
- package/templates/nextblock-template/app/cms/media/components/MediaGridClient.tsx +69 -64
- package/templates/nextblock-template/app/cms/media/components/MediaPickerDialog.tsx +227 -158
- package/templates/nextblock-template/app/cms/media/components/MediaUploadForm.tsx +101 -89
- package/templates/nextblock-template/app/cms/media/page.tsx +1 -1
- package/templates/nextblock-template/app/cms/navigation/components/NavigationItemForm.tsx +2 -2
- package/templates/nextblock-template/app/cms/orders/[id]/MarkPaidButton.tsx +44 -0
- package/templates/nextblock-template/app/cms/orders/[id]/page.tsx +16 -0
- package/templates/nextblock-template/app/cms/orders/actions.ts +201 -0
- package/templates/nextblock-template/app/cms/orders/page.tsx +20 -0
- package/templates/nextblock-template/app/cms/orders/types.ts +20 -0
- package/templates/nextblock-template/app/cms/pages/[id]/edit/EditPageClient.tsx +156 -121
- package/templates/nextblock-template/app/cms/pages/[id]/edit/page.tsx +79 -26
- package/templates/nextblock-template/app/cms/pages/actions.ts +54 -38
- package/templates/nextblock-template/app/cms/pages/components/DeletePageButtonClient.tsx +1 -1
- package/templates/nextblock-template/app/cms/pages/components/PageForm.tsx +267 -116
- package/templates/nextblock-template/app/cms/pages/page.tsx +25 -18
- package/templates/nextblock-template/app/cms/payments/page.tsx +16 -0
- package/templates/nextblock-template/app/cms/posts/[id]/edit/page.tsx +132 -90
- package/templates/nextblock-template/app/cms/posts/actions.ts +71 -72
- package/templates/nextblock-template/app/cms/posts/components/DeletePostButtonClient.tsx +1 -1
- package/templates/nextblock-template/app/cms/posts/components/PostForm.tsx +256 -245
- package/templates/nextblock-template/app/cms/posts/new/page.tsx +1 -1
- package/templates/nextblock-template/app/cms/posts/page.tsx +20 -13
- package/templates/nextblock-template/app/cms/products/ClientNotionEditor.tsx +16 -0
- package/templates/nextblock-template/app/cms/products/ProductFormClientShell.tsx +56 -0
- package/templates/nextblock-template/app/cms/products/[id]/edit/page.tsx +292 -0
- package/templates/nextblock-template/app/cms/products/attributes/page.tsx +12 -0
- package/templates/nextblock-template/app/cms/products/categories/page.tsx +12 -0
- package/templates/nextblock-template/app/cms/products/inventory/page.tsx +13 -0
- package/templates/nextblock-template/app/cms/products/new/page.tsx +143 -0
- package/templates/nextblock-template/app/cms/products/page.tsx +42 -0
- package/templates/nextblock-template/app/cms/products/productFormData.ts +133 -0
- package/templates/nextblock-template/app/cms/products/settings/page.tsx +5 -0
- package/templates/nextblock-template/app/cms/promotions/PromotionsWorkspace.tsx +456 -0
- package/templates/nextblock-template/app/cms/promotions/actions.ts +115 -0
- package/templates/nextblock-template/app/cms/promotions/page.tsx +31 -0
- package/templates/nextblock-template/app/cms/revisions/RevisionHistoryButton.tsx +2 -2
- package/templates/nextblock-template/app/cms/revisions/actions.ts +285 -285
- package/templates/nextblock-template/app/cms/revisions/service.ts +19 -16
- package/templates/nextblock-template/app/cms/revisions/utils.ts +8 -3
- package/templates/nextblock-template/app/cms/settings/backup-restore/BackupRestoreWorkspace.tsx +1004 -0
- package/templates/nextblock-template/app/cms/settings/backup-restore/page.tsx +29 -0
- package/templates/nextblock-template/app/cms/settings/bot-protection/actions.ts +93 -0
- package/templates/nextblock-template/app/cms/settings/bot-protection/components/BotProtectionForm.tsx +129 -0
- package/templates/nextblock-template/app/cms/settings/bot-protection/page.tsx +24 -0
- package/templates/nextblock-template/app/cms/settings/copyright/actions.ts +1 -1
- package/templates/nextblock-template/app/cms/settings/copyright/components/CopyrightForm.tsx +2 -2
- package/templates/nextblock-template/app/cms/settings/copyright/page.tsx +1 -1
- package/templates/nextblock-template/app/cms/settings/cortex-ai/SandboxCortexAiSettingsClient.tsx +496 -0
- package/templates/nextblock-template/app/cms/settings/cortex-ai/StoredCortexAiSettingsClient.tsx +410 -0
- package/templates/nextblock-template/app/cms/settings/cortex-ai/actions.ts +248 -0
- package/templates/nextblock-template/app/cms/settings/cortex-ai/page.tsx +80 -0
- package/templates/nextblock-template/app/cms/settings/currencies/actions.ts +331 -0
- package/templates/nextblock-template/app/cms/settings/currencies/page.tsx +494 -0
- package/templates/nextblock-template/app/cms/settings/extra-translations/ExtraTranslationsWorkspace.tsx +767 -0
- package/templates/nextblock-template/app/cms/settings/extra-translations/actions.ts +203 -44
- package/templates/nextblock-template/app/cms/settings/extra-translations/page.tsx +93 -242
- package/templates/nextblock-template/app/cms/settings/global-css/actions.ts +65 -0
- package/templates/nextblock-template/app/cms/settings/global-css/components/GlobalCssForm.tsx +46 -0
- package/templates/nextblock-template/app/cms/settings/global-css/page.tsx +24 -0
- package/templates/nextblock-template/app/cms/settings/languages/components/DeleteLanguageButton.tsx +1 -1
- package/templates/nextblock-template/app/cms/settings/languages/components/LanguageForm.tsx +2 -2
- package/templates/nextblock-template/app/cms/settings/languages/page.tsx +1 -1
- package/templates/nextblock-template/app/cms/settings/logos/[id]/edit/page.tsx +7 -7
- package/templates/nextblock-template/app/cms/settings/logos/actions.ts +82 -6
- package/templates/nextblock-template/app/cms/settings/logos/components/BrandingSettingsForm.tsx +339 -0
- package/templates/nextblock-template/app/cms/settings/logos/components/DeleteLogoButton.tsx +21 -18
- package/templates/nextblock-template/app/cms/settings/logos/components/LogoForm.tsx +20 -16
- package/templates/nextblock-template/app/cms/settings/logos/components/SiteSeoSettingsForm.tsx +133 -0
- package/templates/nextblock-template/app/cms/settings/logos/new/page.tsx +8 -8
- package/templates/nextblock-template/app/cms/settings/logos/page.tsx +120 -82
- package/templates/nextblock-template/app/cms/settings/logos/types.ts +8 -8
- package/templates/nextblock-template/app/cms/settings/packages/activation-form.tsx +84 -0
- package/templates/nextblock-template/app/cms/settings/packages/package-card.tsx +122 -0
- package/templates/nextblock-template/app/cms/settings/packages/page.tsx +49 -0
- package/templates/nextblock-template/app/cms/settings/privacy/actions.ts +53 -0
- package/templates/nextblock-template/app/cms/settings/privacy/components/PrivacyForm.tsx +196 -0
- package/templates/nextblock-template/app/cms/settings/privacy/page.tsx +26 -0
- package/templates/nextblock-template/app/cms/settings/security/actions.ts +251 -0
- package/templates/nextblock-template/app/cms/settings/security/components/SecurityPanel.tsx +453 -0
- package/templates/nextblock-template/app/cms/settings/security/page.tsx +13 -0
- package/templates/nextblock-template/app/cms/settings/taxes/page.tsx +21 -0
- package/templates/nextblock-template/app/cms/shipping/page.tsx +20 -0
- package/templates/nextblock-template/app/cms/users/[id]/edit/page.tsx +28 -23
- package/templates/nextblock-template/app/cms/users/actions.ts +105 -40
- package/templates/nextblock-template/app/cms/users/components/DeleteUserButton.tsx +1 -1
- package/templates/nextblock-template/app/cms/users/components/UserForm.tsx +65 -152
- package/templates/nextblock-template/app/cms/users/page.tsx +15 -10
- package/templates/nextblock-template/app/globals.css +9 -0
- package/templates/nextblock-template/app/layout.tsx +372 -120
- package/templates/nextblock-template/app/lib/seo.test.ts +52 -0
- package/templates/nextblock-template/app/lib/seo.ts +279 -0
- package/templates/nextblock-template/app/lib/site-settings.ts +87 -0
- package/templates/nextblock-template/app/lib/sitemap-utils.ts +224 -39
- package/templates/nextblock-template/app/lib/ucp/protocol.ts +190 -0
- package/templates/nextblock-template/app/lib/ucp/server.test.ts +56 -0
- package/templates/nextblock-template/app/lib/ucp/server.ts +1914 -0
- package/templates/nextblock-template/app/page.tsx +165 -73
- package/templates/nextblock-template/app/product/[slug]/page.tsx +433 -0
- package/templates/nextblock-template/app/profile/ProfileAccountSidebar.tsx +73 -0
- package/templates/nextblock-template/app/profile/ProfilePageHeader.tsx +16 -0
- package/templates/nextblock-template/app/profile/ProfilePageMissingState.tsx +9 -0
- package/templates/nextblock-template/app/profile/account-data.ts +37 -0
- package/templates/nextblock-template/app/profile/account-links.ts +22 -0
- package/templates/nextblock-template/app/profile/account-types.ts +11 -0
- package/templates/nextblock-template/app/profile/orders/CustomerOrdersPageClient.tsx +124 -0
- package/templates/nextblock-template/app/profile/orders/[id]/CustomerOrderDetailPageClient.tsx +79 -0
- package/templates/nextblock-template/app/profile/orders/[id]/page.tsx +32 -0
- package/templates/nextblock-template/app/profile/orders/page.tsx +19 -0
- package/templates/nextblock-template/app/profile/page.tsx +51 -0
- package/templates/nextblock-template/app/profile/password/PasswordSettingsPageClient.tsx +128 -0
- package/templates/nextblock-template/app/profile/password/actions.ts +59 -0
- package/templates/nextblock-template/app/profile/password/page.tsx +27 -0
- package/templates/nextblock-template/app/providers.tsx +55 -17
- package/templates/nextblock-template/app/robots.txt/route.ts +11 -1
- package/templates/nextblock-template/app/sitemap.ts +128 -0
- package/templates/nextblock-template/app/ucp/v1/carts/[id]/cancel/route.ts +38 -0
- package/templates/nextblock-template/app/ucp/v1/carts/[id]/route.ts +68 -0
- package/templates/nextblock-template/app/ucp/v1/carts/route.ts +35 -0
- package/templates/nextblock-template/app/ucp/v1/catalog/lookup/route.ts +35 -0
- package/templates/nextblock-template/app/ucp/v1/catalog/product/route.ts +35 -0
- package/templates/nextblock-template/app/ucp/v1/catalog/search/route.ts +34 -0
- package/templates/nextblock-template/components/AppShell.tsx +154 -0
- package/templates/nextblock-template/components/BlockRenderer.tsx +210 -64
- package/templates/nextblock-template/components/CartDrawerLoader.tsx +7 -0
- package/templates/nextblock-template/components/CartTranslator.tsx +210 -0
- package/templates/nextblock-template/components/CurrentContentSetter.tsx +25 -0
- package/templates/nextblock-template/components/DeferredCartDrawer.tsx +23 -0
- package/templates/nextblock-template/components/DeferredCartTranslator.tsx +51 -0
- package/templates/nextblock-template/components/DeferredGlobalSearch.tsx +68 -0
- package/templates/nextblock-template/components/DeferredGoogleTagManager.tsx +70 -0
- package/templates/nextblock-template/components/DeferredSpeedInsights.tsx +69 -0
- package/templates/nextblock-template/components/FeatureImageHero.tsx +47 -0
- package/templates/nextblock-template/components/GitHubLoginButton.tsx +36 -0
- package/templates/nextblock-template/components/GlobalSearch.tsx +557 -0
- package/templates/nextblock-template/components/Header.tsx +49 -41
- package/templates/nextblock-template/components/LanguageSwitcher.tsx +55 -32
- package/templates/nextblock-template/components/ResponsiveNav.tsx +138 -43
- package/templates/nextblock-template/components/blocks/PostCardSkeleton.tsx +12 -8
- package/templates/nextblock-template/components/blocks/PostsGridBlock.tsx +12 -55
- package/templates/nextblock-template/components/blocks/PostsGridClient.tsx +42 -37
- package/templates/nextblock-template/components/blocks/TestimonialBlock.tsx +6 -2
- package/templates/nextblock-template/components/blocks/ecommerceRendererLoaders.ts +23 -0
- package/templates/nextblock-template/components/blocks/publicRendererLoaders.ts +25 -0
- package/templates/nextblock-template/components/blocks/renderers/ButtonBlockRenderer.tsx +92 -84
- package/templates/nextblock-template/components/blocks/renderers/CartBlockRenderer.tsx +17 -0
- package/templates/nextblock-template/components/blocks/renderers/CheckoutBlockRenderer.tsx +19 -0
- package/templates/nextblock-template/components/blocks/renderers/ClientTextBlockRenderer.tsx +262 -8
- package/templates/nextblock-template/components/blocks/renderers/FeaturedProductBlockRenderer.tsx +22 -0
- package/templates/nextblock-template/components/blocks/renderers/FormBlockRenderer.tsx +320 -37
- package/templates/nextblock-template/components/blocks/renderers/HeadingBlockRenderer.tsx +11 -8
- package/templates/nextblock-template/components/blocks/renderers/ImageBlockRenderer.tsx +12 -3
- package/templates/nextblock-template/components/blocks/renderers/PostsGridBlockRenderer.tsx +18 -13
- package/templates/nextblock-template/components/blocks/renderers/ProductDetailsBlockRenderer.tsx +90 -0
- package/templates/nextblock-template/components/blocks/renderers/ProductGridBlockRenderer.tsx +31 -0
- package/templates/nextblock-template/components/blocks/renderers/SectionBlockRenderer.tsx +424 -55
- package/templates/nextblock-template/components/blocks/renderers/SectionSlider.tsx +137 -0
- package/templates/nextblock-template/components/blocks/renderers/TestimonialBlockRenderer.tsx +57 -0
- package/templates/nextblock-template/components/blocks/renderers/TextBlockRenderer.tsx +37 -22
- package/templates/nextblock-template/components/blocks/renderers/VideoEmbedBlockRenderer.tsx +23 -15
- package/templates/nextblock-template/components/blocks/renderers/inline/AlertWidgetRenderer.tsx +1 -3
- package/templates/nextblock-template/components/blocks/renderers/inline/CtaWidgetRenderer.tsx +1 -3
- package/templates/nextblock-template/components/blocks/types.ts +7 -6
- package/templates/nextblock-template/components/env-var-warning.tsx +3 -3
- package/templates/nextblock-template/components/form-message.tsx +32 -26
- package/templates/nextblock-template/components/header-auth.tsx +69 -17
- package/templates/nextblock-template/components/privacy/ConsentBanner.tsx +127 -0
- package/templates/nextblock-template/components/privacy/ConsentGatedAnalytics.tsx +59 -0
- package/templates/nextblock-template/components/renderers/CachedDynamicLayoutEngine.tsx +28 -0
- package/templates/nextblock-template/components/renderers/DynamicLayoutEngine.test.tsx +166 -0
- package/templates/nextblock-template/components/renderers/DynamicLayoutEngine.tsx +464 -0
- package/templates/nextblock-template/components/theme-switcher.tsx +8 -8
- package/templates/nextblock-template/components/visual-editing/DeferredVisualEditing.tsx +21 -0
- package/templates/nextblock-template/components/visual-editing/NextblockVisualEditing.tsx +1172 -0
- package/templates/nextblock-template/context/AuthContext.tsx +23 -90
- package/templates/nextblock-template/context/CurrentContentContext.tsx +10 -4
- package/templates/nextblock-template/context/LanguageContext.tsx +16 -16
- package/templates/nextblock-template/context/language-rest-client.ts +31 -0
- package/templates/nextblock-template/docs/01-PROJECT-OVERVIEW.md +94 -0
- package/templates/nextblock-template/docs/02-ECOMMERCE-CAPABILITIES.md +364 -0
- package/templates/nextblock-template/docs/03-CMS-AND-EDITOR.md +202 -0
- package/templates/nextblock-template/docs/04-DATABASE-AND-AUTH.md +252 -0
- package/templates/nextblock-template/docs/05-DEVELOPER-GUIDE.md +238 -0
- package/templates/nextblock-template/docs/06-CLI-AND-SCAFFOLDING.md +125 -0
- package/templates/nextblock-template/docs/07-BLOCK-SDK-AND-EXTENSIBILITY.md +146 -0
- package/templates/nextblock-template/docs/08-NEXTBLOCK-CORTEX-AI-ARCHITECTURE.md +1319 -0
- package/templates/nextblock-template/docs/09-LIVE-DRAFT-MODE.md +104 -0
- package/templates/nextblock-template/docs/10-CUSTOM-BLOCKS.md +222 -0
- package/templates/nextblock-template/docs/README.md +34 -0
- package/templates/nextblock-template/docs/TECHNICAL_SPECIFICATION.md +12507 -0
- package/templates/nextblock-template/hooks/use-hotkeys.ts +21 -14
- package/templates/nextblock-template/hooks/useGlobalSearch.ts +101 -0
- package/templates/nextblock-template/index.d.ts +2 -0
- package/templates/nextblock-template/lib/ai-block-generation.ts +339 -0
- package/templates/nextblock-template/lib/ai-client.ts +247 -0
- package/templates/nextblock-template/lib/ai-config.ts +81 -0
- package/templates/nextblock-template/lib/ai-cortex-widget-builder.ts +125 -0
- package/templates/nextblock-template/lib/ai-global-agent-custom-block-tools.ts +363 -0
- package/templates/nextblock-template/lib/ai-global-agent-db-tools.test.ts +405 -0
- package/templates/nextblock-template/lib/ai-global-agent-db-tools.ts +1228 -0
- package/templates/nextblock-template/lib/ai-global-agent-ecommerce.ts +5 -0
- package/templates/nextblock-template/lib/ai-global-agent-tools-stats.test.ts +223 -0
- package/templates/nextblock-template/lib/ai-global-agent-tools.test.ts +2183 -0
- package/templates/nextblock-template/lib/ai-global-agent-tools.ts +4807 -0
- package/templates/nextblock-template/lib/ai-key-crypto.test.ts +70 -0
- package/templates/nextblock-template/lib/ai-key-crypto.ts +132 -0
- package/templates/nextblock-template/lib/ai-model-catalog.test.ts +49 -0
- package/templates/nextblock-template/lib/ai-model-catalog.ts +41 -0
- package/templates/nextblock-template/lib/ai-model-registry.test.ts +231 -0
- package/templates/nextblock-template/lib/ai-model-registry.ts +522 -0
- package/templates/nextblock-template/lib/auth/cookies.ts +47 -0
- package/templates/nextblock-template/lib/auth/crypto.ts +42 -0
- package/templates/nextblock-template/lib/auth/trustedDevices.ts +92 -0
- package/templates/nextblock-template/lib/auth/twoFactor.ts +167 -0
- package/templates/nextblock-template/lib/auth-redirects.ts +46 -0
- package/templates/nextblock-template/lib/blocks/FeaturedProductBlock.tsx +94 -0
- package/templates/nextblock-template/lib/blocks/ProductGridBlock.tsx +137 -0
- package/templates/nextblock-template/lib/blocks/README.md +13 -670
- package/templates/nextblock-template/lib/blocks/blockRegistry.ts +138 -56
- package/templates/nextblock-template/lib/blocks/blockTypes.ts +18 -0
- package/templates/nextblock-template/lib/blocks/ecommerce-block-schemas.ts +31 -0
- package/templates/nextblock-template/lib/cms-transfer/csv.test.ts +77 -0
- package/templates/nextblock-template/lib/cms-transfer/csv.ts +399 -0
- package/templates/nextblock-template/lib/cms-transfer/server.ts +2243 -0
- package/templates/nextblock-template/lib/cms-transfer/types.ts +145 -0
- package/templates/nextblock-template/lib/cortex-widget-registry.test.ts +199 -0
- package/templates/nextblock-template/lib/cortex-widget-registry.ts +88 -0
- package/templates/nextblock-template/lib/cortex-widget-schema.test.tsx +237 -0
- package/templates/nextblock-template/lib/cortex-widget-schema.ts +393 -0
- package/templates/nextblock-template/lib/custom-block-definitions.ts +87 -0
- package/templates/nextblock-template/lib/custom-block-r2-upload-shared.ts +178 -0
- package/templates/nextblock-template/lib/custom-block-r2-upload.test.ts +140 -0
- package/templates/nextblock-template/lib/custom-block-r2-upload.ts +68 -0
- package/templates/nextblock-template/lib/custom-block-relation-registry.ts +256 -0
- package/templates/nextblock-template/lib/custom-block-relations.test.ts +227 -0
- package/templates/nextblock-template/lib/custom-block-relations.ts +279 -0
- package/templates/nextblock-template/lib/custom-block-safelist.ts +14 -0
- package/templates/nextblock-template/lib/editor/dynamic-extension-core.test.ts +172 -0
- package/templates/nextblock-template/lib/editor/dynamic-extension-core.ts +213 -0
- package/templates/nextblock-template/lib/editor/dynamic-extension-loader.ts +22 -0
- package/templates/nextblock-template/lib/editor/dynamic-extensions.tsx +193 -0
- package/templates/nextblock-template/lib/full-backup/manifest.test.ts +121 -0
- package/templates/nextblock-template/lib/full-backup/manifest.ts +206 -0
- package/templates/nextblock-template/lib/full-backup/server.ts +743 -0
- package/templates/nextblock-template/lib/media/resolveMediaUrl.ts +45 -0
- package/templates/nextblock-template/lib/posts/readTime.ts +60 -0
- package/templates/nextblock-template/lib/privacy/consent-client.ts +57 -0
- package/templates/nextblock-template/lib/privacy/settings.ts +103 -0
- package/templates/nextblock-template/lib/privacy/types.ts +67 -0
- package/templates/nextblock-template/lib/promotions/server.test.ts +74 -0
- package/templates/nextblock-template/lib/promotions/server.ts +741 -0
- package/templates/nextblock-template/lib/resolve-block-relations.test.ts +142 -0
- package/templates/nextblock-template/lib/resolve-block-relations.ts +255 -0
- package/templates/nextblock-template/lib/search/server.ts +585 -0
- package/templates/nextblock-template/lib/search/types.ts +27 -0
- package/templates/nextblock-template/lib/visual-editing/draft-content.test.ts +105 -0
- package/templates/nextblock-template/lib/visual-editing/draft-content.ts +380 -0
- package/templates/nextblock-template/lib/visual-editing/draft-route.test.ts +42 -0
- package/templates/nextblock-template/lib/visual-editing/draft-route.ts +82 -0
- package/templates/nextblock-template/lib/visual-editing/edit-info.test.ts +143 -0
- package/templates/nextblock-template/lib/visual-editing/edit-info.ts +94 -0
- package/templates/nextblock-template/lib/visual-editing/mutations.ts +190 -0
- package/templates/nextblock-template/lib/visual-editing/product-drafts.test.ts +81 -0
- package/templates/nextblock-template/lib/visual-editing/product-drafts.ts +511 -0
- package/templates/nextblock-template/lib/visual-editing/types.ts +122 -0
- package/templates/nextblock-template/lib/zod-config.ts +5 -0
- package/templates/nextblock-template/next.config.js +190 -66
- package/templates/nextblock-template/package.json +34 -30
- package/templates/nextblock-template/proxy.ts +435 -253
- package/templates/nextblock-template/public/images/NBcover.webp +0 -0
- package/templates/nextblock-template/public/images/cap.webp +0 -0
- package/templates/nextblock-template/public/images/commerce-plan.webp +0 -0
- package/templates/nextblock-template/public/images/commerce-square.webp +0 -0
- package/templates/nextblock-template/public/images/commerce-wide.webp +0 -0
- package/templates/nextblock-template/public/images/cortex-ai-square.webp +0 -0
- package/templates/nextblock-template/public/images/cortex-ai.webp +0 -0
- package/templates/nextblock-template/public/images/extensibility.webp +0 -0
- package/templates/nextblock-template/public/images/goals.webp +0 -0
- package/templates/nextblock-template/public/images/included.webp +0 -0
- package/templates/nextblock-template/public/images/nx-graph.webp +0 -0
- package/templates/nextblock-template/public/images/pants.webp +0 -0
- package/templates/nextblock-template/public/images/t-shirt.webp +0 -0
- package/templates/nextblock-template/scripts/validate-editor-block-schema.ts +112 -0
- package/templates/nextblock-template/scripts/verify-cortex-ai-build-widget.tsx +100 -0
- package/templates/nextblock-template/scripts/verify-cortex-ai-generate-blocks.ts +62 -0
- package/templates/nextblock-template/scripts/verify-cortex-ai-global-tools.ts +537 -0
- package/templates/nextblock-template/scripts/verify-cortex-ai-routing.ts +58 -0
- package/templates/nextblock-template/scripts/verify-custom-block-definitions.ts +188 -0
- package/templates/nextblock-template/scripts/verify-dynamic-custom-block-extensions.ts +123 -0
- package/templates/nextblock-template/scripts/verify-dynamic-layout-engine.tsx +133 -0
- package/templates/nextblock-template/scripts/verify-milestone-2-custom-blocks.ts +65 -0
- package/templates/nextblock-template/tailwind.config.js +1 -0
- package/templates/nextblock-template/tools/configure-supabase-auth.js +282 -0
- package/templates/nextblock-template/tools/deploy-supabase.js +69 -71
- package/templates/nextblock-template/tsconfig.json +52 -66
- package/templates/nextblock-template/tsconfig.tsbuildinfo +1 -1
- package/templates/nextblock-template/types/jsdom.d.ts +6 -0
- package/templates/nextblock-template/app/force-styles.tsx +0 -31
- package/templates/nextblock-template/app/sitemap.xml/route.ts +0 -63
- package/templates/nextblock-template/components/blocks/renderers/HeroBlockRenderer.tsx +0 -273
- package/templates/nextblock-template/docs/How to Create a Custom Block.md +0 -149
- package/templates/nextblock-template/docs/cms-application-overview.md +0 -56
- package/templates/nextblock-template/docs/cms-architecture-overview.md +0 -73
- package/templates/nextblock-template/docs/files-structure.md +0 -426
- package/templates/nextblock-template/docs/tiptap-bundle-optimization-summary.md +0 -174
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Live Draft Mode
|
|
2
|
+
|
|
3
|
+
NextBlock features a real-time visual editing environment called **Live Draft Mode**. It allows editors to click on page elements, blocks, and product fields directly in the frontend website to edit them in-place, saving changes as non-destructive draft versions before publishing them to the live site.
|
|
4
|
+
|
|
5
|
+
This document describes the architectural design, API endpoints, database schema, component integrations, and local verification steps for Live Draft Mode.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 1. Architecture Overview
|
|
10
|
+
|
|
11
|
+
```mermaid
|
|
12
|
+
sequenceDiagram
|
|
13
|
+
participant User as Editor (Admin/Writer)
|
|
14
|
+
participant Front as Next.js Frontend
|
|
15
|
+
participant API as Draft API Routes
|
|
16
|
+
participant DB as Supabase Database
|
|
17
|
+
|
|
18
|
+
User->>Front: Click "Edit Page" / Edit URL
|
|
19
|
+
Front->>API: GET /api/draft/start?path=/slug
|
|
20
|
+
API->>DB: Check if slug exists (.limit(1))
|
|
21
|
+
DB-->>API: Returns target document
|
|
22
|
+
API-->>Front: Enable Next.js Draft Mode (Cookies)
|
|
23
|
+
Front->>User: Renders visual editing overlays
|
|
24
|
+
User->>Front: Click block/field to edit
|
|
25
|
+
Front->>DB: Read/Write to drafts table (content_drafts/product_drafts)
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Live Draft Mode consists of:
|
|
29
|
+
1. **Next.js Draft Mode Endpoints**: Verifies document existence and sets Next.js draft-mode headers/cookies.
|
|
30
|
+
2. **Visual Editing Overlays**: DOM attributes (e.g., `data-vercel-edit-info`) that identify editable documents and fields.
|
|
31
|
+
3. **Draft Tables**: Database tables (`content_drafts` and `product_drafts`) that store structural block snapshots and metadata.
|
|
32
|
+
4. **Draft Mutations**: Server actions (`loadVisualEditingBlockContent`, `saveVisualEditingBlockDraft`) to perform non-destructive updates.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## 2. Draft API Endpoints
|
|
37
|
+
|
|
38
|
+
NextBlock has two primary draft entry-point routes:
|
|
39
|
+
* `/api/draft` - Validates token/secret and redirects to the target page with draft mode active.
|
|
40
|
+
* `/api/draft/start` - Checks current user session authorization and document existence, then starts draft mode.
|
|
41
|
+
|
|
42
|
+
### Target Existence Verification
|
|
43
|
+
To support multi-language routing, NextBlock allows identical slugs to exist across different languages (e.g., `/articles` can exist in both English and French translation trees).
|
|
44
|
+
* **Fix**: Endpoints verify existence using `.limit(1)` rather than `.maybeSingle()`. This prevents Postgrest errors (`PGRST116: multiple rows returned`) when querying shared slugs.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## 3. Database Schema
|
|
49
|
+
|
|
50
|
+
Draft data is separated from live production data to ensure non-destructive previewing.
|
|
51
|
+
|
|
52
|
+
### Content Drafts (`content_drafts`)
|
|
53
|
+
Stores page and post drafts.
|
|
54
|
+
* `parent_type`: `"page" | "post"`
|
|
55
|
+
* `parent_id`: Foreign key reference to page/post ID (integer).
|
|
56
|
+
* `meta`: JSONB object storing draft metadata (title, slug, status, meta fields).
|
|
57
|
+
* `blocks`: JSONB array storing all draft blocks associated with the page/post.
|
|
58
|
+
|
|
59
|
+
### Product Drafts (`product_drafts`)
|
|
60
|
+
Stores product drafts.
|
|
61
|
+
* `product_id`: Foreign key reference to product ID (UUID string).
|
|
62
|
+
* `meta`: JSONB object storing draft product metadata (title, short description, sku, price, etc.).
|
|
63
|
+
* `blocks`: JSONB array storing draft description blocks (rich layout).
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## 4. Visual Editing Integration
|
|
68
|
+
|
|
69
|
+
Frontend components use the `visualEditing` context to render hover overlays.
|
|
70
|
+
|
|
71
|
+
### Top-Level & Nested Blocks
|
|
72
|
+
Top-level blocks are rendered using `BlockRenderer.tsx`. For each block, `buildVisualEditAttributes()` generates:
|
|
73
|
+
* `data-vercel-edit-info`: Encodes document type, ID, slug, language, and block target (index/ID).
|
|
74
|
+
* `data-vercel-edit-target`: Target parameters for nested block structures.
|
|
75
|
+
* `data-nextblock-visual-edit`: UI identifier (e.g., `top-level:section`).
|
|
76
|
+
|
|
77
|
+
### Product-Level Visual Editing
|
|
78
|
+
Products support two kinds of visual editing:
|
|
79
|
+
1. **Field-Level Editing**: Modifying plain-text fields like `title` and `short_description`. Handled in `ProductDetailsLayout.tsx`.
|
|
80
|
+
2. **Block-Level Description**: Editing block layouts within the product detail description. Handled via `ProductDetailsBlockRenderer.tsx`.
|
|
81
|
+
|
|
82
|
+
> [!IMPORTANT]
|
|
83
|
+
> **Click Bubbling Prevention**: When block-level descriptions are rendered, the parent wrapper disables the outer `description_json` field editor attributes. This ensures clicks on individual description blocks edit the blocks themselves, avoiding `Invalid product field editor` conflicts.
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## 5. Local Verification
|
|
88
|
+
|
|
89
|
+
To test Live Draft Mode locally:
|
|
90
|
+
|
|
91
|
+
1. **Verify Session Authorization**:
|
|
92
|
+
Make sure you are signed in as an `ADMIN` or `WRITER` in the CMS.
|
|
93
|
+
2. **Enter Draft Mode**:
|
|
94
|
+
Visit the start draft endpoint for any page, post, or product path:
|
|
95
|
+
```http
|
|
96
|
+
GET http://localhost:3000/api/draft/start?path=/product/my-product-slug
|
|
97
|
+
```
|
|
98
|
+
3. **Inspect Overlays**:
|
|
99
|
+
Hover over the page sections. Hover frames and edit buttons should appear.
|
|
100
|
+
4. **Run Automated Tests**:
|
|
101
|
+
Verify draft routing rules using the test suite:
|
|
102
|
+
```powershell
|
|
103
|
+
npx vitest run apps/nextblock/lib/visual-editing/draft-route.test.ts
|
|
104
|
+
```
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
# 10 Custom Blocks (Data-Driven CRUD)
|
|
2
|
+
|
|
3
|
+
NextBlock lets editors create their own block types at runtime, directly from
|
|
4
|
+
the CMS, with no code deploy. A custom block is defined as data — typed fields
|
|
5
|
+
plus a recursive layout schema — stored in Supabase and rendered on the public
|
|
6
|
+
site by a dynamic layout engine instead of a compiled React component.
|
|
7
|
+
|
|
8
|
+
This is a separate, complementary system to the code-defined built-in blocks in
|
|
9
|
+
`apps/nextblock/lib/blocks/blockRegistry.ts`. See
|
|
10
|
+
[03-CMS-AND-EDITOR.md](./03-CMS-AND-EDITOR.md) for the built-in block system and
|
|
11
|
+
[07-BLOCK-SDK-AND-EXTENSIBILITY.md](./07-BLOCK-SDK-AND-EXTENSIBILITY.md) for how
|
|
12
|
+
the three extensibility layers relate.
|
|
13
|
+
|
|
14
|
+
## The Core Idea
|
|
15
|
+
|
|
16
|
+
- A **custom block definition** is a row in `custom_block_definitions`.
|
|
17
|
+
- A **custom block instance** is just an ordinary `blocks` row whose
|
|
18
|
+
`block_type` equals a definition's `slug`.
|
|
19
|
+
|
|
20
|
+
Because an instance is a normal block, custom blocks drop into the page builder
|
|
21
|
+
exactly like built-ins: they can sit at the top level of a page/post or nest
|
|
22
|
+
inside `section` columns, and they participate in ordering, drag-and-drop, and
|
|
23
|
+
revisions without special-casing.
|
|
24
|
+
|
|
25
|
+
## Data Model
|
|
26
|
+
|
|
27
|
+
The table is created in
|
|
28
|
+
`libs/db/src/supabase/migrations/00000000000023_setup_custom_block_definitions.sql`.
|
|
29
|
+
|
|
30
|
+
`public.custom_block_definitions`:
|
|
31
|
+
|
|
32
|
+
| Column | Notes |
|
|
33
|
+
| :-- | :-- |
|
|
34
|
+
| `id` | `uuid` primary key |
|
|
35
|
+
| `slug` | unique, `^[a-z][a-z0-9-]*$`; this is the block instance's `block_type` |
|
|
36
|
+
| `name` | display name (non-empty) |
|
|
37
|
+
| `description` | optional, defaults to `''` |
|
|
38
|
+
| `fields` | `jsonb` field declarations; DB `CHECK` via `is_valid_custom_block_fields()` |
|
|
39
|
+
| `layout_schema` | `jsonb` layout tree; DB `CHECK` via `is_valid_custom_block_layout_schema()` |
|
|
40
|
+
| `is_original` | `false` when the row was produced by duplicating another definition |
|
|
41
|
+
|
|
42
|
+
The migration also defines:
|
|
43
|
+
|
|
44
|
+
- `is_valid_custom_block_fields(jsonb)` and
|
|
45
|
+
`is_valid_custom_block_layout_schema(jsonb)` — immutable validation functions
|
|
46
|
+
used as table `CHECK` constraints, so malformed definitions are rejected at
|
|
47
|
+
the database layer even if application validation is bypassed.
|
|
48
|
+
- `duplicate_block_definition(target_id uuid)` — `SECURITY DEFINER` RPC that
|
|
49
|
+
copies a definition, auto-suffixing the slug (`-copy`, `-copy-2`, …), naming
|
|
50
|
+
it `"<name> Copy"`, and setting `is_original = false`. Restricted to
|
|
51
|
+
`ADMIN`/`WRITER` (or `service_role`).
|
|
52
|
+
|
|
53
|
+
### Row Level Security
|
|
54
|
+
|
|
55
|
+
- Public `SELECT` (definitions must be readable to render on the public site).
|
|
56
|
+
- `INSERT` / `UPDATE` / `DELETE` for authenticated users whose role is `ADMIN`
|
|
57
|
+
or `WRITER`.
|
|
58
|
+
- Full access for `service_role`.
|
|
59
|
+
|
|
60
|
+
## Field Types
|
|
61
|
+
|
|
62
|
+
Application-side schemas live in `libs/utils/src/lib/custom-blocks.ts` and are
|
|
63
|
+
exported from `@nextblock-cms/utils`. Every field shares a base of `key`
|
|
64
|
+
(`^[a-z][a-z0-9_]*$`, unique within a block), `label`, optional `description`,
|
|
65
|
+
and `required`. The `type` discriminates four variants:
|
|
66
|
+
|
|
67
|
+
| Type | Purpose | Notable options |
|
|
68
|
+
| :-- | :-- | :-- |
|
|
69
|
+
| `text` | single-line / plain text | `default_value`, `placeholder`, `min_length`, `max_length` |
|
|
70
|
+
| `rich-text` | HTML rich text | `default_value`, `placeholder` |
|
|
71
|
+
| `image_r2` | image stored in R2 | `accept[]`, `max_bytes`, `default_value` = `{ object_key, url, alt, width, height, … }` |
|
|
72
|
+
| `db_relation` | reference rows in a table | `table`, `value_column` (default `id`), `display_column` (default `title`), `multiple`, `filters` |
|
|
73
|
+
|
|
74
|
+
The CMS authoring components map onto these types: `ImageR2Picker` for
|
|
75
|
+
`image_r2`, `DBRelationSelect` for `db_relation`, and the rich-text editor for
|
|
76
|
+
`rich-text`.
|
|
77
|
+
|
|
78
|
+
## Layout Schema
|
|
79
|
+
|
|
80
|
+
`layout_schema` is a recursive discriminated union (`customBlockLayoutNodeSchema`)
|
|
81
|
+
with two node types:
|
|
82
|
+
|
|
83
|
+
- **`container`** — `{ type: 'container', as?, className?, children: [] }`.
|
|
84
|
+
Groups other nodes.
|
|
85
|
+
- **`field_render`** — `{ type: 'field_render', field_key, as?, className?,
|
|
86
|
+
column?, emptyFallback? }`. Renders a single field's value.
|
|
87
|
+
|
|
88
|
+
Rules and helpers:
|
|
89
|
+
|
|
90
|
+
- `as` is restricted to a safe HTML element set (`article`, `aside`,
|
|
91
|
+
`blockquote`, `div`, `figure`, `figcaption`, `h2`, `h3`, `img`, `p`,
|
|
92
|
+
`section`, `span`).
|
|
93
|
+
- `className` accepts Tailwind utility classes.
|
|
94
|
+
- `column` lets a `field_render` bound to a `db_relation` field surface a
|
|
95
|
+
specific column of the resolved record, so one relation field can render
|
|
96
|
+
several columns (e.g. a product's title and price). `emptyFallback` renders
|
|
97
|
+
when the value is empty.
|
|
98
|
+
- Every `field_key` referenced in the layout must exist in `fields`
|
|
99
|
+
(`assertLayoutFieldKeysExist` enforces this in `customBlockDefinitionCreateSchema`).
|
|
100
|
+
- `orderCustomBlockFieldsByLayout()` orders fields to match the layout's
|
|
101
|
+
depth-first `field_render` order for the editor form; `buildCustomBlockCopySlug()`
|
|
102
|
+
mirrors the SQL duplicate-slug logic on the client.
|
|
103
|
+
|
|
104
|
+
Exported Zod surfaces: `customBlockDefinitionCreateSchema`,
|
|
105
|
+
`customBlockDefinitionUpdateSchema`, and `customBlockDefinitionRowSchema`, with
|
|
106
|
+
inferred types `CustomBlockDefinition`, `CustomBlockDefinitionCreateInput`, and
|
|
107
|
+
`CustomBlockDefinitionUpdateInput`.
|
|
108
|
+
|
|
109
|
+
## CMS CRUD Surface
|
|
110
|
+
|
|
111
|
+
Everything lives under `apps/nextblock/app/cms/custom-blocks`:
|
|
112
|
+
|
|
113
|
+
- `page.tsx` — searchable grid/list of definitions with duplicate and delete.
|
|
114
|
+
- `new/page.tsx` and `[id]/edit/page.tsx` — authoring screens.
|
|
115
|
+
- `components/BlockComposer.tsx` — the field + layout composer.
|
|
116
|
+
- `components/DBRelationSelect.tsx`, `components/ImageR2Picker.tsx` — field-type
|
|
117
|
+
editors.
|
|
118
|
+
- `components/BlocksLibraryTransferControls.tsx` — import/export UI.
|
|
119
|
+
|
|
120
|
+
Server actions in `app/cms/custom-blocks/actions.ts` all gate on
|
|
121
|
+
`requireCmsWriter` (`ADMIN`/`WRITER`) and revalidate the
|
|
122
|
+
`custom-block-definitions` cache tag plus `/cms/blocks` and `/cms/custom-blocks`:
|
|
123
|
+
|
|
124
|
+
- `listCustomBlockDefinitions`, `getCustomBlockDefinition`
|
|
125
|
+
- `createCustomBlockDefinition`, `updateCustomBlockDefinition`,
|
|
126
|
+
`deleteCustomBlockDefinition`
|
|
127
|
+
- `duplicateCustomBlockDefinition` (calls the `duplicate_block_definition` RPC)
|
|
128
|
+
- `exportBlocksLibraryAction`, `dryRunBlocksLibraryImportAction`,
|
|
129
|
+
`applyBlocksLibraryImportAction`
|
|
130
|
+
|
|
131
|
+
## Rendering
|
|
132
|
+
|
|
133
|
+
The loader is `apps/nextblock/lib/custom-block-definitions.ts`:
|
|
134
|
+
|
|
135
|
+
- `getCachedCustomBlockDefinitions()` and
|
|
136
|
+
`getCachedCustomBlockDefinitionBySlug()` read through `getSsgSupabaseClient`
|
|
137
|
+
and `unstable_cache` (tag `custom-block-definitions`, 60s revalidate).
|
|
138
|
+
- The by-slug path falls back to a live (uncached) read when the cache misses,
|
|
139
|
+
so a freshly saved block renders immediately instead of showing
|
|
140
|
+
"Unsupported block type" during the revalidation window.
|
|
141
|
+
|
|
142
|
+
`apps/nextblock/components/BlockRenderer.tsx` dispatches blocks: if a
|
|
143
|
+
`block_type` has no built-in renderer, it looks the slug up via
|
|
144
|
+
`getCachedCustomBlockDefinitionBySlug()` and renders through
|
|
145
|
+
`CachedDynamicLayoutEngine` (which wraps
|
|
146
|
+
`components/renderers/DynamicLayoutEngine.tsx`). The dynamic engine walks the
|
|
147
|
+
`layout_schema`, renders `container` nodes as their `as` element with the given
|
|
148
|
+
classes, and resolves each `field_render` against the instance content
|
|
149
|
+
(including `db_relation` lookups). If neither a built-in renderer nor a custom
|
|
150
|
+
definition matches, the renderer shows an "Unsupported block type" notice with
|
|
151
|
+
the offending slug.
|
|
152
|
+
|
|
153
|
+
CMS-side editing of an instance uses
|
|
154
|
+
`app/cms/blocks/editors/DynamicCustomBlockEditor.tsx` and
|
|
155
|
+
`app/cms/blocks/components/CustomBlockEditorPreview.tsx`.
|
|
156
|
+
|
|
157
|
+
## Import / Export / Backup / Restore
|
|
158
|
+
|
|
159
|
+
Custom blocks are portable as a JSON "Blocks Library" bundle. The backend is
|
|
160
|
+
`apps/nextblock/lib/cms-transfer/server.ts`:
|
|
161
|
+
|
|
162
|
+
- `exportBlocksLibraryBundle()` serializes all definitions.
|
|
163
|
+
- `dryRunBlocksLibraryImport()` previews an import without writing.
|
|
164
|
+
- `applyBlocksLibraryImport()` applies it.
|
|
165
|
+
|
|
166
|
+
A bundle entry (`BackupCustomBlockRecord` in
|
|
167
|
+
`apps/nextblock/lib/cms-transfer/types.ts`) carries `slug`, `name`,
|
|
168
|
+
`description`, `fields`, `layout_schema`, and `is_original`. Imports run under a
|
|
169
|
+
conflict mode of `create_new` or `overwrite_existing`, and return a summary of
|
|
170
|
+
`created` / `updated` / `skipped` rows plus warnings and errors. Exports are
|
|
171
|
+
named `nextblock-blocks-library-<YYYY-MM-DD>.json`.
|
|
172
|
+
|
|
173
|
+
Custom blocks also ride along inside the broader content backup bundle
|
|
174
|
+
(`CmsBackupBundleV1.custom_blocks`, optional for backward compatibility),
|
|
175
|
+
surfaced at `/cms/import-export` via `ContentTransferControls.tsx`.
|
|
176
|
+
|
|
177
|
+
## Cortex AI "Build Widget"
|
|
178
|
+
|
|
179
|
+
Cortex AI can generate a custom block definition from a prompt:
|
|
180
|
+
|
|
181
|
+
- Route: `apps/nextblock/app/api/ai/cortex/build-widget/route.ts`.
|
|
182
|
+
- Helpers: `apps/nextblock/lib/cortex-widget-registry.ts` and the custom-block
|
|
183
|
+
agent tools in `apps/nextblock/lib/ai-global-agent-custom-block-tools.ts`.
|
|
184
|
+
- After a Cortex-driven change, the front end dispatches a
|
|
185
|
+
`nextblock:cortex-data-changed` event; the custom-blocks list listens for it
|
|
186
|
+
(and for window focus) and refetches so the library stays in sync without a
|
|
187
|
+
reload.
|
|
188
|
+
|
|
189
|
+
See [08-NEXTBLOCK-CORTEX-AI-ARCHITECTURE.md](./08-NEXTBLOCK-CORTEX-AI-ARCHITECTURE.md)
|
|
190
|
+
for the surrounding AI architecture and credential model.
|
|
191
|
+
|
|
192
|
+
## Verification
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
# Validate the custom block definition schemas / fixtures
|
|
196
|
+
npx tsx apps/nextblock/scripts/verify-custom-block-definitions.ts
|
|
197
|
+
|
|
198
|
+
# Exercise the dynamic layout engine
|
|
199
|
+
npx tsx apps/nextblock/scripts/verify-dynamic-layout-engine.tsx
|
|
200
|
+
|
|
201
|
+
# Cortex AI widget builder (needs OPENROUTER_API_KEY or stored BYOK)
|
|
202
|
+
npm run verify:cortex-ai-build-widget
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
Relevant Vitest files:
|
|
206
|
+
|
|
207
|
+
- `apps/nextblock/components/renderers/DynamicLayoutEngine.test.tsx`
|
|
208
|
+
- `apps/nextblock/lib/cortex-widget-registry.test.ts`
|
|
209
|
+
- `apps/nextblock/lib/cortex-widget-schema.test.tsx`
|
|
210
|
+
|
|
211
|
+
## Notes for Contributors
|
|
212
|
+
|
|
213
|
+
- `custom_block_definitions` was added after the squashed migration baseline
|
|
214
|
+
(migration `00000000000023`). Per the production rule in
|
|
215
|
+
[05-DEVELOPER-GUIDE.md](./05-DEVELOPER-GUIDE.md) and the root `AGENTS.md`,
|
|
216
|
+
schema changes here must be new, forward-only migrations.
|
|
217
|
+
- After changing the table or seed data, regenerate the sandbox reset payload
|
|
218
|
+
with `npm run generate:sandbox` (the generated SQL already includes the
|
|
219
|
+
custom blocks migration).
|
|
220
|
+
- The slug is the public contract: renaming a definition's slug orphans every
|
|
221
|
+
existing instance that references the old slug (they fall back to
|
|
222
|
+
"Unsupported block type" until re-pointed).
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# NextBlock CMS Documentation
|
|
2
|
+
|
|
3
|
+
This folder is the source-of-truth reference set for the NextBlock monorepo.
|
|
4
|
+
The numbered files are written from live code, routes, migrations, and shipped
|
|
5
|
+
library surfaces rather than historical planning notes.
|
|
6
|
+
|
|
7
|
+
## Start Here
|
|
8
|
+
|
|
9
|
+
- Product and architecture overview: [01-PROJECT-OVERVIEW.md](./01-PROJECT-OVERVIEW.md)
|
|
10
|
+
- Commerce capabilities: [02-ECOMMERCE-CAPABILITIES.md](./02-ECOMMERCE-CAPABILITIES.md)
|
|
11
|
+
- CMS editor and block system: [03-CMS-AND-EDITOR.md](./03-CMS-AND-EDITOR.md)
|
|
12
|
+
- Database, auth, and migrations: [04-DATABASE-AND-AUTH.md](./04-DATABASE-AND-AUTH.md)
|
|
13
|
+
- Contributor workflow and local operations: [05-DEVELOPER-GUIDE.md](./05-DEVELOPER-GUIDE.md)
|
|
14
|
+
- CLI and scaffolded project flow: [06-CLI-AND-SCAFFOLDING.md](./06-CLI-AND-SCAFFOLDING.md)
|
|
15
|
+
- Block SDK and extensibility surface: [07-BLOCK-SDK-AND-EXTENSIBILITY.md](./07-BLOCK-SDK-AND-EXTENSIBILITY.md)
|
|
16
|
+
- Cortex AI architecture: [08-NEXTBLOCK-CORTEX-AI-ARCHITECTURE.md](./08-NEXTBLOCK-CORTEX-AI-ARCHITECTURE.md)
|
|
17
|
+
- Live draft (visual editing) mode: [09-LIVE-DRAFT-MODE.md](./09-LIVE-DRAFT-MODE.md)
|
|
18
|
+
- Custom blocks (data-driven CRUD): [10-CUSTOM-BLOCKS.md](./10-CUSTOM-BLOCKS.md)
|
|
19
|
+
|
|
20
|
+
## Audience Guide
|
|
21
|
+
|
|
22
|
+
- New contributors: read `01`, then `04`, then `05`.
|
|
23
|
+
- Commerce work: read `02`, then `04`.
|
|
24
|
+
- Editor or page-builder work: read `03`, then `07`.
|
|
25
|
+
- Custom block work: read `03`, then `10`.
|
|
26
|
+
- AI / Cortex work: read `08`.
|
|
27
|
+
- CLI or template work: read `06`.
|
|
28
|
+
- AI agents: start with this index, then move directly to the subsystem file that
|
|
29
|
+
matches the task. Treat `apps/nextblock`, `libs/*`, and
|
|
30
|
+
`libs/db/src/supabase/migrations` as the final authority if a doc and code ever
|
|
31
|
+
disagree.
|
|
32
|
+
- AI agents touching migrations must also read the root `AGENTS.md` note:
|
|
33
|
+
production/shared database changes are append-only and non-destructive by
|
|
34
|
+
default.
|