create-nextblock 0.0.1
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 +997 -0
- package/package.json +25 -0
- package/scripts/sync-template.js +284 -0
- package/templates/nextblock-template/.env.example +37 -0
- package/templates/nextblock-template/.swcrc +30 -0
- package/templates/nextblock-template/README.md +194 -0
- package/templates/nextblock-template/app/(auth-pages)/forgot-password/page.tsx +57 -0
- package/templates/nextblock-template/app/(auth-pages)/layout.tsx +9 -0
- package/templates/nextblock-template/app/(auth-pages)/post-sign-in/page.tsx +28 -0
- package/templates/nextblock-template/app/(auth-pages)/sign-in/page.tsx +67 -0
- package/templates/nextblock-template/app/(auth-pages)/sign-up/page.tsx +70 -0
- package/templates/nextblock-template/app/ToasterProvider.tsx +17 -0
- package/templates/nextblock-template/app/[slug]/PageClientContent.tsx +147 -0
- package/templates/nextblock-template/app/[slug]/page.tsx +145 -0
- package/templates/nextblock-template/app/[slug]/page.utils.ts +183 -0
- package/templates/nextblock-template/app/actions/email.ts +31 -0
- package/templates/nextblock-template/app/actions/formActions.ts +65 -0
- package/templates/nextblock-template/app/actions/languageActions.ts +130 -0
- package/templates/nextblock-template/app/actions/postActions.ts +80 -0
- package/templates/nextblock-template/app/actions.ts +146 -0
- package/templates/nextblock-template/app/api/process-image/route.ts +210 -0
- package/templates/nextblock-template/app/api/revalidate/route.ts +86 -0
- package/templates/nextblock-template/app/api/revalidate-log/route.ts +23 -0
- package/templates/nextblock-template/app/api/upload/presigned-url/route.ts +106 -0
- package/templates/nextblock-template/app/api/upload/proxy/route.ts +84 -0
- package/templates/nextblock-template/app/auth/callback/route.ts +58 -0
- package/templates/nextblock-template/app/blog/[slug]/PostClientContent.tsx +169 -0
- package/templates/nextblock-template/app/blog/[slug]/page.tsx +177 -0
- package/templates/nextblock-template/app/blog/[slug]/page.utils.ts +136 -0
- package/templates/nextblock-template/app/blog/page.tsx +77 -0
- package/templates/nextblock-template/app/cms/CmsClientLayout.tsx +321 -0
- package/templates/nextblock-template/app/cms/blocks/actions.ts +434 -0
- package/templates/nextblock-template/app/cms/blocks/components/BackgroundSelector.tsx +348 -0
- package/templates/nextblock-template/app/cms/blocks/components/BlockEditorArea.tsx +567 -0
- package/templates/nextblock-template/app/cms/blocks/components/BlockEditorModal.tsx +98 -0
- package/templates/nextblock-template/app/cms/blocks/components/BlockTypeCard.tsx +58 -0
- package/templates/nextblock-template/app/cms/blocks/components/BlockTypeSelector.tsx +62 -0
- package/templates/nextblock-template/app/cms/blocks/components/ColumnEditor.tsx +276 -0
- package/templates/nextblock-template/app/cms/blocks/components/DeleteBlockButtonClient.tsx +47 -0
- package/templates/nextblock-template/app/cms/blocks/components/EditableBlock.tsx +182 -0
- package/templates/nextblock-template/app/cms/blocks/components/MediaLibraryModal.tsx +120 -0
- package/templates/nextblock-template/app/cms/blocks/components/SectionConfigPanel.tsx +133 -0
- package/templates/nextblock-template/app/cms/blocks/components/SortableBlockItem.tsx +46 -0
- package/templates/nextblock-template/app/cms/blocks/editors/ButtonBlockEditor.tsx +85 -0
- package/templates/nextblock-template/app/cms/blocks/editors/FormBlockEditor.tsx +182 -0
- package/templates/nextblock-template/app/cms/blocks/editors/HeadingBlockEditor.tsx +111 -0
- package/templates/nextblock-template/app/cms/blocks/editors/ImageBlockEditor.tsx +150 -0
- package/templates/nextblock-template/app/cms/blocks/editors/PostsGridBlockEditor.tsx +79 -0
- package/templates/nextblock-template/app/cms/blocks/editors/SectionBlockEditor.tsx +337 -0
- package/templates/nextblock-template/app/cms/blocks/editors/TextBlockEditor.tsx +81 -0
- package/templates/nextblock-template/app/cms/blocks/editors/VideoEmbedBlockEditor.tsx +64 -0
- package/templates/nextblock-template/app/cms/components/ConfirmationModal.tsx +51 -0
- package/templates/nextblock-template/app/cms/components/ContentLanguageSwitcher.tsx +145 -0
- package/templates/nextblock-template/app/cms/components/CopyContentFromLanguage.tsx +203 -0
- package/templates/nextblock-template/app/cms/components/LanguageFilterSelect.tsx +69 -0
- package/templates/nextblock-template/app/cms/dashboard/page.tsx +247 -0
- package/templates/nextblock-template/app/cms/layout.tsx +10 -0
- package/templates/nextblock-template/app/cms/media/UploadFolderContext.tsx +22 -0
- package/templates/nextblock-template/app/cms/media/[id]/edit/page.tsx +80 -0
- package/templates/nextblock-template/app/cms/media/actions.ts +577 -0
- package/templates/nextblock-template/app/cms/media/components/DeleteMediaButtonClient.tsx +53 -0
- package/templates/nextblock-template/app/cms/media/components/FolderNavigator.tsx +273 -0
- package/templates/nextblock-template/app/cms/media/components/FolderTree.tsx +122 -0
- package/templates/nextblock-template/app/cms/media/components/MediaEditForm.tsx +157 -0
- package/templates/nextblock-template/app/cms/media/components/MediaGridClient.tsx +275 -0
- package/templates/nextblock-template/app/cms/media/components/MediaImage.tsx +70 -0
- package/templates/nextblock-template/app/cms/media/components/MediaPickerDialog.tsx +195 -0
- package/templates/nextblock-template/app/cms/media/components/MediaUploadForm.tsx +362 -0
- package/templates/nextblock-template/app/cms/media/page.tsx +120 -0
- package/templates/nextblock-template/app/cms/navigation/[id]/edit/page.tsx +101 -0
- package/templates/nextblock-template/app/cms/navigation/actions.ts +358 -0
- package/templates/nextblock-template/app/cms/navigation/components/DeleteNavItemButton.tsx +52 -0
- package/templates/nextblock-template/app/cms/navigation/components/NavigationItemForm.tsx +248 -0
- package/templates/nextblock-template/app/cms/navigation/components/NavigationLanguageSwitcher.tsx +132 -0
- package/templates/nextblock-template/app/cms/navigation/components/NavigationMenuDnd.tsx +701 -0
- package/templates/nextblock-template/app/cms/navigation/components/SortableNavItem.tsx +98 -0
- package/templates/nextblock-template/app/cms/navigation/new/page.tsx +26 -0
- package/templates/nextblock-template/app/cms/navigation/page.tsx +102 -0
- package/templates/nextblock-template/app/cms/navigation/utils.ts +51 -0
- package/templates/nextblock-template/app/cms/pages/[id]/edit/EditPageClient.tsx +121 -0
- package/templates/nextblock-template/app/cms/pages/[id]/edit/page.tsx +79 -0
- package/templates/nextblock-template/app/cms/pages/actions.ts +241 -0
- package/templates/nextblock-template/app/cms/pages/components/DeletePageButtonClient.tsx +47 -0
- package/templates/nextblock-template/app/cms/pages/components/PageForm.tsx +253 -0
- package/templates/nextblock-template/app/cms/pages/new/page.tsx +52 -0
- package/templates/nextblock-template/app/cms/pages/page.tsx +232 -0
- package/templates/nextblock-template/app/cms/posts/[id]/edit/page.tsx +183 -0
- package/templates/nextblock-template/app/cms/posts/actions.ts +309 -0
- package/templates/nextblock-template/app/cms/posts/components/DeletePostButtonClient.tsx +55 -0
- package/templates/nextblock-template/app/cms/posts/components/PostForm.tsx +419 -0
- package/templates/nextblock-template/app/cms/posts/new/page.tsx +21 -0
- package/templates/nextblock-template/app/cms/posts/page.tsx +192 -0
- package/templates/nextblock-template/app/cms/revisions/JsonDiffView.tsx +86 -0
- package/templates/nextblock-template/app/cms/revisions/RevisionHistoryButton.tsx +201 -0
- package/templates/nextblock-template/app/cms/revisions/actions.ts +84 -0
- package/templates/nextblock-template/app/cms/revisions/service.ts +344 -0
- package/templates/nextblock-template/app/cms/revisions/utils.ts +127 -0
- package/templates/nextblock-template/app/cms/settings/copyright/actions.ts +68 -0
- package/templates/nextblock-template/app/cms/settings/copyright/components/CopyrightForm.tsx +78 -0
- package/templates/nextblock-template/app/cms/settings/copyright/page.tsx +32 -0
- package/templates/nextblock-template/app/cms/settings/extra-translations/actions.ts +117 -0
- package/templates/nextblock-template/app/cms/settings/extra-translations/page.tsx +216 -0
- package/templates/nextblock-template/app/cms/settings/languages/[id]/edit/page.tsx +77 -0
- package/templates/nextblock-template/app/cms/settings/languages/actions.ts +261 -0
- package/templates/nextblock-template/app/cms/settings/languages/components/DeleteLanguageButton.tsx +76 -0
- package/templates/nextblock-template/app/cms/settings/languages/components/LanguageForm.tsx +167 -0
- package/templates/nextblock-template/app/cms/settings/languages/new/page.tsx +34 -0
- package/templates/nextblock-template/app/cms/settings/languages/page.tsx +156 -0
- package/templates/nextblock-template/app/cms/settings/logos/[id]/edit/page.tsx +19 -0
- package/templates/nextblock-template/app/cms/settings/logos/actions.ts +114 -0
- package/templates/nextblock-template/app/cms/settings/logos/components/LogoForm.tsx +177 -0
- package/templates/nextblock-template/app/cms/settings/logos/new/page.tsx +11 -0
- package/templates/nextblock-template/app/cms/settings/logos/page.tsx +118 -0
- package/templates/nextblock-template/app/cms/settings/logos/types.ts +8 -0
- package/templates/nextblock-template/app/cms/users/[id]/edit/page.tsx +91 -0
- package/templates/nextblock-template/app/cms/users/actions.ts +156 -0
- package/templates/nextblock-template/app/cms/users/components/DeleteUserButton.tsx +71 -0
- package/templates/nextblock-template/app/cms/users/components/UserForm.tsx +138 -0
- package/templates/nextblock-template/app/cms/users/page.tsx +183 -0
- package/templates/nextblock-template/app/favicon.ico +0 -0
- package/templates/nextblock-template/app/globals.css +401 -0
- package/templates/nextblock-template/app/layout.tsx +191 -0
- package/templates/nextblock-template/app/lib/sitemap-utils.ts +68 -0
- package/templates/nextblock-template/app/page.tsx +109 -0
- package/templates/nextblock-template/app/providers.tsx +43 -0
- package/templates/nextblock-template/app/robots.txt/route.ts +19 -0
- package/templates/nextblock-template/app/sitemap.xml/route.ts +63 -0
- package/templates/nextblock-template/app/unauthorized/page.tsx +27 -0
- package/templates/nextblock-template/backup/backup_2025-06-19.sql +8057 -0
- package/templates/nextblock-template/backup/backup_2025-06-20.sql +8159 -0
- package/templates/nextblock-template/backup/backup_2025-07-08.sql +8411 -0
- package/templates/nextblock-template/backup/backup_2025-07-09.sql +8442 -0
- package/templates/nextblock-template/backup/backup_2025-07-10.sql +8442 -0
- package/templates/nextblock-template/backup/backup_2025-10-01.sql +8803 -0
- package/templates/nextblock-template/backup/backup_2025-10-02.sql +9749 -0
- package/templates/nextblock-template/components/BlockRenderer.tsx +119 -0
- package/templates/nextblock-template/components/FooterNavigation.tsx +33 -0
- package/templates/nextblock-template/components/Header.tsx +42 -0
- package/templates/nextblock-template/components/HtmlScriptExecutor.tsx +47 -0
- package/templates/nextblock-template/components/LanguageSwitcher.tsx +103 -0
- package/templates/nextblock-template/components/ResponsiveNav.tsx +372 -0
- package/templates/nextblock-template/components/blocks/PostCardSkeleton.tsx +17 -0
- package/templates/nextblock-template/components/blocks/PostsGridBlock.tsx +93 -0
- package/templates/nextblock-template/components/blocks/PostsGridClient.tsx +180 -0
- package/templates/nextblock-template/components/blocks/renderers/ButtonBlockRenderer.tsx +92 -0
- package/templates/nextblock-template/components/blocks/renderers/ClientTextBlockRenderer.tsx +69 -0
- package/templates/nextblock-template/components/blocks/renderers/FormBlockRenderer.tsx +98 -0
- package/templates/nextblock-template/components/blocks/renderers/HeadingBlockRenderer.tsx +41 -0
- package/templates/nextblock-template/components/blocks/renderers/HeroBlockRenderer.tsx +240 -0
- package/templates/nextblock-template/components/blocks/renderers/ImageBlockRenderer.tsx +79 -0
- package/templates/nextblock-template/components/blocks/renderers/PostsGridBlockRenderer.tsx +33 -0
- package/templates/nextblock-template/components/blocks/renderers/SectionBlockRenderer.tsx +189 -0
- package/templates/nextblock-template/components/blocks/renderers/TextBlockRenderer.tsx +31 -0
- package/templates/nextblock-template/components/blocks/renderers/VideoEmbedBlockRenderer.tsx +59 -0
- package/templates/nextblock-template/components/blocks/renderers/inline/AlertWidgetRenderer.tsx +51 -0
- package/templates/nextblock-template/components/blocks/renderers/inline/CtaWidgetRenderer.tsx +40 -0
- package/templates/nextblock-template/components/blocks/types.ts +8 -0
- package/templates/nextblock-template/components/env-var-warning.tsx +33 -0
- package/templates/nextblock-template/components/form-message.tsx +26 -0
- package/templates/nextblock-template/components/header-auth.tsx +71 -0
- package/templates/nextblock-template/components/submit-button.tsx +23 -0
- package/templates/nextblock-template/components/theme-switcher.tsx +78 -0
- package/templates/nextblock-template/context/AuthContext.tsx +138 -0
- package/templates/nextblock-template/context/CurrentContentContext.tsx +42 -0
- package/templates/nextblock-template/context/LanguageContext.tsx +206 -0
- package/templates/nextblock-template/docs/cms-application-overview.md +56 -0
- package/templates/nextblock-template/docs/cms-architecture-overview.md +73 -0
- package/templates/nextblock-template/docs/files-structure.md +426 -0
- package/templates/nextblock-template/docs/tiptap-bundle-optimization-summary.md +174 -0
- package/templates/nextblock-template/eslint.config.mjs +28 -0
- package/templates/nextblock-template/index.d.ts +5 -0
- package/templates/nextblock-template/lib/blocks/README.md +670 -0
- package/templates/nextblock-template/lib/blocks/blockRegistry.ts +1001 -0
- package/templates/nextblock-template/lib/ui/ColorPicker.ts +1 -0
- package/templates/nextblock-template/lib/ui/ConfirmationDialog.ts +1 -0
- package/templates/nextblock-template/lib/ui/CustomSelectWithInput.ts +1 -0
- package/templates/nextblock-template/lib/ui/Skeleton.ts +1 -0
- package/templates/nextblock-template/lib/ui/avatar.ts +1 -0
- package/templates/nextblock-template/lib/ui/badge.ts +1 -0
- package/templates/nextblock-template/lib/ui/button.ts +1 -0
- package/templates/nextblock-template/lib/ui/card.ts +1 -0
- package/templates/nextblock-template/lib/ui/checkbox.ts +1 -0
- package/templates/nextblock-template/lib/ui/dialog.ts +1 -0
- package/templates/nextblock-template/lib/ui/dropdown-menu.ts +1 -0
- package/templates/nextblock-template/lib/ui/input.ts +1 -0
- package/templates/nextblock-template/lib/ui/label.ts +1 -0
- package/templates/nextblock-template/lib/ui/popover.ts +1 -0
- package/templates/nextblock-template/lib/ui/progress.ts +1 -0
- package/templates/nextblock-template/lib/ui/select.ts +1 -0
- package/templates/nextblock-template/lib/ui/separator.ts +1 -0
- package/templates/nextblock-template/lib/ui/table.ts +1 -0
- package/templates/nextblock-template/lib/ui/textarea.ts +1 -0
- package/templates/nextblock-template/lib/ui/tooltip.ts +1 -0
- package/templates/nextblock-template/lib/ui/ui.ts +1 -0
- package/templates/nextblock-template/middleware.ts +206 -0
- package/templates/nextblock-template/next-env.d.ts +6 -0
- package/templates/nextblock-template/next.config.js +99 -0
- package/templates/nextblock-template/package.json +52 -0
- package/templates/nextblock-template/postcss.config.js +6 -0
- package/templates/nextblock-template/project.json +7 -0
- package/templates/nextblock-template/public/.gitkeep +0 -0
- package/templates/nextblock-template/scripts/backfill-image-meta.ts +149 -0
- package/templates/nextblock-template/scripts/backup.js +53 -0
- package/templates/nextblock-template/scripts/test-bundle-optimization.js +114 -0
- package/templates/nextblock-template/tailwind.config.ts +19 -0
- package/templates/nextblock-template/tsconfig.json +62 -0
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
├── .editorconfig
|
|
2
|
+
├── .env.exemple
|
|
3
|
+
├── .gitignore
|
|
4
|
+
├── .prettierignore
|
|
5
|
+
├── .prettierrc
|
|
6
|
+
├── .verdaccio
|
|
7
|
+
└── config.yml
|
|
8
|
+
├── .vscode
|
|
9
|
+
├── extensions.json
|
|
10
|
+
└── settings.json
|
|
11
|
+
├── LICENSE.md
|
|
12
|
+
├── README.md
|
|
13
|
+
├── apps
|
|
14
|
+
└── nextblock
|
|
15
|
+
│ ├── .swcrc
|
|
16
|
+
│ ├── README.md
|
|
17
|
+
│ ├── app
|
|
18
|
+
│ ├── (auth-pages)
|
|
19
|
+
│ │ ├── forgot-password
|
|
20
|
+
│ │ │ └── page.tsx
|
|
21
|
+
│ │ ├── layout.tsx
|
|
22
|
+
│ │ ├── post-sign-in
|
|
23
|
+
│ │ │ └── page.tsx
|
|
24
|
+
│ │ ├── sign-in
|
|
25
|
+
│ │ │ └── page.tsx
|
|
26
|
+
│ │ └── sign-up
|
|
27
|
+
│ │ │ └── page.tsx
|
|
28
|
+
│ ├── [slug]
|
|
29
|
+
│ │ ├── PageClientContent.tsx
|
|
30
|
+
│ │ ├── page.tsx
|
|
31
|
+
│ │ └── page.utils.ts
|
|
32
|
+
│ ├── actions.ts
|
|
33
|
+
│ ├── actions
|
|
34
|
+
│ │ ├── email.ts
|
|
35
|
+
│ │ ├── formActions.ts
|
|
36
|
+
│ │ ├── languageActions.ts
|
|
37
|
+
│ │ └── postActions.ts
|
|
38
|
+
│ ├── api
|
|
39
|
+
│ │ ├── process-image
|
|
40
|
+
│ │ │ └── route.ts
|
|
41
|
+
│ │ ├── revalidate-log
|
|
42
|
+
│ │ │ └── route.ts
|
|
43
|
+
│ │ ├── revalidate
|
|
44
|
+
│ │ │ └── route.ts
|
|
45
|
+
│ │ └── upload
|
|
46
|
+
│ │ │ ├── presigned-url
|
|
47
|
+
│ │ │ └── route.ts
|
|
48
|
+
│ │ │ └── proxy
|
|
49
|
+
│ │ │ └── route.ts
|
|
50
|
+
│ ├── auth
|
|
51
|
+
│ │ └── callback
|
|
52
|
+
│ │ │ └── route.ts
|
|
53
|
+
│ ├── blog
|
|
54
|
+
│ │ ├── [slug]
|
|
55
|
+
│ │ │ ├── PostClientContent.tsx
|
|
56
|
+
│ │ │ ├── page.tsx
|
|
57
|
+
│ │ │ └── page.utils.ts
|
|
58
|
+
│ │ └── page.tsx
|
|
59
|
+
│ ├── cms
|
|
60
|
+
│ │ ├── CmsClientLayout.tsx
|
|
61
|
+
│ │ ├── blocks
|
|
62
|
+
│ │ │ ├── actions.ts
|
|
63
|
+
│ │ │ ├── components
|
|
64
|
+
│ │ │ │ ├── BackgroundSelector.tsx
|
|
65
|
+
│ │ │ │ ├── BlockEditorArea.tsx
|
|
66
|
+
│ │ │ │ ├── BlockEditorModal.tsx
|
|
67
|
+
│ │ │ │ ├── BlockTypeCard.tsx
|
|
68
|
+
│ │ │ │ ├── BlockTypeSelector.tsx
|
|
69
|
+
│ │ │ │ ├── ColumnEditor.tsx
|
|
70
|
+
│ │ │ │ ├── DeleteBlockButtonClient.tsx
|
|
71
|
+
│ │ │ │ ├── DynamicRichTextEditor.tsx
|
|
72
|
+
│ │ │ │ ├── EditableBlock.tsx
|
|
73
|
+
│ │ │ │ ├── MediaLibraryModal.tsx
|
|
74
|
+
│ │ │ │ ├── MenuBar.tsx
|
|
75
|
+
│ │ │ │ ├── RichTextEditor.tsx
|
|
76
|
+
│ │ │ │ ├── RoleAwareRichTextEditor.tsx
|
|
77
|
+
│ │ │ │ ├── SectionConfigPanel.tsx
|
|
78
|
+
│ │ │ │ ├── SortableBlockItem.tsx
|
|
79
|
+
│ │ │ │ └── tiptap-extensions
|
|
80
|
+
│ │ │ │ │ ├── AlertWidgetNode.ts
|
|
81
|
+
│ │ │ │ │ ├── CtaWidgetNode.ts
|
|
82
|
+
│ │ │ │ │ ├── DivNode.ts
|
|
83
|
+
│ │ │ │ │ ├── FontSizeMark.ts
|
|
84
|
+
│ │ │ │ │ ├── PreserveAllAttributesExtension.ts
|
|
85
|
+
│ │ │ │ │ ├── StyleTagNode.ts
|
|
86
|
+
│ │ │ │ │ └── components
|
|
87
|
+
│ │ │ │ │ ├── AlertWidgetComponent.tsx
|
|
88
|
+
│ │ │ │ │ └── CtaWidgetComponent.tsx
|
|
89
|
+
│ │ │ └── editors
|
|
90
|
+
│ │ │ │ ├── ButtonBlockEditor.tsx
|
|
91
|
+
│ │ │ │ ├── FormBlockEditor.tsx
|
|
92
|
+
│ │ │ │ ├── HeadingBlockEditor.tsx
|
|
93
|
+
│ │ │ │ ├── ImageBlockEditor.tsx
|
|
94
|
+
│ │ │ │ ├── PostsGridBlockEditor.tsx
|
|
95
|
+
│ │ │ │ ├── SectionBlockEditor.tsx
|
|
96
|
+
│ │ │ │ ├── TextBlockEditor.tsx
|
|
97
|
+
│ │ │ │ └── VideoEmbedBlockEditor.tsx
|
|
98
|
+
│ │ ├── components
|
|
99
|
+
│ │ │ ├── ConfirmationModal.tsx
|
|
100
|
+
│ │ │ ├── ContentLanguageSwitcher.tsx
|
|
101
|
+
│ │ │ ├── CopyContentFromLanguage.tsx
|
|
102
|
+
│ │ │ └── LanguageFilterSelect.tsx
|
|
103
|
+
│ │ ├── dashboard
|
|
104
|
+
│ │ │ └── page.tsx
|
|
105
|
+
│ │ ├── layout.tsx
|
|
106
|
+
│ │ ├── media
|
|
107
|
+
│ │ │ ├── [id]
|
|
108
|
+
│ │ │ │ └── edit
|
|
109
|
+
│ │ │ │ │ └── page.tsx
|
|
110
|
+
│ │ │ ├── actions.ts
|
|
111
|
+
│ │ │ ├── components
|
|
112
|
+
│ │ │ │ ├── DeleteMediaButtonClient.tsx
|
|
113
|
+
│ │ │ │ ├── MediaEditForm.tsx
|
|
114
|
+
│ │ │ │ ├── MediaGridClient.tsx
|
|
115
|
+
│ │ │ │ ├── MediaImage.tsx
|
|
116
|
+
│ │ │ │ └── MediaUploadForm.tsx
|
|
117
|
+
│ │ │ └── page.tsx
|
|
118
|
+
│ │ ├── navigation
|
|
119
|
+
│ │ │ ├── [id]
|
|
120
|
+
│ │ │ │ └── edit
|
|
121
|
+
│ │ │ │ │ └── page.tsx
|
|
122
|
+
│ │ │ ├── actions.ts
|
|
123
|
+
│ │ │ ├── components
|
|
124
|
+
│ │ │ │ ├── DeleteNavItemButton.tsx
|
|
125
|
+
│ │ │ │ ├── NavigationItemForm.tsx
|
|
126
|
+
│ │ │ │ ├── NavigationLanguageSwitcher.tsx
|
|
127
|
+
│ │ │ │ ├── NavigationMenuDnd.tsx
|
|
128
|
+
│ │ │ │ └── SortableNavItem.tsx
|
|
129
|
+
│ │ │ ├── new
|
|
130
|
+
│ │ │ │ └── page.tsx
|
|
131
|
+
│ │ │ ├── page.tsx
|
|
132
|
+
│ │ │ └── utils.ts
|
|
133
|
+
│ │ ├── pages
|
|
134
|
+
│ │ │ ├── [id]
|
|
135
|
+
│ │ │ │ └── edit
|
|
136
|
+
│ │ │ │ │ └── page.tsx
|
|
137
|
+
│ │ │ ├── actions.ts
|
|
138
|
+
│ │ │ ├── components
|
|
139
|
+
│ │ │ │ ├── DeletePageButtonClient.tsx
|
|
140
|
+
│ │ │ │ └── PageForm.tsx
|
|
141
|
+
│ │ │ ├── new
|
|
142
|
+
│ │ │ │ └── page.tsx
|
|
143
|
+
│ │ │ └── page.tsx
|
|
144
|
+
│ │ ├── posts
|
|
145
|
+
│ │ │ ├── [id]
|
|
146
|
+
│ │ │ │ └── edit
|
|
147
|
+
│ │ │ │ │ └── page.tsx
|
|
148
|
+
│ │ │ ├── actions.ts
|
|
149
|
+
│ │ │ ├── components
|
|
150
|
+
│ │ │ │ ├── DeletePostButtonClient.tsx
|
|
151
|
+
│ │ │ │ └── PostForm.tsx
|
|
152
|
+
│ │ │ ├── new
|
|
153
|
+
│ │ │ │ └── page.tsx
|
|
154
|
+
│ │ │ └── page.tsx
|
|
155
|
+
│ │ ├── settings
|
|
156
|
+
│ │ │ ├── copyright
|
|
157
|
+
│ │ │ │ ├── actions.ts
|
|
158
|
+
│ │ │ │ ├── components
|
|
159
|
+
│ │ │ │ │ └── CopyrightForm.tsx
|
|
160
|
+
│ │ │ │ └── page.tsx
|
|
161
|
+
│ │ │ ├── extra-translations
|
|
162
|
+
│ │ │ │ ├── actions.ts
|
|
163
|
+
│ │ │ │ └── page.tsx
|
|
164
|
+
│ │ │ ├── languages
|
|
165
|
+
│ │ │ │ ├── [id]
|
|
166
|
+
│ │ │ │ │ └── edit
|
|
167
|
+
│ │ │ │ │ │ └── page.tsx
|
|
168
|
+
│ │ │ │ ├── actions.ts
|
|
169
|
+
│ │ │ │ ├── components
|
|
170
|
+
│ │ │ │ │ ├── DeleteLanguageButton.tsx
|
|
171
|
+
│ │ │ │ │ └── LanguageForm.tsx
|
|
172
|
+
│ │ │ │ ├── new
|
|
173
|
+
│ │ │ │ │ └── page.tsx
|
|
174
|
+
│ │ │ │ └── page.tsx
|
|
175
|
+
│ │ │ └── logos
|
|
176
|
+
│ │ │ │ ├── [id]
|
|
177
|
+
│ │ │ │ └── edit
|
|
178
|
+
│ │ │ │ │ └── page.tsx
|
|
179
|
+
│ │ │ │ ├── actions.ts
|
|
180
|
+
│ │ │ │ ├── components
|
|
181
|
+
│ │ │ │ └── LogoForm.tsx
|
|
182
|
+
│ │ │ │ ├── new
|
|
183
|
+
│ │ │ │ └── page.tsx
|
|
184
|
+
│ │ │ │ ├── page.tsx
|
|
185
|
+
│ │ │ │ └── types.ts
|
|
186
|
+
│ │ └── users
|
|
187
|
+
│ │ │ ├── [id]
|
|
188
|
+
│ │ │ └── edit
|
|
189
|
+
│ │ │ │ └── page.tsx
|
|
190
|
+
│ │ │ ├── actions.ts
|
|
191
|
+
│ │ │ ├── components
|
|
192
|
+
│ │ │ ├── DeleteUserButton.tsx
|
|
193
|
+
│ │ │ └── UserForm.tsx
|
|
194
|
+
│ │ │ └── page.tsx
|
|
195
|
+
│ ├── favicon.ico
|
|
196
|
+
│ ├── layout.tsx
|
|
197
|
+
│ ├── lib
|
|
198
|
+
│ │ └── sitemap-utils.ts
|
|
199
|
+
│ ├── page.tsx
|
|
200
|
+
│ ├── robots.txt
|
|
201
|
+
│ │ └── route.ts
|
|
202
|
+
│ ├── sitemap.xml
|
|
203
|
+
│ │ └── route.ts
|
|
204
|
+
│ └── unauthorized
|
|
205
|
+
│ │ └── page.tsx
|
|
206
|
+
│ ├── backup
|
|
207
|
+
│ ├── backup_2025-06-19.sql
|
|
208
|
+
│ ├── backup_2025-06-20.sql
|
|
209
|
+
│ ├── backup_2025-07-08.sql
|
|
210
|
+
│ ├── backup_2025-07-09.sql
|
|
211
|
+
│ └── backup_2025-07-10.sql
|
|
212
|
+
│ ├── components
|
|
213
|
+
│ ├── BlockRenderer.tsx
|
|
214
|
+
│ ├── FooterNavigation.tsx
|
|
215
|
+
│ ├── Header.tsx
|
|
216
|
+
│ ├── LanguageSwitcher.tsx
|
|
217
|
+
│ ├── ResponsiveNav.tsx
|
|
218
|
+
│ ├── blocks
|
|
219
|
+
│ │ ├── PostCardSkeleton.tsx
|
|
220
|
+
│ │ ├── PostsGridBlock.tsx
|
|
221
|
+
│ │ ├── PostsGridClient.tsx
|
|
222
|
+
│ │ ├── renderers
|
|
223
|
+
│ │ │ ├── ButtonBlockRenderer.tsx
|
|
224
|
+
│ │ │ ├── ClientTextBlockRenderer.tsx
|
|
225
|
+
│ │ │ ├── FormBlockRenderer.tsx
|
|
226
|
+
│ │ │ ├── HeadingBlockRenderer.tsx
|
|
227
|
+
│ │ │ ├── HeroBlockRenderer.tsx
|
|
228
|
+
│ │ │ ├── ImageBlockRenderer.tsx
|
|
229
|
+
│ │ │ ├── PostsGridBlockRenderer.tsx
|
|
230
|
+
│ │ │ ├── SectionBlockRenderer.tsx
|
|
231
|
+
│ │ │ ├── TextBlockRenderer.tsx
|
|
232
|
+
│ │ │ ├── VideoEmbedBlockRenderer.tsx
|
|
233
|
+
│ │ │ └── inline
|
|
234
|
+
│ │ │ │ ├── AlertWidgetRenderer.tsx
|
|
235
|
+
│ │ │ │ └── CtaWidgetRenderer.tsx
|
|
236
|
+
│ │ └── types.ts
|
|
237
|
+
│ ├── env-var-warning.tsx
|
|
238
|
+
│ ├── form-message.tsx
|
|
239
|
+
│ ├── header-auth.tsx
|
|
240
|
+
│ ├── submit-button.tsx
|
|
241
|
+
│ └── theme-switcher.tsx
|
|
242
|
+
│ ├── context
|
|
243
|
+
│ ├── AuthContext.tsx
|
|
244
|
+
│ ├── CurrentContentContext.tsx
|
|
245
|
+
│ └── LanguageContext.tsx
|
|
246
|
+
│ ├── docs
|
|
247
|
+
│ ├── cms-application-overview.md
|
|
248
|
+
│ ├── cms-architecture-overview.md
|
|
249
|
+
│ └── tiptap-bundle-optimization-summary.md
|
|
250
|
+
│ ├── eslint.config.mjs
|
|
251
|
+
│ ├── index.d.ts
|
|
252
|
+
│ ├── lib
|
|
253
|
+
│ └── blocks
|
|
254
|
+
│ │ ├── README.md
|
|
255
|
+
│ │ └── blockRegistry.ts
|
|
256
|
+
│ ├── middleware.ts
|
|
257
|
+
│ ├── next-env.d.ts
|
|
258
|
+
│ ├── next.config.js
|
|
259
|
+
│ ├── postcss.config.js
|
|
260
|
+
│ ├── project.json
|
|
261
|
+
│ ├── public
|
|
262
|
+
│ └── .gitkeep
|
|
263
|
+
│ ├── scripts
|
|
264
|
+
│ ├── backfill-image-meta.ts
|
|
265
|
+
│ ├── backup.js
|
|
266
|
+
│ └── test-bundle-optimization.js
|
|
267
|
+
│ ├── tailwind.config.ts
|
|
268
|
+
│ └── tsconfig.json
|
|
269
|
+
├── components.json
|
|
270
|
+
├── docs
|
|
271
|
+
├── AI-Dev-Onboarding-Guide.md
|
|
272
|
+
├── Tiptap Feature-Rich Editor Prompts.md
|
|
273
|
+
├── block-editor-analysis.md
|
|
274
|
+
├── inline-cta-widget-design.md
|
|
275
|
+
├── inline-widget-design.md
|
|
276
|
+
└── monorepo-archetecture.md
|
|
277
|
+
├── eslint.config.mjs
|
|
278
|
+
├── libs
|
|
279
|
+
├── db
|
|
280
|
+
│ ├── README.md
|
|
281
|
+
│ ├── eslint.config.mjs
|
|
282
|
+
│ ├── project.json
|
|
283
|
+
│ ├── src
|
|
284
|
+
│ │ ├── index.ts
|
|
285
|
+
│ │ ├── lib
|
|
286
|
+
│ │ │ └── supabase
|
|
287
|
+
│ │ │ │ ├── client.ts
|
|
288
|
+
│ │ │ │ ├── middleware.ts
|
|
289
|
+
│ │ │ │ ├── server.ts
|
|
290
|
+
│ │ │ │ ├── ssg-client.ts
|
|
291
|
+
│ │ │ │ └── types.ts
|
|
292
|
+
│ │ ├── server.ts
|
|
293
|
+
│ │ └── supabase
|
|
294
|
+
│ │ │ ├── .gitignore
|
|
295
|
+
│ │ │ ├── config.toml
|
|
296
|
+
│ │ │ └── migrations
|
|
297
|
+
│ │ │ ├── 20250513194738_setup_roles_and_profiles.sql
|
|
298
|
+
│ │ │ ├── 20250513194910_auto_create_profile_trigger.sql
|
|
299
|
+
│ │ │ ├── 20250513194916_rls_for_profiles.sql
|
|
300
|
+
│ │ │ ├── 20250514125634_fix_recursive_rls_policies.sql
|
|
301
|
+
│ │ │ ├── 20250514143016_setup_languages_table.sql
|
|
302
|
+
│ │ │ ├── 20250514171549_create_pages_table.sql
|
|
303
|
+
│ │ │ ├── 20250514171550_create_posts_table.sql
|
|
304
|
+
│ │ │ ├── 20250514171552_create_media_table.sql
|
|
305
|
+
│ │ │ ├── 20250514171553_create_blocks_table.sql
|
|
306
|
+
│ │ │ ├── 20250514171615_create_navigation_table.sql
|
|
307
|
+
│ │ │ ├── 20250514171627_rls_policies_for_content_tables.sql
|
|
308
|
+
│ │ │ ├── 20250515194800_add_translation_group_id.sql
|
|
309
|
+
│ │ │ ├── 20250520171900_add_translation_group_to_nav_items.sql
|
|
310
|
+
│ │ │ ├── 20250521143933_seed_homepage_and_nav.sql
|
|
311
|
+
│ │ │ ├── 20250523145833_add_feature_image_to_posts.sql
|
|
312
|
+
│ │ │ ├── 20250523151737_add_rls_to_media_table.sql
|
|
313
|
+
│ │ │ ├── 20250526110400_add_image_dimensions_to_media.sql
|
|
314
|
+
│ │ │ ├── 20250526153321_optimize_rls_policies.sql
|
|
315
|
+
│ │ │ ├── 20250526172513_resolve_select_policy_overlaps.sql
|
|
316
|
+
│ │ │ ├── 20250526172853_resolve_remaining_rls_v5.sql
|
|
317
|
+
│ │ │ ├── 20250526173538_finalize_rls_cleanup_v7.sql
|
|
318
|
+
│ │ │ ├── 20250526174710_separate_write_policies_v8.sql
|
|
319
|
+
│ │ │ ├── 20250526175359_fix_languages_select_rls_v9.sql
|
|
320
|
+
│ │ │ ├── 20250526182940_fix_nav_read_policy_v10.sql
|
|
321
|
+
│ │ │ ├── 20250526183239_fix_posts_read_rls_v11.sql
|
|
322
|
+
│ │ │ ├── 20250526183746_fix_media_select_rls_v12.sql
|
|
323
|
+
│ │ │ ├── 20250526184205_consolidate_content_read_rls_v13.sql
|
|
324
|
+
│ │ │ ├── 20250526185854_optimize_indexes.sql
|
|
325
|
+
│ │ │ ├── 20250526190900_debug_blocks_rls.sql
|
|
326
|
+
│ │ │ ├── 20250526191217_consolidate_blocks_select_rls.sql
|
|
327
|
+
│ │ │ ├── 20250526192822_fix_handle_languages_update_search_path.sql
|
|
328
|
+
│ │ │ ├── 20250527150500_fix_blocks_rls_policy.sql
|
|
329
|
+
│ │ │ ├── 20250602150602_add_blur_data_url_to_media.sql
|
|
330
|
+
│ │ │ ├── 20250602150959_add_variants_to_media.sql
|
|
331
|
+
│ │ │ ├── 20250618124000_create_get_my_claim_function.sql
|
|
332
|
+
│ │ │ ├── 20250618124100_create_logos_table.sql
|
|
333
|
+
│ │ │ ├── 20250618130000_fix_linter_warnings.sql
|
|
334
|
+
│ │ │ ├── 20250618151500_revert_storage_rls.sql
|
|
335
|
+
│ │ │ ├── 20250619084800_reinstate_storage_rls.sql
|
|
336
|
+
│ │ │ ├── 20250619092430_widen_logo_insert_policy.sql
|
|
337
|
+
│ │ │ ├── 20250619093122_fix_get_my_claim_volatility.sql
|
|
338
|
+
│ │ │ ├── 20250619104249_consolidated_logo_rls_fix.sql
|
|
339
|
+
│ │ │ ├── 20250619110700_fix_logo_rls_again.sql
|
|
340
|
+
│ │ │ ├── 20250619113200_add_file_path_to_media.sql
|
|
341
|
+
│ │ │ ├── 20250619124100_fix_rls_performance_warnings.sql
|
|
342
|
+
│ │ │ ├── 20250619195500_create_site_settings_table.sql
|
|
343
|
+
│ │ │ ├── 20250619201500_add_anon_read_to_site_settings.sql
|
|
344
|
+
│ │ │ ├── 20250619202000_add_is_active_to_languages.sql
|
|
345
|
+
│ │ │ ├── 20250620085700_fix_site_settings_write_rls.sql
|
|
346
|
+
│ │ │ ├── 20250620095500_fix_profiles_read_rls.sql
|
|
347
|
+
│ │ │ ├── 20250620100000_use_security_definer_for_rls.sql
|
|
348
|
+
│ │ │ ├── 20250620130000_add_public_read_to_logos.sql
|
|
349
|
+
│ │ │ ├── 20250708091700_create_translations_table.sql
|
|
350
|
+
│ │ │ ├── 20250708093403_seed_translations_table.sql
|
|
351
|
+
│ │ │ ├── 20250708110600_fix_translations_rls_policies.sql
|
|
352
|
+
│ │ │ └── 20250708112300_add_new_translations.sql
|
|
353
|
+
│ ├── tsconfig.json
|
|
354
|
+
│ ├── tsconfig.lib.json
|
|
355
|
+
│ └── vite.config.ts
|
|
356
|
+
├── environment.d.ts
|
|
357
|
+
├── sdk
|
|
358
|
+
│ ├── README.md
|
|
359
|
+
│ ├── eslint.config.mjs
|
|
360
|
+
│ ├── package.json
|
|
361
|
+
│ ├── project.json
|
|
362
|
+
│ ├── src
|
|
363
|
+
│ │ ├── index.ts
|
|
364
|
+
│ │ └── lib
|
|
365
|
+
│ │ │ └── sdk.ts
|
|
366
|
+
│ ├── tsconfig.json
|
|
367
|
+
│ ├── tsconfig.lib.json
|
|
368
|
+
│ └── vite.config.ts
|
|
369
|
+
├── ui
|
|
370
|
+
│ ├── .babelrc
|
|
371
|
+
│ ├── README.md
|
|
372
|
+
│ ├── eslint.config.mjs
|
|
373
|
+
│ ├── project.json
|
|
374
|
+
│ ├── src
|
|
375
|
+
│ │ ├── index.ts
|
|
376
|
+
│ │ ├── lib
|
|
377
|
+
│ │ │ ├── ColorPicker.tsx
|
|
378
|
+
│ │ │ ├── ConfirmationDialog.tsx
|
|
379
|
+
│ │ │ ├── CustomSelectWithInput.tsx
|
|
380
|
+
│ │ │ ├── Skeleton.tsx
|
|
381
|
+
│ │ │ ├── avatar.tsx
|
|
382
|
+
│ │ │ ├── badge.tsx
|
|
383
|
+
│ │ │ ├── button.tsx
|
|
384
|
+
│ │ │ ├── card.tsx
|
|
385
|
+
│ │ │ ├── checkbox.tsx
|
|
386
|
+
│ │ │ ├── dialog.tsx
|
|
387
|
+
│ │ │ ├── dropdown-menu.tsx
|
|
388
|
+
│ │ │ ├── input.tsx
|
|
389
|
+
│ │ │ ├── label.tsx
|
|
390
|
+
│ │ │ ├── popover.tsx
|
|
391
|
+
│ │ │ ├── progress.tsx
|
|
392
|
+
│ │ │ ├── select.tsx
|
|
393
|
+
│ │ │ ├── separator.tsx
|
|
394
|
+
│ │ │ ├── table.tsx
|
|
395
|
+
│ │ │ ├── textarea.tsx
|
|
396
|
+
│ │ │ ├── tooltip.tsx
|
|
397
|
+
│ │ │ └── ui.tsx
|
|
398
|
+
│ │ └── styles
|
|
399
|
+
│ │ │ └── globals.css
|
|
400
|
+
│ ├── tsconfig.json
|
|
401
|
+
│ ├── tsconfig.lib.json
|
|
402
|
+
│ └── vite.config.ts
|
|
403
|
+
└── utils
|
|
404
|
+
│ ├── README.md
|
|
405
|
+
│ ├── eslint.config.mjs
|
|
406
|
+
│ ├── project.json
|
|
407
|
+
│ ├── src
|
|
408
|
+
│ ├── index.ts
|
|
409
|
+
│ ├── lib
|
|
410
|
+
│ │ ├── check-env-vars.ts
|
|
411
|
+
│ │ ├── client-utils.ts
|
|
412
|
+
│ │ ├── email-config.ts
|
|
413
|
+
│ │ ├── r2-client.ts
|
|
414
|
+
│ │ ├── translations-context.tsx
|
|
415
|
+
│ │ ├── translations.ts
|
|
416
|
+
│ │ └── utils.ts
|
|
417
|
+
│ └── server.ts
|
|
418
|
+
│ ├── tsconfig.json
|
|
419
|
+
│ ├── tsconfig.lib.json
|
|
420
|
+
│ └── vite.config.ts
|
|
421
|
+
├── nx.json
|
|
422
|
+
├── package-lock.json
|
|
423
|
+
├── package.json
|
|
424
|
+
├── project.json
|
|
425
|
+
├── tailwind.config.ts
|
|
426
|
+
└── tsconfig.base.json
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# TipTap Bundle Optimization Implementation Summary
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
Successfully implemented role-based bundle optimization for TipTap rich text editor, achieving significant JavaScript bundle size reduction for anonymous users and regular users without ADMIN or WRITER roles.
|
|
5
|
+
|
|
6
|
+
## Implementation Details
|
|
7
|
+
|
|
8
|
+
### 1. Dynamic Loading Architecture
|
|
9
|
+
- **Created [`DynamicRichTextEditor.tsx`](../app/cms/blocks/components/DynamicRichTextEditor.tsx)**: Base dynamic wrapper with lazy loading
|
|
10
|
+
- **Created [`RoleAwareRichTextEditor.tsx`](../app/cms/blocks/components/RoleAwareRichTextEditor.tsx)**: Role-based loading component
|
|
11
|
+
- **Updated [`TextBlockEditor.tsx`](../app/cms/blocks/editors/TextBlockEditor.tsx)**: Now uses role-aware component
|
|
12
|
+
|
|
13
|
+
### 2. Bundle Separation Configuration
|
|
14
|
+
- **Enhanced [`next.config.ts`](../next.config.ts)**: Added webpack optimization for TipTap chunk separation
|
|
15
|
+
- **Configured cache groups**: Separate chunks for `@tiptap/*`, `prosemirror*`, and custom extensions
|
|
16
|
+
- **Async chunk loading**: TipTap only loads when dynamically imported
|
|
17
|
+
|
|
18
|
+
### 3. Role-Based Access Control
|
|
19
|
+
- **Leveraged existing auth system**: Uses `useAuth()` hook from [`AuthContext`](../context/AuthContext.tsx)
|
|
20
|
+
- **Role validation**: Only ADMIN and WRITER roles can access TipTap
|
|
21
|
+
- **Fallback editor**: Basic textarea for unauthorized users
|
|
22
|
+
- **Loading states**: Proper skeletons during auth determination
|
|
23
|
+
|
|
24
|
+
## Performance Results
|
|
25
|
+
|
|
26
|
+
### Bundle Analysis (Verified)
|
|
27
|
+
```
|
|
28
|
+
✅ Bundle optimization SUCCESSFUL!
|
|
29
|
+
- TipTap is properly separated into async chunks
|
|
30
|
+
- Main bundle is clean of TipTap dependencies
|
|
31
|
+
- Role-based loading prevents unnecessary downloads
|
|
32
|
+
|
|
33
|
+
📊 Bundle Analysis Results:
|
|
34
|
+
Total chunks: 50
|
|
35
|
+
TipTap-related chunks: 1 (tiptap.e2acb1b739e4a3e9.js)
|
|
36
|
+
Main app chunks: 2
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Expected Performance Impact
|
|
40
|
+
- **Bundle size reduction**: 200-500KB for anonymous users
|
|
41
|
+
- **JavaScript execution time**: 100-300ms improvement for non-CMS pages
|
|
42
|
+
- **Speed Index improvement**: 400-800ms for public pages
|
|
43
|
+
- **Lighthouse score increase**: 3-5 points for public pages
|
|
44
|
+
|
|
45
|
+
## Technical Implementation
|
|
46
|
+
|
|
47
|
+
### Components Created
|
|
48
|
+
1. **DynamicRichTextEditor**: Base dynamic loading wrapper
|
|
49
|
+
- Error boundaries for failed TipTap loads
|
|
50
|
+
- Loading skeletons
|
|
51
|
+
- Fallback basic text editor
|
|
52
|
+
|
|
53
|
+
2. **RoleAwareRichTextEditor**: Role-based loading logic
|
|
54
|
+
- Auth state checking
|
|
55
|
+
- Conditional TipTap loading
|
|
56
|
+
- Basic editor for unauthorized users
|
|
57
|
+
|
|
58
|
+
### Webpack Configuration
|
|
59
|
+
```typescript
|
|
60
|
+
webpack: (config, { isServer }) => {
|
|
61
|
+
if (!isServer) {
|
|
62
|
+
config.optimization.splitChunks.cacheGroups = {
|
|
63
|
+
tiptap: {
|
|
64
|
+
test: /[\\/]node_modules[\\/](@tiptap|prosemirror)[\\/]/,
|
|
65
|
+
name: 'tiptap',
|
|
66
|
+
chunks: 'async',
|
|
67
|
+
priority: 30,
|
|
68
|
+
},
|
|
69
|
+
tiptapExtensions: {
|
|
70
|
+
test: /[\\/](tiptap-extensions|RichTextEditor|MenuBar|MediaLibraryModal)[\\/]/,
|
|
71
|
+
name: 'tiptap-extensions',
|
|
72
|
+
chunks: 'async',
|
|
73
|
+
priority: 25,
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
return config;
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Dependencies Optimized
|
|
82
|
+
- `@tiptap/react` (53.2KB)
|
|
83
|
+
- `@tiptap/starter-kit` (46.4KB)
|
|
84
|
+
- `@tiptap/extension-image`
|
|
85
|
+
- `@tiptap/extension-color`
|
|
86
|
+
- `@tiptap/extension-text-style`
|
|
87
|
+
- `@tiptap/pm` (ProseMirror core)
|
|
88
|
+
- Custom extensions: FontSizeMark, StyleTagNode, DivNode, PreserveAllAttributesExtension
|
|
89
|
+
|
|
90
|
+
## User Experience
|
|
91
|
+
|
|
92
|
+
### For Anonymous Users
|
|
93
|
+
- **No TipTap download**: JavaScript bundle excludes all TipTap code
|
|
94
|
+
- **Faster page loads**: Reduced initial bundle size
|
|
95
|
+
- **Better performance**: Less JavaScript parsing and execution
|
|
96
|
+
|
|
97
|
+
### For CMS Users (ADMIN/WRITER)
|
|
98
|
+
- **Dynamic loading**: TipTap loads only when needed
|
|
99
|
+
- **Loading indicators**: Smooth skeleton transitions
|
|
100
|
+
- **Full functionality**: Complete rich text editing capabilities
|
|
101
|
+
- **Error handling**: Fallback to basic editor if TipTap fails
|
|
102
|
+
|
|
103
|
+
### For Regular Users (Non-CMS)
|
|
104
|
+
- **Basic text editor**: Simple textarea fallback
|
|
105
|
+
- **Consistent UX**: Same interface, reduced functionality
|
|
106
|
+
- **No performance impact**: No TipTap code loaded
|
|
107
|
+
|
|
108
|
+
## Testing and Verification
|
|
109
|
+
|
|
110
|
+
### Automated Testing
|
|
111
|
+
- **Created [`test-bundle-optimization.js`](../scripts/test-bundle-optimization.js)**: Comprehensive bundle analysis
|
|
112
|
+
- **Bundle analysis**: Verifies chunk separation
|
|
113
|
+
- **Main bundle check**: Confirms TipTap exclusion
|
|
114
|
+
- **Performance metrics**: Expected improvement calculations
|
|
115
|
+
|
|
116
|
+
### Manual Testing Checklist
|
|
117
|
+
1. ✅ Anonymous user - TipTap not loaded
|
|
118
|
+
2. ✅ WRITER/ADMIN user - TipTap loads dynamically
|
|
119
|
+
3. ✅ Network tab shows proper chunk loading
|
|
120
|
+
4. ✅ Fallback editor works for unauthorized users
|
|
121
|
+
5. ✅ Error boundaries handle TipTap load failures
|
|
122
|
+
|
|
123
|
+
## Maintenance Notes
|
|
124
|
+
|
|
125
|
+
### Future Considerations
|
|
126
|
+
- **Monitor bundle sizes**: Regular analysis with `npm run analyze`
|
|
127
|
+
- **Update TipTap versions**: Ensure compatibility with dynamic loading
|
|
128
|
+
- **Performance monitoring**: Track real-world performance metrics
|
|
129
|
+
- **User feedback**: Monitor CMS user experience
|
|
130
|
+
|
|
131
|
+
### Code Organization
|
|
132
|
+
- **Modular architecture**: Easy to extend or modify
|
|
133
|
+
- **Type safety**: Full TypeScript support maintained
|
|
134
|
+
- **Error handling**: Comprehensive fallback strategies
|
|
135
|
+
- **Loading states**: Consistent UX patterns
|
|
136
|
+
|
|
137
|
+
## Commands for Testing
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
# Analyze bundle composition
|
|
141
|
+
npm run analyze
|
|
142
|
+
|
|
143
|
+
# Test bundle optimization
|
|
144
|
+
node scripts/test-bundle-optimization.js
|
|
145
|
+
|
|
146
|
+
# Development with optimization
|
|
147
|
+
npm run dev
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Success Metrics
|
|
151
|
+
|
|
152
|
+
### Technical Metrics
|
|
153
|
+
- ✅ TipTap separated into async chunks
|
|
154
|
+
- ✅ Main bundle clean of TipTap dependencies
|
|
155
|
+
- ✅ Role-based loading implemented
|
|
156
|
+
- ✅ Error boundaries and fallbacks working
|
|
157
|
+
- ✅ TypeScript support maintained
|
|
158
|
+
|
|
159
|
+
### Performance Metrics (Expected)
|
|
160
|
+
- 📈 200-500KB bundle size reduction for anonymous users
|
|
161
|
+
- 📈 100-300ms faster JavaScript execution
|
|
162
|
+
- 📈 400-800ms Speed Index improvement
|
|
163
|
+
- 📈 3-5 point Lighthouse score increase
|
|
164
|
+
|
|
165
|
+
## Conclusion
|
|
166
|
+
|
|
167
|
+
The TipTap bundle optimization has been successfully implemented with:
|
|
168
|
+
- **Zero breaking changes** to existing CMS functionality
|
|
169
|
+
- **Significant performance improvements** for public pages
|
|
170
|
+
- **Proper role-based access control** integration
|
|
171
|
+
- **Comprehensive error handling** and fallback strategies
|
|
172
|
+
- **Maintainable and extensible** architecture
|
|
173
|
+
|
|
174
|
+
The optimization ensures that anonymous users and regular users never download unnecessary TipTap code, while CMS users get the full rich text editing experience with dynamic loading.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { FlatCompat } from '@eslint/eslintrc';
|
|
2
|
+
import { dirname } from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
import js from '@eslint/js';
|
|
5
|
+
import { fixupConfigRules } from '@eslint/compat';
|
|
6
|
+
import nx from '@nx/eslint-plugin';
|
|
7
|
+
import baseConfig from '../../eslint.config.mjs';
|
|
8
|
+
const compat = new FlatCompat({
|
|
9
|
+
baseDirectory: dirname(fileURLToPath(import.meta.url)),
|
|
10
|
+
recommendedConfig: js.configs.recommended,
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
const config = [
|
|
14
|
+
...fixupConfigRules(compat.extends('next')),
|
|
15
|
+
...fixupConfigRules(compat.extends('next/core-web-vitals')),
|
|
16
|
+
...baseConfig,
|
|
17
|
+
...nx.configs['flat/react-typescript'],
|
|
18
|
+
{
|
|
19
|
+
ignores: ['.next/**/*', '**/next-env.d.ts', 'apps/nextblock/next-env.d.ts'],
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
rules: {
|
|
23
|
+
'@next/next/no-html-link-for-pages': ['error', 'apps/nextblock/app'],
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
export default config;
|