@nextblock-cms/db 0.16.4 → 0.17.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.
Files changed (41) hide show
  1. package/package.json +1 -1
  2. package/supabase/functions/nextblock-migration-ingest/index.ts +8 -8
  3. package/supabase/migrations/02000_catchup_gen1.sql +5880 -0
  4. package/supabase/migrations/{00000000000000_baseline_schema.sql → 02001_baseline_schema.sql} +2734 -2454
  5. package/supabase/migrations/{00000000000001_baseline_constraints_and_indexes.sql → 02002_baseline_constraints_and_indexes.sql} +1262 -1071
  6. package/supabase/migrations/{00000000000002_baseline_security_and_grants.sql → 02003_baseline_security_and_grants.sql} +1577 -1335
  7. package/supabase/migrations/02004_baseline_seed.sql +565 -0
  8. package/supabase/migrations/00000000000003_baseline_seed.sql +0 -468
  9. package/supabase/migrations/00000000000004_default_logo_email_safe.sql +0 -24
  10. package/supabase/migrations/00000000000005_add_custom_canonical.sql +0 -13
  11. package/supabase/migrations/00000000000006_home_live_demo_promo.sql +0 -67
  12. package/supabase/migrations/00000000000007_home_live_demo_promo_copy_fix.sql +0 -49
  13. package/supabase/migrations/00000000000008_setup_article_reorder.sql +0 -30
  14. package/supabase/migrations/00000000000009_home_live_demo_promo_contrast.sql +0 -52
  15. package/supabase/migrations/00000000000010_drop_github_username.sql +0 -79
  16. package/supabase/migrations/00000000000011_language_detection_admin_only.sql +0 -21
  17. package/supabase/migrations/00000000000012_cortex_ai_stock_photo_settings.sql +0 -25
  18. package/supabase/migrations/00000000000013_youtube_nocookie_embeds.sql +0 -136
  19. package/supabase/migrations/00000000000014_site_themes.sql +0 -254
  20. package/supabase/migrations/00000000000015_scheduled_publishing.sql +0 -43
  21. package/supabase/migrations/00000000000016_product_revisions_and_revision_baseline.sql +0 -310
  22. package/supabase/migrations/00000000000017_cortex_ai_mcp_server.sql +0 -91
  23. package/supabase/migrations/00000000000018_site_scripts.sql +0 -96
  24. package/supabase/migrations/00000000000019_site_script_revisions.sql +0 -85
  25. package/supabase/migrations/00000000000020_updating_article.sql +0 -162
  26. package/supabase/migrations/00000000000021_updating_article_git_merge.sql +0 -91
  27. package/supabase/migrations/00000000000022_updating_article_accuracy.sql +0 -94
  28. package/supabase/migrations/00000000000023_updating_article_layout_not_host.sql +0 -87
  29. package/supabase/migrations/00000000000024_updating_article_newline_fix.sql +0 -70
  30. package/supabase/migrations/00000000000025_rebrand_nextblock_dev.sql +0 -53
  31. package/supabase/migrations/00000000000026_product_inquiries.sql +0 -118
  32. package/supabase/migrations/00000000000027_message_threads.sql +0 -391
  33. package/supabase/migrations/00000000000028_interaction_replies.sql +0 -86
  34. package/supabase/migrations/00000000000029_form_endpoints_default_empty.sql +0 -52
  35. package/supabase/migrations/00000000000030_seo_redirects_and_robots.sql +0 -149
  36. package/supabase/migrations/00000000000031_seo_robots_settings_admin_only.sql +0 -35
  37. package/supabase/migrations/00000000000032_seed_seo_score_optimizations.sql +0 -1172
  38. package/supabase/migrations/00000000000033_seed_seo_score_optimizations_p2.sql +0 -353
  39. package/supabase/migrations/00000000000034_seed_seo_french_legal_readability.sql +0 -101
  40. package/supabase/migrations/00000000000035_digital_products_seo_optimizations.sql +0 -134
  41. package/supabase/migrations/00000000000036_seed_posts_missing_seo_metadata.sql +0 -37
@@ -1,1172 +0,0 @@
1
- -- Migration: 00000000000032_seed_seo_score_optimizations.sql
2
- -- Description: Optimize seeded pages and posts for perfect 100/100 Page SEO scores.
3
- -- Safety: All updates are forward-only and content-guarded so they only apply to
4
- -- default seeded copy and will NEVER overwrite customized content on external sites.
5
-
6
- DO $$
7
- BEGIN
8
- -----------------------------------------------------------------------------
9
- -- 1. Page Metadata Optimizations
10
- -----------------------------------------------------------------------------
11
- UPDATE public.pages
12
- SET meta_title = 'NextBlock™ - CMS Next.js Haute Performance',
13
- meta_description = 'NextBlock est un CMS Next.js open-source conçu sur Supabase. Éditeur visuel de blocs, bilingue et scores Lighthouse parfaits dès le premier jour.',
14
- updated_at = now()
15
- WHERE slug = 'accueil'
16
- AND (meta_title IS NULL OR meta_title = '' OR meta_title = 'NextBlock™ - CMS Next.js Haute Performance')
17
- AND (meta_description IS NULL OR meta_description = '' OR meta_description LIKE 'NextBlock est un CMS Next.js%');
18
-
19
- UPDATE public.pages
20
- SET meta_title = 'NextBlock Journal | Engineering Guides & Tutorials',
21
- meta_description = 'Read technical deep dives, tutorials, and release notes on Next.js 16, Supabase, and modern visual web publishing from the NextBlock team.',
22
- updated_at = now()
23
- WHERE slug = 'articles' AND language_id = 1
24
- AND (meta_description IS NULL OR meta_description = '' OR meta_description = 'Explore architectural walkthroughs, Supabase recipes, and block editor experiments written by the Nextblock core team.');
25
-
26
- UPDATE public.pages
27
- SET meta_title = 'Journal NextBlock | Guides Techniques et Tutoriels',
28
- meta_description = 'Découvrez des guides techniques, des tutoriels et des analyses sur Next.js 16, Supabase et l’édition de blocs moderne avec l’équipe NextBlock.',
29
- updated_at = now()
30
- WHERE slug = 'articles' AND language_id = 2
31
- AND (meta_description IS NULL OR meta_description = '' OR meta_description = 'Explorez les guides d''architecture, les recettes Supabase et les experiences de l''editeur de blocs de NextBlock.');
32
-
33
- UPDATE public.pages
34
- SET meta_title = 'Contact Us | NextBlock Open-Source CMS',
35
- meta_description = 'Have questions, ideas, or feedback about NextBlock? Reach out to our team for technical support, partnership inquiries, and community discussions.',
36
- updated_at = now()
37
- WHERE slug = 'contact' AND language_id = 1
38
- AND (meta_description IS NULL OR meta_description = '' OR meta_description LIKE 'NextBlock™ is an open-source project driven%');
39
-
40
- UPDATE public.pages
41
- SET meta_title = 'Contactez-nous | NextBlock CMS Open Source',
42
- meta_description = 'Une question, une idée ou un retour sur NextBlock ? Contactez notre équipe pour du support technique, des partenariats ou échanger sur le projet.',
43
- updated_at = now()
44
- WHERE slug = 'contact' AND language_id = 2
45
- AND (meta_description IS NULL OR meta_description = '' OR meta_description LIKE 'NextBlock™ est un projet open-source propulsé%');
46
-
47
- UPDATE public.pages
48
- SET meta_title = 'Shop NextBlock™ Modules | Official Store',
49
- meta_description = 'Browse official commercial modules and licenses for NextBlock CMS. Get instant access to NextBlock Commerce and Cortex AI with secure checkout.',
50
- updated_at = now()
51
- WHERE slug = 'shop'
52
- AND (meta_description IS NULL OR meta_description = '' OR meta_description = 'Browse our premium products');
53
-
54
- UPDATE public.pages
55
- SET meta_title = 'Boutique NextBlock™ | Modules et Licences Officielles',
56
- meta_description = 'Achetez des licences et extensions officielles pour NextBlock CMS. Accédez à NextBlock Commerce et Cortex AI avec un paiement simple et sécurisé.',
57
- updated_at = now()
58
- WHERE slug = 'boutique'
59
- AND (meta_description IS NULL OR meta_description = '' OR meta_description IN ('Decouvrez nos produits premium', 'Découvrez nos produits premium'));
60
-
61
- -----------------------------------------------------------------------------
62
- -- 2. Post Metadata Optimizations
63
- -----------------------------------------------------------------------------
64
- UPDATE public.posts
65
- SET meta_description = 'A single command keeps your NextBlock install updated on Docker, Supabase, or a cloned repo. Learn how it works and keeps your data safe.',
66
- updated_at = now()
67
- WHERE slug = 'how-updating-works'
68
- AND (meta_description IS NULL OR meta_description LIKE 'A single command keeps your NextBlock install updated%');
69
-
70
- UPDATE public.posts
71
- SET meta_title = 'Mises à jour NextBlock : une commande pour chaque site',
72
- meta_description = 'Une seule commande met à jour NextBlock sur Docker, Supabase ou un dépôt cloné. Découvrez le fonctionnement et la protection de vos données.',
73
- updated_at = now()
74
- WHERE slug = 'comment-fonctionnent-les-mises-a-jour'
75
- AND (meta_title IS NULL OR meta_title LIKE 'Les mises à jour de NextBlock%');
76
-
77
- -----------------------------------------------------------------------------
78
- -- 3. Post Content Optimizations (Content-Guarded)
79
- -----------------------------------------------------------------------------
80
- -- Post 1: How NextBlock Works EN
81
- UPDATE public.blocks
82
- SET content = jsonb_set(content, '{html_content}', to_jsonb('
83
- <p class=''text-lg leading-8 text-slate-700 dark:text-slate-300''>NextBlock™ is built so the hosted CMS, the open-source starter, and the developer tools feel like one clear product. A shared Nx workspace and typed blocks keep code clean and teams moving fast.</p>
84
-
85
- <div class=''grid gap-4 md:grid-cols-3 my-10''>
86
- <div class=''rounded-3xl border border-sky-200/70 bg-sky-50/70 p-6 dark:border-sky-500/20 dark:bg-sky-500/10''>
87
- <p class=''text-xs font-semibold uppercase tracking-[0.22em] text-sky-700 dark:text-sky-200''>One codebase</p>
88
- <h2 class=''mt-3 text-xl font-semibold text-slate-900 dark:text-white''>Shared foundation</h2>
89
- <p class=''mt-3 text-sm text-slate-600 dark:text-slate-300''>Marketing pages, CMS screens, and the starter template grow together instead of drifting apart.</p>
90
- </div>
91
- <div class=''rounded-3xl border border-indigo-200/70 bg-indigo-50/70 p-6 dark:border-indigo-500/20 dark:bg-indigo-500/10''>
92
- <p class=''text-xs font-semibold uppercase tracking-[0.22em] text-indigo-700 dark:text-indigo-200''>Typed content</p>
93
- <h2 class=''mt-3 text-xl font-semibold text-slate-900 dark:text-white''>Blocks with guardrails</h2>
94
- <p class=''mt-3 text-sm text-slate-600 dark:text-slate-300''>Zod schemas and typed contracts make every custom block safe to build and ship.</p>
95
- </div>
96
- <div class=''rounded-3xl border border-emerald-200/70 bg-emerald-50/70 p-6 dark:border-emerald-500/20 dark:bg-emerald-500/10''>
97
- <p class=''text-xs font-semibold uppercase tracking-[0.22em] text-emerald-700 dark:text-emerald-200''>Editorial UX</p>
98
- <h2 class=''mt-3 text-xl font-semibold text-slate-900 dark:text-white''>Product-grade editing</h2>
99
- <p class=''mt-3 text-sm text-slate-600 dark:text-slate-300''>The Tiptap layer gives writers a rich editing screen without hiding the power of clean HTML.</p>
100
- </div>
101
- </div>
102
-
103
- <div class=''flex flex-col md:flex-row gap-8 items-center my-12''>
104
- <div class=''w-full md:w-1/2 space-y-4''>
105
- <h2>Monorepo Layout and Dependency Flow</h2>
106
- <p>The <code>apps/nextblock</code> folder holds the production Next.js app. This includes the public site and the private CMS admin area. The <code>apps/create-nextblock</code> tool mirrors that setup so teams can start with proven patterns right away.</p>
107
- <ul class=''list-disc pl-6 space-y-2 text-sm''>
108
- <li><strong>@nextblock-cms/ui</strong> - UI parts, design tokens, and shared buttons</li>
109
- <li><strong>@nextblock-cms/utils</strong> - Translations, safety checks, and image helpers</li>
110
- <li><strong>@nextblock-cms/db</strong> - Safe migrations, typed database queries, and schemas</li>
111
- <li><strong>@nextblock-cms/editor</strong> - The reusable Tiptap v3 block editor</li>
112
- <li><strong>@nextblock-cms/sdk</strong> - Typed tools to build and check custom blocks</li>
113
- <li><strong>@nextblock-cms/ecommerce</strong> - The digital store package when activated</li>
114
- </ul>
115
- <p>Run <code>nx graph</code> to see how code flows across the workspace. Shared path aliases and Tailwind styles help keep designs aligned across all pages.</p>
116
- </div>
117
- <aside class=''w-full md:w-1/2 rounded-[2rem] border border-slate-200/80 bg-white p-4 shadow-xl dark:border-white/10 dark:bg-white/5''>
118
- <div class=''relative aspect-video overflow-hidden rounded-2xl''><iframe class=''absolute inset-0 h-full w-full border-0'' src=''https://www.youtube-nocookie.com/embed/DNqU8ez9qjs?si=p2oIy0f-n7wiaBmO'' title=''How NextBlock™ Works'' allow=''accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share'' referrerpolicy=''strict-origin-when-cross-origin'' loading=''lazy'' allowfullscreen></iframe></div>
119
- <p class=''mt-3 text-sm text-slate-500 dark:text-slate-400''>Nx makes workspace relations clear. That is why our starter, CMS, and packages stay aligned.</p>
120
- </aside>
121
- </div>
122
-
123
- <figure class=''my-12 overflow-hidden rounded-[2rem] border border-slate-200/80 bg-slate-950 shadow-2xl dark:border-white/10''>
124
- <img src=''/images/extensibility.webp'' alt=''NextBlock™ extensibility artwork showing the CMS connected to reusable modules and integrations'' class=''w-full h-auto object-cover'' />
125
- <figcaption class=''border-t border-white/10 px-6 py-4 text-sm text-slate-300''>One unified design system spans content blocks, editing tools, and store features.</figcaption>
126
- </figure>
127
-
128
- <h2>Block Registry as Product Surface</h2>
129
- <p>The block registry file is the source of truth for all blocks. It holds Zod schemas, starter content, and editor components. Today it includes everything from text and headings to sections, post grids, checkout forms, and product cards.</p>
130
- <p>Sections support nested columns, so you can build real page layouts rather than flat lists. Typed helper functions keep custom layouts safe and easy to maintain.</p>
131
-
132
- <h2>The Editing Layer</h2>
133
- <p>The editor package wraps Tiptap into a rich editing surface. It offers slash commands, floating menus, drag handles, tables, checklists, and code blocks. It preserves clean HTML so teams are never locked into a closed format.</p>
134
-
135
- <h2>Inside the CMS Shell</h2>
136
- <p>Inside the CMS folder, each feature follows a clear pattern: item lists, create forms, edit screens, and server actions that wrap database updates. This gives editors a smooth flow while keeping credentials safe on the server.</p>
137
-
138
- <h2>Open Core Without Product Drift</h2>
139
- <p>The core CMS is open-source under the AGPL license. Store modules remain source-available and turn on with verified licenses. This keeps the core lightweight while unlocking advanced tools when you need them.</p>
140
-
141
- <h2>Why It Holds Together</h2>
142
- <p>The Nx monorepo keeps libraries clean. The Next.js framework ensures fast page loads. Supabase migrations define database rules, and Tiptap gives writers a great authoring screen. When you run <code>npm create nextblock</code>, you get a complete, working system from day one.</p>
143
- '::text)),
144
- updated_at = now()
145
- WHERE post_id = 1
146
- AND content->>'html_content' LIKE '%NextBlock™ is designed so the hosted CMS%';
147
-
148
- -- Post 2: Comment NextBlock Fonctionne FR
149
- UPDATE public.blocks
150
- SET content = jsonb_set(content, '{html_content}', to_jsonb('
151
- <p class=''text-lg leading-8 text-slate-700 dark:text-slate-300''>NextBlock™ est conçu pour offrir une expérience fluide entre le CMS hébergé, le projet open-source et les outils développeur. L''espace Nx partagé et les blocs typés permettent aux équipes de publier vite tout en gardant un code très propre.</p>
152
-
153
- <div class=''grid gap-4 md:grid-cols-3 my-10''>
154
- <div class=''rounded-3xl border border-sky-200/70 bg-sky-50/70 p-6 dark:border-sky-500/20 dark:bg-sky-500/10''>
155
- <p class=''text-xs font-semibold uppercase tracking-[0.22em] text-sky-700 dark:text-sky-200''>Base unique</p>
156
- <h2 class=''mt-3 text-xl font-semibold text-slate-900 dark:text-white''>Une même base</h2>
157
- <p class=''mt-3 text-sm text-slate-600 dark:text-slate-300''>Les pages du site, les écrans du CMS et le modèle de départ évoluent ensemble sans dérive.</p>
158
- </div>
159
- <div class=''rounded-3xl border border-indigo-200/70 bg-indigo-50/70 p-6 dark:border-indigo-500/20 dark:bg-indigo-500/10''>
160
- <p class=''text-xs font-semibold uppercase tracking-[0.22em] text-indigo-700 dark:text-indigo-200''>Contenu typé</p>
161
- <h2 class=''mt-3 text-xl font-semibold text-slate-900 dark:text-white''>Blocs avec garde-fous</h2>
162
- <p class=''mt-3 text-sm text-slate-600 dark:text-slate-300''>Les schémas Zod et les types stricts sécurisent chaque nouveau bloc personnalisé.</p>
163
- </div>
164
- <div class=''rounded-3xl border border-emerald-200/70 bg-emerald-50/70 p-6 dark:border-emerald-500/20 dark:bg-emerald-500/10''>
165
- <p class=''text-xs font-semibold uppercase tracking-[0.22em] text-emerald-700 dark:text-emerald-200''>Confort de rédaction</p>
166
- <h2 class=''mt-3 text-xl font-semibold text-slate-900 dark:text-white''>Édition premium</h2>
167
- <p class=''mt-3 text-sm text-slate-600 dark:text-slate-300''>L''éditeur Tiptap offre un vrai confort de travail sans brider la puissance du HTML propre.</p>
168
- </div>
169
- </div>
170
-
171
- <div class=''flex flex-col md:flex-row gap-8 items-center my-12''>
172
- <div class=''w-full md:w-1/2 space-y-4''>
173
- <h2>Architecture monorepo et flux de dépendances</h2>
174
- <p>Le dossier <code>apps/nextblock</code> contient le site Next.js public et le tableau de bord privé du CMS. La commande <code>apps/create-nextblock</code> reprend cette même base pour lancer des projets sains dès le premier jour.</p>
175
- <ul class=''list-disc pl-6 space-y-2 text-sm''>
176
- <li><strong>@nextblock-cms/ui</strong> - Composants d''interface, boutons et styles partagés</li>
177
- <li><strong>@nextblock-cms/utils</strong> - Traductions, gardes d''environnement et images</li>
178
- <li><strong>@nextblock-cms/db</strong> - Migrations sûres, accès typé à la base et schémas</li>
179
- <li><strong>@nextblock-cms/editor</strong> - L''éditeur de blocs réutilisable basé sur Tiptap v3</li>
180
- <li><strong>@nextblock-cms/sdk</strong> - Outils typés pour créer et vérifier des blocs sur mesure</li>
181
- <li><strong>@nextblock-cms/ecommerce</strong> - Le module de boutique en ligne une fois activé</li>
182
- </ul>
183
- <p>La commande <code>nx graph</code> montre clairement les liens entre chaque dossier. Les alias de code et la configuration Tailwind partagée assurent un design soigné partout.</p>
184
- </div>
185
- <aside class=''w-full md:w-1/2 rounded-[2rem] border border-slate-200/80 bg-white p-4 shadow-xl dark:border-white/10 dark:bg-white/5''>
186
- <div class=''relative aspect-video overflow-hidden rounded-2xl''><iframe class=''absolute inset-0 h-full w-full border-0'' src=''https://www.youtube-nocookie.com/embed/DNqU8ez9qjs?si=p2oIy0f-n7wiaBmO'' title=''Comment NextBlock™ Fonctionne'' allow=''accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share'' referrerpolicy=''strict-origin-when-cross-origin'' loading=''lazy'' allowfullscreen></iframe></div>
187
- <p class=''mt-3 text-sm text-slate-500 dark:text-slate-400''>Nx rend chaque lien visible dans le projet. C''est pourquoi le starter et le CMS restent toujours synchronisés.</p>
188
- </aside>
189
- </div>
190
-
191
- <figure class=''my-12 overflow-hidden rounded-[2rem] border border-slate-200/80 bg-slate-950 shadow-2xl dark:border-white/10''>
192
- <img src=''/images/extensibility.webp'' alt=''Illustration NextBlock montrant les connexions entre le CMS et les modules externes'' class=''w-full h-auto object-cover'' />
193
- <figcaption class=''border-t border-white/10 px-6 py-4 text-sm text-slate-300''>Un même système visuel réunit la gestion de contenu, l''édition et les modules du store.</figcaption>
194
- </figure>
195
-
196
- <h2>Le registre de blocs comme surface produit</h2>
197
- <p>Le registre de blocs est la source de vérité pour tous les blocs du CMS. Il rassemble les schémas Zod, les contenus de départ et les composants d''affichage. Il gère le texte, les titres, les sections, les listes d''articles et les formulaires de paiement.</p>
198
- <p>Les sections acceptent des colonnes imbriquées. Vous pouvez ainsi monter de vraies pages complètes plutôt que de simples listes de textes. Des fonctions typées rendent cette souplesse très sûre à manipuler.</p>
199
-
200
- <h2>La couche d''édition</h2>
201
- <p>Le paquet éditeur transforme Tiptap en un espace de rédaction riche. Il propose des commandes slash, des menus flottants, des tableaux, des listes de tâches et des blocs de code colorés. Il conserve un HTML propre pour ne jamais vous enfermer.</p>
202
-
203
- <h2>À l''intérieur du shell CMS</h2>
204
- <p>Dans le dossier CMS, chaque module suit la même logique : listes de données, pages d''ajout, écrans d''édition et Server Actions. Les rédacteurs travaillent en toute confiance pendant que les accès restent protégés sur le serveur.</p>
205
-
206
- <h2>Open core sans dérive produit</h2>
207
- <p>Le cœur de NextBlock est open-source sous licence AGPL. Les modules du store s''activent avec une clé de licence valide. Le socle reste léger tout en ouvrant des outils pro quand vous en avez besoin.</p>
208
-
209
- <h2>Pourquoi l''ensemble tient</h2>
210
- <p>Le monorepo Nx garde les librairies bien rangées. L''application Next.js assure la rapidité des pages. Les migrations Supabase fixent les règles de la base, et l''éditeur Tiptap offre un vrai confort de travail. En lançant <code>npm create nextblock</code>, vous profitez d''une base solide et prête à l''emploi.</p>
211
- '::text)),
212
- updated_at = now()
213
- WHERE post_id = 2
214
- AND content->>'html_content' LIKE '%NextBlock™ relie le CMS h&eacute;berg&eacute;%';
215
-
216
- -- Post 3: Setup EN (Card headings H3 -> H2)
217
- UPDATE public.blocks
218
- SET content = jsonb_set(
219
- content,
220
- '{html_content}',
221
- to_jsonb(
222
- replace(
223
- replace(
224
- replace(
225
- replace(
226
- content->>'html_content',
227
- '<h3 class=''mt-2 mb-2 text-xl font-semibold text-slate-900 dark:text-white''>Deploy on Vercel</h3>',
228
- '<h2 class=''mt-2 mb-2 text-xl font-semibold text-slate-900 dark:text-white''>Deploy on Vercel</h2>'
229
- ),
230
- '<h3 class=''mt-2 mb-2 text-xl font-semibold text-slate-900 dark:text-white''>npm create nextblock &rarr; Docker</h3>',
231
- '<h2 class=''mt-2 mb-2 text-xl font-semibold text-slate-900 dark:text-white''>npm create nextblock &rarr; Docker</h2>'
232
- ),
233
- '<h3 class=''mt-2 mb-2 text-xl font-semibold text-slate-900 dark:text-white''>npm create nextblock &rarr; Supabase + R2</h3>',
234
- '<h2 class=''mt-2 mb-2 text-xl font-semibold text-slate-900 dark:text-white''>npm create nextblock &rarr; Supabase + R2</h2>'
235
- ),
236
- '<h3 class=''mt-2 mb-2 text-xl font-semibold text-slate-900 dark:text-white''>Clone the repository</h3>',
237
- '<h2 class=''mt-2 mb-2 text-xl font-semibold text-slate-900 dark:text-white''>Clone the repository</h2>'
238
- )
239
- )
240
- ),
241
- updated_at = now()
242
- WHERE post_id = 3
243
- AND content->>'html_content' LIKE '%NextBlock is an open-source, AI-native Next.js CMS%';
244
-
245
- -- Post 4: Setup FR (Card headings H3 -> H2)
246
- UPDATE public.blocks
247
- SET content = jsonb_set(
248
- content,
249
- '{html_content}',
250
- to_jsonb(
251
- replace(
252
- replace(
253
- replace(
254
- replace(
255
- content->>'html_content',
256
- '<h3 class=''mt-2 mb-2 text-xl font-semibold text-slate-900 dark:text-white''>Déployer sur Vercel</h3>',
257
- '<h2 class=''mt-2 mb-2 text-xl font-semibold text-slate-900 dark:text-white''>Déployer sur Vercel</h2>'
258
- ),
259
- '<h3 class=''mt-2 mb-2 text-xl font-semibold text-slate-900 dark:text-white''>npm create nextblock &rarr; Docker</h3>',
260
- '<h2 class=''mt-2 mb-2 text-xl font-semibold text-slate-900 dark:text-white''>npm create nextblock &rarr; Docker</h2>'
261
- ),
262
- '<h3 class=''mt-2 mb-2 text-xl font-semibold text-slate-900 dark:text-white''>npm create nextblock &rarr; Supabase + R2</h3>',
263
- '<h2 class=''mt-2 mb-2 text-xl font-semibold text-slate-900 dark:text-white''>npm create nextblock &rarr; Supabase + R2</h2>'
264
- ),
265
- '<h3 class=''mt-2 mb-2 text-xl font-semibold text-slate-900 dark:text-white''>Cloner le dépôt</h3>',
266
- '<h2 class=''mt-2 mb-2 text-xl font-semibold text-slate-900 dark:text-white''>Cloner le dépôt</h2>'
267
- )
268
- )
269
- ),
270
- updated_at = now()
271
- WHERE post_id = 4
272
- AND content->>'html_content' LIKE '%NextBlock est un CMS Next.js open-source%';
273
-
274
- -- Post 5: Commerce EN
275
- UPDATE public.blocks
276
- SET content = jsonb_set(content, '{html_content}', to_jsonb('
277
- <p class=''text-lg leading-8 text-slate-700 dark:text-slate-300''>NextBlock™ Commerce is our first premium module. It adds a complete store layer to the same editor you use for content. It is built for teams that want their catalog and checkout in one place.</p>
278
-
279
- <div class=''grid gap-4 md:grid-cols-3 my-10''>
280
- <div class=''rounded-3xl border border-emerald-200/70 bg-emerald-50/70 p-6 dark:border-emerald-500/20 dark:bg-emerald-500/10''>
281
- <p class=''text-xs font-semibold uppercase tracking-[0.22em] text-emerald-700 dark:text-emerald-200''>Commerce core</p>
282
- <h2 class=''mt-3 text-xl font-semibold text-slate-900 dark:text-white''>Catalog + checkout</h2>
283
- <p class=''mt-3 text-sm text-slate-600 dark:text-slate-300''>Products, orders, shipping, and invoices plug right into the CMS shell.</p>
284
- </div>
285
- <div class=''rounded-3xl border border-sky-200/70 bg-sky-50/70 p-6 dark:border-sky-500/20 dark:bg-sky-500/10''>
286
- <p class=''text-xs font-semibold uppercase tracking-[0.22em] text-sky-700 dark:text-sky-200''>Global selling</p>
287
- <h2 class=''mt-3 text-xl font-semibold text-slate-900 dark:text-white''>Multi-currency ready</h2>
288
- <p class=''mt-3 text-sm text-slate-600 dark:text-slate-300''>Live rate sync, price rounding, and market rules make selling worldwide simple.</p>
289
- </div>
290
- <div class=''rounded-3xl border border-indigo-200/70 bg-indigo-50/70 p-6 dark:border-indigo-500/20 dark:bg-indigo-500/10''>
291
- <p class=''text-xs font-semibold uppercase tracking-[0.22em] text-indigo-700 dark:text-indigo-200''>Operator workflow</p>
292
- <h2 class=''mt-3 text-xl font-semibold text-slate-900 dark:text-white''>Provider-aware flow</h2>
293
- <p class=''mt-3 text-sm text-slate-600 dark:text-slate-300''>Stripe and Freemius run side by side so your shop stays clean and easy to use.</p>
294
- </div>
295
- </div>
296
-
297
- <h2>Product Catalog</h2>
298
- <p>The store supports physical goods and digital downloads. You can set up variants, custom options, images, prices, SKUs, and stock levels. Product photos live in your main media library. That means your content and marketing teams work with the same files.</p>
299
-
300
- <h2>Multi-Currency Engine</h2>
301
- <p>The pricing engine is built for real international stores. It handles rates, rounding, and rules with ease:</p>
302
- <ul class=''list-disc pl-6 space-y-2 text-sm''>
303
- <li><strong>Unlimited currencies:</strong> Add any ISO currency code, symbol, and exchange rate.</li>
304
- <li><strong>Auto FX sync:</strong> Refresh daily rates from Frankfurter or your own provider URL.</li>
305
- <li><strong>Rounding rules:</strong> Round prices up, down, or use charm pricing like <code>9.99</code>.</li>
306
- <li><strong>Store auto-sync:</strong> Convert product prices whenever currency rates refresh.</li>
307
- <li><strong>Rebasing:</strong> Switch your base store currency with full recalculations.</li>
308
- <li><strong>Custom price overrides:</strong> Set exact prices for specific countries when needed.</li>
309
- </ul>
310
-
311
- <h2>Tax Automation</h2>
312
- <p>You can set tax rates by hand or let Stripe Tax calculate totals automatically:</p>
313
- <div class=''grid md:grid-cols-2 gap-6 my-6''>
314
- <div class=''p-6 rounded-2xl border border-slate-200 dark:border-white/10 bg-slate-50 dark:bg-white/5''>
315
- <h3 class=''font-bold text-slate-900 dark:text-white mb-2''>Manual mode</h3>
316
- <p class=''text-sm text-slate-600 dark:text-slate-400''>Set tax rates by country, state, or province. Stacked rates like GST and PST are supported. Detailed tax lines are saved with each order.</p>
317
- </div>
318
- <div class=''p-6 rounded-2xl border border-slate-200 dark:border-white/10 bg-slate-50 dark:bg-white/5''>
319
- <h3 class=''font-bold text-slate-900 dark:text-white mb-2''>Automatic mode</h3>
320
- <p class=''text-sm text-slate-600 dark:text-slate-400''>Stripe Tax calculates final amounts during checkout. Product tax codes travel with each item, and webhooks record final numbers.</p>
321
- </div>
322
- </div>
323
-
324
- <h2>Shipping and Checkout</h2>
325
- <p>Shipping zones match by country and state. They support local method names, per-currency pricing, and free shipping rules. Fallback options ensure buyers always see a valid rate.</p>
326
- <p>The checkout flow understands different payment providers:</p>
327
- <ul class=''list-disc pl-6 space-y-2 text-sm''>
328
- <li><strong>Stripe:</strong> Handles physical goods, inventory checks, shipping costs, taxes, and Checkout sessions.</li>
329
- <li><strong>Freemius:</strong> Handles digital software licenses, plans, and hosted checkout pages.</li>
330
- <li>Cart items stay grouped by provider so the buying steps are always clear.</li>
331
- </ul>
332
-
333
- <figure class=''my-12 overflow-hidden rounded-[2rem] border border-slate-200/80 bg-slate-950 shadow-2xl dark:border-white/10''>
334
- <img src=''/images/commerce-plan.webp'' alt=''Commerce roadmap board outlining premium module goals and future storefront capabilities for NextBlock™'' class=''w-full h-auto object-cover'' />
335
- <figcaption class=''border-t border-white/10 px-6 py-4 text-sm text-slate-300''>Commerce is the first premium module on our roadmap. It fits naturally into the larger CMS platform.</figcaption>
336
- </figure>
337
-
338
- <h2>Inventory, Orders, and Invoices</h2>
339
- <p>When stock tracking is on, checkout checks quantities before payment. Once paid, stock counts update in the database right away.</p>
340
- <ul class=''list-disc pl-6 space-y-2 text-sm''>
341
- <li>Order status moves smoothly from pending to paid to shipped.</li>
342
- <li>Invoice numbers generate through safe database functions.</li>
343
- <li>Printable invoices use your company brand settings.</li>
344
- <li>Customers can view their past orders and receipts anytime.</li>
345
- </ul>
346
-
347
- <h2>Commerce Surfaces Inside the CMS</h2>
348
- <p>When the store package is active, the CMS reveals new screens. You get product lists, stock tools, order details, shipping setup, tax rules, and currency settings. All of these screens look and feel like the rest of the CMS, so your team feels right at home.</p>
349
- '::text)),
350
- updated_at = now()
351
- WHERE post_id = 5
352
- AND content->>'html_content' LIKE '%NextBlock™ Commerce is the first premium module%';
353
-
354
- -- Post 6: Commerce FR
355
- UPDATE public.blocks
356
- SET content = jsonb_set(content, '{html_content}', to_jsonb('
357
- <p class=''text-lg leading-8 text-slate-700 dark:text-slate-300''>NextBlock™ Commerce est notre premier module premium. Il ajoute une vraie boutique en ligne directement dans le CMS. Il s''adresse aux équipes qui veulent réunir leurs articles, leur catalogue et leurs ventes au même endroit.</p>
358
-
359
- <div class=''grid gap-4 md:grid-cols-3 my-10''>
360
- <div class=''rounded-3xl border border-emerald-200/70 bg-emerald-50/70 p-6 dark:border-emerald-500/20 dark:bg-emerald-500/10''>
361
- <p class=''text-xs font-semibold uppercase tracking-[0.22em] text-emerald-700 dark:text-emerald-200''>Cœur commerce</p>
362
- <h2 class=''mt-3 text-xl font-semibold text-slate-900 dark:text-white''>Catalogue + checkout</h2>
363
- <p class=''mt-3 text-sm text-slate-600 dark:text-slate-300''>Articles, commandes, livraison et factures s''intègrent dans le même CMS.</p>
364
- </div>
365
- <div class=''rounded-3xl border border-sky-200/70 bg-sky-50/70 p-6 dark:border-sky-500/20 dark:bg-sky-500/10''>
366
- <p class=''text-xs font-semibold uppercase tracking-[0.22em] text-sky-700 dark:text-sky-200''>Vente internationale</p>
367
- <h2 class=''mt-3 text-xl font-semibold text-slate-900 dark:text-white''>Multi-devise</h2>
368
- <p class=''mt-3 text-sm text-slate-600 dark:text-slate-300''>Taux de change en direct, prix ronds et règles locales facilitent les ventes.</p>
369
- </div>
370
- <div class=''rounded-3xl border border-indigo-200/70 bg-indigo-50/70 p-6 dark:border-indigo-500/20 dark:bg-indigo-500/10''>
371
- <p class=''text-xs font-semibold uppercase tracking-[0.22em] text-indigo-700 dark:text-indigo-200''>Gestion claire</p>
372
- <h2 class=''mt-3 text-xl font-semibold text-slate-900 dark:text-white''>Par fournisseur</h2>
373
- <p class=''mt-3 text-sm text-slate-600 dark:text-slate-300''>Stripe et Freemius fonctionnent ensemble pour garder une boutique claire.</p>
374
- </div>
375
- </div>
376
-
377
- <h2>Catalogue produits</h2>
378
- <p>Le module gère les biens physiques et les produits téléchargeables. Vous pouvez créer des variantes, des options sur mesure, des images, des prix, des SKU et des niveaux de stock. Vos visuels restent rangés dans votre médiathèque habituelle. Rédacteurs et vendeurs travaillent donc avec les mêmes fichiers.</p>
379
-
380
- <h2>Moteur multi-devise</h2>
381
- <p>La gestion des prix est conçue pour de vraies boutiques mondiales :</p>
382
- <ul class=''list-disc pl-6 space-y-2 text-sm''>
383
- <li><strong>Devises illimitées :</strong> Ajoutez chaque code de devise, son symbole et son taux de conversion.</li>
384
- <li><strong>Mise à jour automatique :</strong> Actualisez les taux chaque jour avec Frankfurter ou votre URL privée.</li>
385
- <li><strong>Arrondis des prix :</strong> Arrondissez vers le haut, vers le bas ou avec des prix comme <code>9,99</code>.</li>
386
- <li><strong>Synchronisation du catalogue :</strong> Convertissez les prix dès que les devises changent.</li>
387
- <li><strong>Changement de devise socle :</strong> Changez la monnaie par défaut avec recalcul complet.</li>
388
- <li><strong>Prix personnalisés :</strong> Fixez des prix précis pour chaque pays si nécessaire.</li>
389
- </ul>
390
-
391
- <h2>Taxes automatiques</h2>
392
- <p>Vous pouvez régler vos taux à la main ou laisser Stripe Tax faire les calculs :</p>
393
- <div class=''grid md:grid-cols-2 gap-6 my-6''>
394
- <div class=''p-6 rounded-2xl border border-slate-200 dark:border-white/10 bg-slate-50 dark:bg-white/5''>
395
- <h3 class=''font-bold text-slate-900 dark:text-white mb-2''>Mode manuel</h3>
396
- <p class=''text-sm text-slate-600 dark:text-slate-400''>Réglez les taux par pays et province. Les taxes cumulées comme la TPS et la TVQ sont gérées. Chaque ligne est enregistrée sur la commande.</p>
397
- </div>
398
- <div class=''p-6 rounded-2xl border border-slate-200 dark:border-white/10 bg-slate-50 dark:bg-white/5''>
399
- <h3 class=''font-bold text-slate-900 dark:text-white mb-2''>Mode automatique</h3>
400
- <p class=''text-sm text-slate-600 dark:text-slate-400''>Stripe Tax calcule les montants finaux lors de l''achat. Les codes fiscaux suivent les articles, et les webhooks confirment les chiffres.</p>
401
- </div>
402
- </div>
403
-
404
- <h2>Livraison et checkout</h2>
405
- <p>Les zones de livraison se basent sur le pays et la région. Elles acceptent des libellés traduits, des tarifs par devise et la gratuité dès un certain montant. Un tarif de secours évite les blocages.</p>
406
- <p>Le tunnel d''achat s''adapte à chaque passerelle de paiement :</p>
407
- <ul class=''list-disc pl-6 space-y-2 text-sm''>
408
- <li><strong>Stripe :</strong> Gère les produits physiques, les stocks, la livraison, les taxes et les sessions Checkout.</li>
409
- <li><strong>Freemius :</strong> Gère les licences de logiciels, les formules et les pages de paiement sécurisées.</li>
410
- <li>Les articles restent séparés par fournisseur pour garder un parcours d''achat très simple.</li>
411
- </ul>
412
-
413
- <figure class=''my-12 overflow-hidden rounded-[2rem] border border-slate-200/80 bg-slate-950 shadow-2xl dark:border-white/10''>
414
- <img src=''/images/commerce-plan.webp'' alt=''Plan de développement de la boutique NextBlock illustrant les futures capacités e-commerce'' class=''w-full h-auto object-cover'' />
415
- <figcaption class=''border-t border-white/10 px-6 py-4 text-sm text-slate-300''>Le commerce est le premier module officiel de notre feuille de route. Il s''intègre au cœur du CMS.</figcaption>
416
- </figure>
417
-
418
- <h2>Inventaire, commandes et factures</h2>
419
- <p>Quand le suivi de stock est actif, le panier vérifie les quantités avant paiement. Après paiement, les stocks diminuent aussitôt dans la base de données.</p>
420
- <ul class=''list-disc pl-6 space-y-2 text-sm''>
421
- <li>Le statut passe simplement de panier en attente à payé puis expédié.</li>
422
- <li>Les numéros de facture sont créés par des fonctions sûres en base.</li>
423
- <li>Les factures à imprimer reprennent les couleurs de votre marque.</li>
424
- <li>Vos clients peuvent consulter l''historique de leurs commandes à tout moment.</li>
425
- </ul>
426
-
427
- <h2>Surfaces commerce dans le CMS</h2>
428
- <p>Quand le module de vente est activé, le CMS affiche de nouveaux écrans. Vous profitez de la liste des articles, du suivi des stocks, des commandes, de la livraison, des taxes et des devises. Ces pages reprennent le design habituel du CMS pour ne pas dépayser votre équipe.</p>
429
- '::text)),
430
- updated_at = now()
431
- WHERE post_id = 6
432
- AND content->>'html_content' LIKE '%NextBlock™ Commerce est le premier module premium de l''ecosysteme%';
433
-
434
- -- Post 7: Cortex AI EN
435
- UPDATE public.blocks
436
- SET content = jsonb_set(content, '{html_content}', to_jsonb('
437
- <p class=''text-lg leading-8 text-slate-700 dark:text-slate-300''>NextBlock Cortex AI is the smart content tool built for modern web pages. It understands page blocks, section layouts, and editorial rules so you can create better content faster.</p>
438
-
439
- <div class=''grid gap-4 md:grid-cols-3 my-10''>
440
- <div class=''rounded-3xl border border-violet-200/70 bg-violet-50/80 p-6 dark:border-violet-500/20 dark:bg-violet-500/10''>
441
- <p class=''text-xs font-semibold uppercase tracking-[0.22em] text-violet-700 dark:text-violet-200''>Model routing</p>
442
- <h2 class=''mt-3 text-xl font-semibold text-slate-900 dark:text-white''>Pick the right model</h2>
443
- <p class=''mt-3 text-sm text-slate-600 dark:text-slate-300''>Route your prompts through OpenRouter or your own provider to balance speed and price.</p>
444
- </div>
445
- <div class=''rounded-3xl border border-sky-200/70 bg-sky-50/80 p-6 dark:border-sky-500/20 dark:bg-sky-500/10''>
446
- <p class=''text-xs font-semibold uppercase tracking-[0.22em] text-sky-700 dark:text-sky-200''>BYOK control</p>
447
- <h2 class=''mt-3 text-xl font-semibold text-slate-900 dark:text-white''>Use your own keys</h2>
448
- <p class=''mt-3 text-sm text-slate-600 dark:text-slate-300''>Keep provider keys safe on your server while giving editors a simple AI writing screen.</p>
449
- </div>
450
- <div class=''rounded-3xl border border-emerald-200/70 bg-emerald-50/80 p-6 dark:border-emerald-500/20 dark:bg-emerald-500/10''>
451
- <p class=''text-xs font-semibold uppercase tracking-[0.22em] text-emerald-700 dark:text-emerald-200''>Typed output</p>
452
- <h2 class=''mt-3 text-xl font-semibold text-slate-900 dark:text-white''>Generate valid blocks</h2>
453
- <p class=''mt-3 text-sm text-slate-600 dark:text-slate-300''>Typed schemas ensure AI content drops straight into your pages as clean, working blocks.</p>
454
- </div>
455
- </div>
456
-
457
- <h2>Why Cortex AI Belongs Inside the Editor</h2>
458
- <p>Generic chat tools can draft text, but they do not know the difference between a hero banner, a card grid, and a blog post. Cortex AI lives right inside your editing screen. It creates content that fits the blocks on your live site.</p>
459
- <p>This makes AI truly useful for everyday work. You can draft a new landing section, polish a summary, expand product copy, or translate a full article with ease.</p>
460
-
461
- <div class=''rounded-[2rem] border border-slate-200/80 bg-slate-50/90 p-6 my-10 dark:border-white/10 dark:bg-slate-900/70''>
462
- <p class=''text-xs font-semibold uppercase tracking-[0.22em] text-violet-700 dark:text-violet-200''>Editorial workflow</p>
463
- <div class=''grid gap-5 md:grid-cols-2 mt-5''>
464
- <div class=''rounded-2xl border border-slate-200 bg-white p-5 dark:border-white/10 dark:bg-slate-950/50''>
465
- <h3 class=''mt-0 text-xl text-slate-900 dark:text-white''>Faster first drafts</h3>
466
- <p class=''text-sm text-slate-600 dark:text-slate-300''>Start with a prompt and get a section, article draft, or product story that matches your tone.</p>
467
- </div>
468
- <div class=''rounded-2xl border border-slate-200 bg-white p-5 dark:border-white/10 dark:bg-slate-950/50''>
469
- <h3 class=''mt-0 text-xl text-slate-900 dark:text-white''>Cleaner revisions</h3>
470
- <p class=''text-sm text-slate-600 dark:text-slate-300''>Ask for shorter, clearer, or translated text without leaving your edit screen.</p>
471
- </div>
472
- </div>
473
- </div>
474
-
475
- <h2>Model Routing and Cost Control</h2>
476
- <p>Cortex AI gives you full control over your models. You can pick fast models for quick drafts and stronger models for technical articles. You manage your API keys on the server, so your writers can focus on good content.</p>
477
- <ul class=''list-disc pl-6 space-y-2 text-sm''>
478
- <li>Use quick models for rewrites, titles, and summaries.</li>
479
- <li>Use top models for long guides and difficult translations.</li>
480
- <li>Keep provider keys safe in your private server settings.</li>
481
- <li>Control costs without changing how pages display to visitors.</li>
482
- </ul>
483
-
484
- <h2>Block-Aware Generation</h2>
485
- <p>Cortex AI does more than write plain text. It creates structured content that maps directly to NextBlock components. You get ready-to-use section copy, headings, buttons, and translated blocks. You spend less time fixing messy copy from external tools.</p>
486
- <p>Because the generated content respects your block rules, everything looks consistent and runs fast on the web.</p>
487
-
488
- <h2>Safer Team Workflows</h2>
489
- <p>AI works best when humans stay in control. With Cortex AI, editors review every draft before publishing. Developers manage the model keys, and the CMS keeps all versions in your normal history log.</p>
490
-
491
- <h2>A Practical Launch Flow</h2>
492
- <ol class=''list-decimal pl-6 space-y-2 text-sm''>
493
- <li>Draft an article, landing section, or product story from a clear prompt.</li>
494
- <li>Refine the text to match your audience and brand tone.</li>
495
- <li>Create a translated version or shorter summary for social cards and search tags.</li>
496
- <li>Review the content in the editor, hit publish, and track your revisions over time.</li>
497
- </ol>
498
-
499
- <p>Cortex AI turns your CMS into a faster creative workshop. It does not replace human taste, but it helps you turn great ideas into finished pages in record time.</p>
500
- '::text)),
501
- updated_at = now()
502
- WHERE post_id = 7
503
- AND content->>'html_content' LIKE '%NextBlock Cortex AI is the AI layer built%';
504
-
505
- -----------------------------------------------------------------------------
506
- -- 4. Page Block Content Optimizations (Content-Guarded)
507
- -----------------------------------------------------------------------------
508
-
509
- -- Page 1 Block Updates
510
- UPDATE public.blocks
511
- SET content = replace(content::text, 'Edge-rendered marketing sites, launches, and docs with uncompromising performance.', 'Fast edge-rendered sites, launches, and docs. Built for top speed and clean code.')::jsonb,
512
- updated_at = now()
513
- WHERE page_id = 1
514
- AND content::text LIKE '%' || 'Edge-rendered marketing sites, launches,' || '%';
515
-
516
- UPDATE public.blocks
517
- SET content = replace(content::text, 'NextBlock™ is the open-source, developer-first Next.js CMS that merges 100% Lighthouse scores with a powerful visual block editor.', 'NextBlock™ is the open-source Next.js CMS that pairs 100% Lighthouse scores with a visual block editor.')::jsonb,
518
- updated_at = now()
519
- WHERE page_id = 1
520
- AND content::text LIKE '%' || 'NextBlock™ is the open-source, developer' || '%';
521
-
522
- UPDATE public.blocks
523
- SET content = replace(content::text, 'NextBlock™ is a holistic platform that unites performance, editorial experience, and developer control so every stakeholder delivers their best work.', 'NextBlock™ brings speed, clear editing, and developer control together so your team can build better web pages.')::jsonb,
524
- updated_at = now()
525
- WHERE page_id = 1
526
- AND content::text LIKE '%' || 'NextBlock™ is a holistic platform that u' || '%';
527
-
528
- UPDATE public.blocks
529
- SET content = replace(content::text, 'Built for 100% Lighthouse scores with global delivery and near-instant FCP.', 'Built for top Lighthouse scores, quick page loads, and fast global delivery.')::jsonb,
530
- updated_at = now()
531
- WHERE page_id = 1
532
- AND content::text LIKE '%' || 'Built for 100% Lighthouse scores with gl' || '%';
533
-
534
- UPDATE public.blocks
535
- SET content = replace(content::text, 'A low-code, Notion-style block editor empowers teams to ship pages without engineering help.', 'A clean block editor gives your team the power to create pages without writing code.')::jsonb,
536
- updated_at = now()
537
- WHERE page_id = 1
538
- AND content::text LIKE '%' || 'A low-code, Notion-style block editor em' || '%';
539
-
540
- UPDATE public.blocks
541
- SET content = replace(content::text, 'Open-source control with a clean Nx monorepo and a typed SDK for limitless customization.', 'Full open-source control with a clean monorepo and typed tools to build custom blocks with ease.')::jsonb,
542
- updated_at = now()
543
- WHERE page_id = 1
544
- AND content::text LIKE '%' || 'Open-source control with a clean Nx mono' || '%';
545
-
546
- UPDATE public.blocks
547
- SET content = replace(content::text, 'Every layer of NextBlock™ leans on proven developer-first technology so the platform feels familiar, performant, and trustworthy from day one.', 'NextBlock™ uses tools you already know and trust, so your site stays fast, safe, and easy to run.')::jsonb,
548
- updated_at = now()
549
- WHERE page_id = 1
550
- AND content::text LIKE '%' || 'Every layer of NextBlock™ leans on prove' || '%';
551
-
552
- UPDATE public.blocks
553
- SET content = replace(content::text, 'For Content Creators', 'For Writers and Editors')::jsonb,
554
- updated_at = now()
555
- WHERE page_id = 1
556
- AND content::text LIKE '%' || 'For Content Creators' || '%';
557
-
558
- UPDATE public.blocks
559
- SET content = replace(content::text, 'Drag-and-drop layouts with a Notion-like interface.', 'Drag and drop blocks in a clean, simple layout.')::jsonb,
560
- updated_at = now()
561
- WHERE page_id = 1
562
- AND content::text LIKE '%' || 'Drag-and-drop layouts with a Notion-like' || '%';
563
-
564
- UPDATE public.blocks
565
- SET content = replace(content::text, 'Pre-built hero, feature, testimonial, and callout components.', 'Add heroes, galleries, and quotes with one click.')::jsonb,
566
- updated_at = now()
567
- WHERE page_id = 1
568
- AND content::text LIKE '%' || 'Pre-built hero, feature, testimonial, an' || '%';
569
-
570
- UPDATE public.blocks
571
- SET content = replace(content::text, 'Drag-and-drop assets with folders, search, and alt text.', 'Keep your images organized with folders and tags.')::jsonb,
572
- updated_at = now()
573
- WHERE page_id = 1
574
- AND content::text LIKE '%' || 'Drag-and-drop assets with folders, searc' || '%';
575
-
576
- UPDATE public.blocks
577
- SET content = replace(content::text, 'Audit trail with one-click restore for every change.', 'Restore any saved version with a single click.')::jsonb,
578
- updated_at = now()
579
- WHERE page_id = 1
580
- AND content::text LIKE '%' || 'Audit trail with one-click restore for e' || '%';
581
-
582
- UPDATE public.blocks
583
- SET content = replace(content::text, 'Server Components, ISR, and Edge Functions ready out of the box.', 'Built with Server Components and fast edge caching.')::jsonb,
584
- updated_at = now()
585
- WHERE page_id = 1
586
- AND content::text LIKE '%' || 'Server Components, ISR, and Edge Functio' || '%';
587
-
588
- UPDATE public.blocks
589
- SET content = replace(content::text, 'Postgres, Auth, Storage, and Row-Level Security fully wired.', 'Postgres database, user auth, and file storage ready to use.')::jsonb,
590
- updated_at = now()
591
- WHERE page_id = 1
592
- AND content::text LIKE '%' || 'Postgres, Auth, Storage, and Row-Level S' || '%';
593
-
594
- UPDATE public.blocks
595
- SET content = replace(content::text, 'Nx-powered monorepo engineered for scale and clean separation.', 'An Nx workspace made for scale and clean code.')::jsonb,
596
- updated_at = now()
597
- WHERE page_id = 1
598
- AND content::text LIKE '%' || 'Nx-powered monorepo engineered for scale' || '%';
599
-
600
- UPDATE public.blocks
601
- SET content = replace(content::text, 'TypeScript SDK with Zod validation for building custom blocks.', 'Build and type new blocks in minutes.')::jsonb,
602
- updated_at = now()
603
- WHERE page_id = 1
604
- AND content::text LIKE '%' || 'TypeScript SDK with Zod validation for b' || '%';
605
-
606
- UPDATE public.blocks
607
- SET content = replace(content::text, 'NextBlock™ Commerce transforms your content platform into a complete e-commerce engine. Products, checkout, multi-currency, taxes, shipping, invoices — all natively integrated into the block editor you already know.', 'NextBlock™ Commerce turns your content site into a full online store. Sell products, take payments, handle taxes, and ship orders — all from the block editor you already use.')::jsonb,
608
- updated_at = now()
609
- WHERE page_id = 1
610
- AND content::text LIKE '%' || 'NextBlock™ Commerce transforms your cont' || '%';
611
-
612
- UPDATE public.blocks
613
- SET content = replace(content::text, 'NextBlock™ Commerce transforms your content platform into a complete e-commerce engine. Products, checkout, multi-currency, taxes, shipping, invoices — all natively integrated into the block editor you already know.', 'NextBlock™ Commerce turns your content site into a full online store. Sell products, take payments, handle taxes, and ship orders — all from the block editor you already use.')::jsonb,
614
- updated_at = now()
615
- WHERE page_id = 1
616
- AND content::text LIKE '%' || 'NextBlock™ Commerce transforms your cont' || '%';
617
-
618
- UPDATE public.blocks
619
- SET content = replace(content::text, 'NextBlock™ Commerce ships a complete e-commerce toolkit so you can go from catalog to checkout without third-party plugins.', 'NextBlock™ Commerce ships a complete online store toolkit so you can go from catalog to checkout with ease.')::jsonb,
620
- updated_at = now()
621
- WHERE page_id = 1
622
- AND content::text LIKE '%' || 'NextBlock™ Commerce ships a complete e-c' || '%';
623
-
624
- UPDATE public.blocks
625
- SET content = replace(content::text, 'Live FX rates, rounding rules, and auto-sync across all currencies.', 'Live exchange rates, round prices, and auto-sync across all currencies.')::jsonb,
626
- updated_at = now()
627
- WHERE page_id = 1
628
- AND content::text LIKE '%' || 'Live FX rates, rounding rules, and auto-' || '%';
629
-
630
- UPDATE public.blocks
631
- SET content = replace(content::text, 'Define custom rates or let Stripe Tax handle calculations automatically.', 'Set custom tax rates or let Stripe Tax calculate totals automatically.')::jsonb,
632
- updated_at = now()
633
- WHERE page_id = 1
634
- AND content::text LIKE '%' || 'Define custom rates or let Stripe Tax ha' || '%';
635
-
636
- UPDATE public.blocks
637
- SET content = replace(content::text, 'Country and state-level zones with free shipping thresholds.', 'Set shipping rates by country and state, with free shipping rules.')::jsonb,
638
- updated_at = now()
639
- WHERE page_id = 1
640
- AND content::text LIKE '%' || 'Country and state-level zones with free ' || '%';
641
-
642
- UPDATE public.blocks
643
- SET content = replace(content::text, 'Stripe for physical goods and Freemius for software licenses with seamless checkout.', 'Use Stripe for physical goods and Freemius for software licenses with simple checkout.')::jsonb,
644
- updated_at = now()
645
- WHERE page_id = 1
646
- AND content::text LIKE '%' || 'Stripe for physical goods and Freemius f' || '%';
647
-
648
- UPDATE public.blocks
649
- SET content = replace(content::text, 'Automatic stock decrement on payment with variant-level tracking.', 'Update stock counts when an order is paid, with variant tracking.')::jsonb,
650
- updated_at = now()
651
- WHERE page_id = 1
652
- AND content::text LIKE '%' || 'Automatic stock decrement on payment wit' || '%';
653
-
654
- UPDATE public.blocks
655
- SET content = replace(content::text, 'Order management, printable invoices, and customer receipts out of the box.', 'Manage orders, print invoices, and view customer reports with ease.')::jsonb,
656
- updated_at = now()
657
- WHERE page_id = 1
658
- AND content::text LIKE '%' || 'Order management, printable invoices, an' || '%';
659
-
660
- UPDATE public.blocks
661
- SET content = replace(content::text, 'NextBlock™ Cortex AI brings native block-level intelligence directly to your editor. Generate copy, refactor structures, and automate translations in one click, built directly on our high-performance architecture.', 'NextBlock™ Cortex AI helps you write, edit, and translate content right inside the block editor. Draft text, refine layouts, and switch languages with ease.')::jsonb,
662
- updated_at = now()
663
- WHERE page_id = 1
664
- AND content::text LIKE '%' || 'NextBlock™ Cortex AI brings native block' || '%';
665
-
666
- UPDATE public.blocks
667
- SET content = replace(content::text, 'NextBlock™ is building a sustainable open-core roadmap so the platform grows with your business.', 'NextBlock™ is built to grow with your business and help your team succeed.')::jsonb,
668
- updated_at = now()
669
- WHERE page_id = 1
670
- AND content::text LIKE '%' || 'NextBlock™ is building a sustainable ope' || '%';
671
-
672
-
673
- -- Page 2 Block Updates
674
- UPDATE public.blocks
675
- SET content = replace(content::text, 'NextBlock™ est le CMS Next.js open-source alliant scores Lighthouse parfaits et éditeur visuel puissant.', 'NextBlock™ est le CMS Next.js open-source alliant scores parfaits et éditeur de blocs visuel.')::jsonb,
676
- updated_at = now()
677
- WHERE page_id = 2
678
- AND content::text LIKE '%' || 'NextBlock™ est le CMS Next.js open-sourc' || '%';
679
-
680
- UPDATE public.blocks
681
- SET content = replace(content::text, 'Sites marketing et docs rendus à l''edge avec des performances irréprochables.', 'Sites marketing et docs rendus à l''edge. Conçus pour la vitesse et un code propre.')::jsonb,
682
- updated_at = now()
683
- WHERE page_id = 2
684
- AND content::text LIKE '%' || 'Sites marketing et docs rendus à l''edge ' || '%';
685
-
686
- UPDATE public.blocks
687
- SET content = replace(content::text, 'NextBlock™ unifie performances, expérience éditoriale et contrôle développeur pour que chaque équipe livre son meilleur travail.', 'NextBlock™ réunit la vitesse, la clarté d''édition et le contrôle développeur. Votre équipe peut ainsi créer de meilleures pages web.')::jsonb,
688
- updated_at = now()
689
- WHERE page_id = 2
690
- AND content::text LIKE '%' || 'NextBlock™ unifie performances, expérien' || '%';
691
-
692
- UPDATE public.blocks
693
- SET content = replace(content::text, 'Pensé pour des scores Lighthouse parfaits avec une diffusion mondiale.', 'Conçu pour des scores élevés et une diffusion rapide.')::jsonb,
694
- updated_at = now()
695
- WHERE page_id = 2
696
- AND content::text LIKE '%' || 'Pensé pour des scores Lighthouse parfait' || '%';
697
-
698
- UPDATE public.blocks
699
- SET content = replace(content::text, 'Un éditeur façon Notion pour publier sans dépendre des développeurs.', 'Un éditeur simple pour publier sans coder.')::jsonb,
700
- updated_at = now()
701
- WHERE page_id = 2
702
- AND content::text LIKE '%' || 'Un éditeur façon Notion pour publier san' || '%';
703
-
704
- UPDATE public.blocks
705
- SET content = replace(content::text, 'Un socle Next.js + Supabase modulaire, extensible et auto-hébergeable.', 'Un socle moderne, souple et très simple à faire grandir.')::jsonb,
706
- updated_at = now()
707
- WHERE page_id = 2
708
- AND content::text LIKE '%' || 'Un socle Next.js + Supabase modulaire, e' || '%';
709
-
710
- UPDATE public.blocks
711
- SET content = replace(content::text, 'Chaque couche de NextBlock™ repose sur des technologies éprouvées pour une expérience familière et performante.', 'NextBlock™ s''appuie sur des outils fiables et éprouvés. Votre site reste rapide, robuste et facile à maintenir au quotidien.')::jsonb,
712
- updated_at = now()
713
- WHERE page_id = 2
714
- AND content::text LIKE '%' || 'Chaque couche de NextBlock™ repose sur d' || '%';
715
-
716
- UPDATE public.blocks
717
- SET content = replace(content::text, 'Glisser-déposer façon Notion.', 'Glissez et déposez vos blocs dans une mise en page claire.')::jsonb,
718
- updated_at = now()
719
- WHERE page_id = 2
720
- AND content::text LIKE '%' || 'Glisser-déposer façon Notion.' || '%';
721
-
722
- UPDATE public.blocks
723
- SET content = replace(content::text, 'Héros, galeries, témoignages.', 'Insérez des héros, des galeries et des avis clients en un clic.')::jsonb,
724
- updated_at = now()
725
- WHERE page_id = 2
726
- AND content::text LIKE '%' || 'Héros, galeries, témoignages.' || '%';
727
-
728
- UPDATE public.blocks
729
- SET content = replace(content::text, 'Dossiers, tags et actions groupées.', 'Rangez vos photos et médias avec des dossiers et des tags.')::jsonb,
730
- updated_at = now()
731
- WHERE page_id = 2
732
- AND content::text LIKE '%' || 'Dossiers, tags et actions groupées.' || '%';
733
-
734
- UPDATE public.blocks
735
- SET content = replace(content::text, 'Historique et restauration instantanée.', 'Retrouvez et restaurez vos versions précédentes sans stress.')::jsonb,
736
- updated_at = now()
737
- WHERE page_id = 2
738
- AND content::text LIKE '%' || 'Historique et restauration instantanée.' || '%';
739
-
740
- UPDATE public.blocks
741
- SET content = replace(content::text, 'Server Components, ISR et Edge prêts à l''emploi.', 'Conçu avec Server Components et un cache edge très rapide.')::jsonb,
742
- updated_at = now()
743
- WHERE page_id = 2
744
- AND content::text LIKE '%' || 'Server Components, ISR et Edge prêts à l' || '%';
745
-
746
- UPDATE public.blocks
747
- SET content = replace(content::text, 'Postgres, auth, stockage, temps réel.', 'Base Postgres, profils, auth et stockage de fichiers prêts à l''emploi.')::jsonb,
748
- updated_at = now()
749
- WHERE page_id = 2
750
- AND content::text LIKE '%' || 'Postgres, auth, stockage, temps réel.' || '%';
751
-
752
- UPDATE public.blocks
753
- SET content = replace(content::text, 'Dépendances lisibles et centrales.', 'Une structure claire et bien rangée faite pour grandir sereinement.')::jsonb,
754
- updated_at = now()
755
- WHERE page_id = 2
756
- AND content::text LIKE '%' || 'Dépendances lisibles et centrales.' || '%';
757
-
758
- UPDATE public.blocks
759
- SET content = replace(content::text, 'Widgets typés et extensibles.', 'Créez et typez vos nouveaux composants en un instant.')::jsonb,
760
- updated_at = now()
761
- WHERE page_id = 2
762
- AND content::text LIKE '%' || 'Widgets typés et extensibles.' || '%';
763
-
764
- UPDATE public.blocks
765
- SET content = replace(content::text, 'NextBlock™ Commerce transforme votre plateforme de contenu en moteur e-commerce complet. Produits, checkout, multi-devises, taxes, expédition, factures — le tout intégré nativement dans l''éditeur de blocs que vous connaissez déjà.', 'NextBlock™ Commerce transforme votre site de contenu en vraie boutique en ligne. Vendez des articles et recevez des paiements en ligne. Gérez vos taxes et vos envois dans l''éditeur que vous connaissez déjà.')::jsonb,
766
- updated_at = now()
767
- WHERE page_id = 2
768
- AND content::text LIKE '%' || 'NextBlock™ Commerce transforme votre pla' || '%';
769
-
770
- UPDATE public.blocks
771
- SET content = replace(content::text, 'NextBlock™ Commerce livre une boîte à outils e-commerce complète pour aller du catalogue au paiement sans plugins tiers.', 'NextBlock™ Commerce propose une boîte à outils complète. Allez du catalogue au paiement sans aucun plugin externe.')::jsonb,
772
- updated_at = now()
773
- WHERE page_id = 2
774
- AND content::text LIKE '%' || 'NextBlock™ Commerce livre une boîte à ou' || '%';
775
-
776
- UPDATE public.blocks
777
- SET content = replace(content::text, 'Taux de change en temps réel, modes d''arrondi, prix charme et synchronisation automatique sur toutes les devises.', 'Taux de change en direct, prix ronds et mise à jour automatique sur toutes les devises.')::jsonb,
778
- updated_at = now()
779
- WHERE page_id = 2
780
- AND content::text LIKE '%' || 'Taux de change en temps réel, modes d''ar' || '%';
781
-
782
- UPDATE public.blocks
783
- SET content = replace(content::text, 'Taux manuels empilés (TPS + TVQ) ou calcul automatique via Stripe Tax — à vous de choisir.', 'Définissez vos taxes ou laissez Stripe Tax calculer les montants finaux.')::jsonb,
784
- updated_at = now()
785
- WHERE page_id = 2
786
- AND content::text LIKE '%' || 'Taux manuels empilés (TPS + TVQ) ou calc' || '%';
787
-
788
- UPDATE public.blocks
789
- SET content = replace(content::text, 'Résolution par pays et état, tarification par devise et seuils de livraison gratuite.', 'Ajustez les frais de port par pays et état avec des règles d''envoi gratuit.')::jsonb,
790
- updated_at = now()
791
- WHERE page_id = 2
792
- AND content::text LIKE '%' || 'Résolution par pays et état, tarificatio' || '%';
793
-
794
- UPDATE public.blocks
795
- SET content = replace(content::text, 'Stripe pour les produits physiques, Freemius pour les licences numériques — checkout intelligent avec validation d''inventaire.', 'Paiement Stripe pour les biens et Freemius pour les licences logicielles.')::jsonb,
796
- updated_at = now()
797
- WHERE page_id = 2
798
- AND content::text LIKE '%' || 'Stripe pour les produits physiques, Free' || '%';
799
-
800
- UPDATE public.blocks
801
- SET content = replace(content::text, 'Déduction automatique des quantités au paiement avec gestion des stocks par variante.', 'Mettez à jour les stocks dès qu''un achat est validé, avec suivi des variantes.')::jsonb,
802
- updated_at = now()
803
- WHERE page_id = 2
804
- AND content::text LIKE '%' || 'Déduction automatique des quantités au p' || '%';
805
-
806
- UPDATE public.blocks
807
- SET content = replace(content::text, 'Gestion du cycle de vie des commandes, numérotation stable des factures et rapports de commandes exportables.', 'Suivez chaque commande, imprimez des factures et téléchargez vos bilans en toute simplicité.')::jsonb,
808
- updated_at = now()
809
- WHERE page_id = 2
810
- AND content::text LIKE '%' || 'Gestion du cycle de vie des commandes, n' || '%';
811
-
812
- UPDATE public.blocks
813
- SET content = replace(content::text, 'NextBlock™ Cortex AI apporte une intelligence native au niveau des blocs directement dans votre éditeur. Générez du texte, restructurez vos contenus et automatisez les traductions en un clic, le tout propulsé par notre architecture haute performance.', 'NextBlock™ Cortex AI vous aide à rédiger, corriger et traduire vos textes au cœur de l''éditeur de blocs. Créez des ébauches, améliorez vos titres et passez d''une langue à l''autre en un clin d''œil.')::jsonb,
814
- updated_at = now()
815
- WHERE page_id = 2
816
- AND content::text LIKE '%' || 'NextBlock™ Cortex AI apporte une intelli' || '%';
817
-
818
- UPDATE public.blocks
819
- SET content = replace(content::text, 'NextBlock™ construit une feuille de route open-core durable qui évolue avec votre activité.', 'NextBlock™ est pensé pour accompagner la croissance de votre entreprise. Nous voulons faire réussir vos projets web.')::jsonb,
820
- updated_at = now()
821
- WHERE page_id = 2
822
- AND content::text LIKE '%' || 'NextBlock™ construit une feuille de rout' || '%';
823
-
824
- UPDATE public.blocks
825
- SET content = replace(content::text, 'Le commerce arrive en premier, puis l''ecosysteme s''etend avec des plugins, des blocs et des modules construits par les partenaires.', 'Le commerce ouvre la voie. Notre écosystème grandit avec de nouveaux plugins, des blocs utiles et des modules partenaires.')::jsonb,
826
- updated_at = now()
827
- WHERE page_id = 2
828
- AND content::text LIKE '%' || 'Le commerce arrive en premier, puis l''ec' || '%';
829
-
830
- UPDATE public.blocks
831
- SET content = replace(content::text, 'Transformez votre site en vitrine composable avec produits, checkout, tarification multi-devise, taxes automatiques et blocs commerce relies a votre contenu editorial.', 'Ajoutez une boutique complète à côté de vos articles. Profitez de produits, du paiement en ligne, de devises et de taxes sans effort.')::jsonb,
832
- updated_at = now()
833
- WHERE page_id = 2
834
- AND content::text LIKE '%' || 'Transformez votre site en vitrine compos' || '%';
835
-
836
- UPDATE public.blocks
837
- SET content = replace(content::text, 'Une marketplace communautaire ouvrira la voie a la publication, la vente et la distribution de blocs, themes, integrations et modules partenaires.', 'Un espace partagé permet aux développeurs de publier et vendre des blocs sur mesure, des thèmes et des outils connectés.')::jsonb,
838
- updated_at = now()
839
- WHERE page_id = 2
840
- AND content::text LIKE '%' || 'Une marketplace communautaire ouvrira la' || '%';
841
-
842
- UPDATE public.blocks
843
- SET content = replace(content::text, 'NextBlock™ se construit en public. Ajoutez une étoile, partagez vos retours et façonnez l''avenir du CMS orienté performance.', 'NextBlock™ avance en public. Mettez une étoile sur le dépôt, partagez vos avis et façonnez la suite avec nous.')::jsonb,
844
- updated_at = now()
845
- WHERE page_id = 2
846
- AND content::text LIKE '%' || 'NextBlock™ se construit en public. Ajout' || '%';
847
-
848
-
849
- -- Page 3 Block Updates
850
- UPDATE public.blocks
851
- SET content = replace(content::text, '<h2 class=''text-4xl md:text-5xl font-bold text-white text-center md:text-left mb-6''>Deep dives into performance, DX, and visual editing.</h2>', '<h1 class=''text-4xl md:text-5xl font-bold text-white text-center md:text-left mb-6''>The NextBlock Journal: Performance, DX, and Visual Editing</h1>')::jsonb,
852
- updated_at = now()
853
- WHERE page_id = 3
854
- AND content::text LIKE '%' || '<h2 class=''text-4xl md:text-5xl font-bol' || '%';
855
-
856
- UPDATE public.blocks
857
- SET content = replace(content::text, '<p class=''text-slate-300 text-lg max-w-xl mx-auto md:mx-0 text-center md:text-left leading-relaxed''>Explore architectural walkthroughs, Supabase recipes, and block editor experiments written by the Nextblock core team.</p>', '<p class=''text-slate-300 text-lg max-w-xl mx-auto md:mx-0 text-center md:text-left leading-relaxed''>Explore practical guides, architecture deep dives, and editor workflows written by the NextBlock team and community.</p> <div class=''mt-8 text-slate-300 space-y-4 max-w-3xl''> <p>Welcome to the NextBlock Journal. This is your home for in-depth technical guides, release notes, and real-world web architecture patterns. Whether you are launching your first Next.js site or scaling an online store, our articles give you clear, tested steps to help you build faster.</p> <p>We believe modern web projects need developer freedom and a simple editing experience. Our engineering posts show how to pair Next.js 16 with Supabase Postgres, edge caching, and server actions without complex glue code. You will learn how to keep your Lighthouse score at 100% while giving teams a rich, block-based writing experience.</p> <p>Here are the key topics we cover across our editorial library:</p> <ul class=''space-y-2 list-disc pl-5''> <li><strong>Getting Started Guides:</strong> Simple setup walkthroughs for one-click Vercel deploys, local Docker environments, and custom cloud stacks.</li> <li><strong>Architecture & Performance:</strong> Deep dives into fast page rendering, clean CSS delivery, image optimization, and safe database migrations.</li> <li><strong>E-Commerce Workflows:</strong> Practical patterns for multi-currency pricing, automated tax sync, stock tracking, and provider checkout flows.</li> <li><strong>AI Content Tools:</strong> How to use Cortex AI to generate structured blocks, manage provider keys, and speed up routine translation work.</li> </ul> <p>Our team updates this collection regularly as we release new core features and modules. We test our code on live sites before publishing. Each post includes full technical explanations and architecture diagrams so you can apply the solutions to your own web stack.</p> <p>Have a topic you want us to cover or want to share your own case study? Join our community on GitHub or reach out to our team anytime. We welcome questions, ideas, and pull requests from all builders. You can subscribe to updates or start reading our latest published articles below.</p> </div>')::jsonb,
858
- updated_at = now()
859
- WHERE page_id = 3
860
- AND content::text LIKE '%' || '<p class=''text-slate-300 text-lg max-w-x' || '%';
861
-
862
-
863
- -- Page 4 Block Updates
864
- UPDATE public.blocks
865
- SET content = replace(content::text, '<h2 class=''text-4xl md:text-5xl font-bold text-white text-center md:text-left mb-6''>Plongées dans la performance, l''expérience dev et l''édition visuelle.</h2>', '<h1 class=''text-4xl md:text-5xl font-bold text-white text-center md:text-left mb-6''>Le Journal NextBlock : Performance, Expérience Dev et Édition</h1>')::jsonb,
866
- updated_at = now()
867
- WHERE page_id = 4
868
- AND content::text LIKE '%' || '<h2 class=''text-4xl md:text-5xl font-bol' || '%';
869
-
870
- UPDATE public.blocks
871
- SET content = replace(content::text, '<p class=''text-lg max-w-xl mx-auto md:mx-0 text-center md:text-left text-slate-300 leading-relaxed''>Walkthroughs d''architecture, recettes Supabase et expérimentations éditeur écrits par l''équipe Nextblock.</p>', '<p class=''text-lg max-w-xl mx-auto md:mx-0 text-center md:text-left text-slate-300 leading-relaxed''>Retrouvez des guides pratiques, des études d''architecture et des conseils pour éditer vos contenus avec NextBlock.</p> <div class=''mt-8 text-slate-300 space-y-4 max-w-3xl''> <p>Bienvenue sur le Journal NextBlock. Cet espace rassemble nos guides techniques détaillés. Vous y trouverez les nouveautés de chaque version et les meilleures pratiques du web moderne. Vous lancez votre premier site Next.js ? Vous faites grandir une boutique en ligne ? Nos articles vous donnent des étapes simples et vérifiées pour construire plus vite.</p> <p>Nous pensons qu''un bon site web doit offrir toute la liberté aux développeurs. Il doit aussi apporter une vraie simplicité aux équipes éditoriales. Nos articles techniques expliquent comment marier Next.js 16 avec Supabase Postgres, le cache edge et les Server Actions. Tout cela se fait sans code superflu. Vous découvrirez comment maintenir un score Lighthouse parfait. En même temps, votre équipe profite d''un éditeur de blocs visuel et très agréable.</p> <p>Voici les principaux sujets abordés dans notre bibliothèque éditoriale :</p> <ul class=''space-y-2 list-disc pl-5''> <li><strong>Guides de démarrage :</strong> Des tutoriels pas à pas pour déployer sur Vercel en un clic, lancer une pile Docker locale ou installer votre propre cloud.</li> <li><strong>Architecture et performance :</strong> Des explications claires sur le rendu rapide des pages, les styles en ligne, l''optimisation des images et les migrations sûres.</li> <li><strong>Commerce en ligne :</strong> Des conseils concrets pour gérer plusieurs devises, synchroniser les taxes, suivre les stocks et réussir vos paiements.</li> <li><strong>Outils IA pour le contenu :</strong> Comment utiliser Cortex AI pour créer des blocs bien typés, garder le contrôle de vos clés et traduire vos pages en un instant.</li> </ul> <p>Notre équipe enrichit cette collection au fil des mises à jour du projet. Nous testons chaque exemple de code sur des sites réels avant publication. Chaque tutoriel propose des explications complètes pour adapter facilement ces solutions à votre propre projet.</p> <p>Vous avez une idée de sujet ou un retour d''expérience à partager ? Rejoignez notre communauté sur GitHub ou contactez notre équipe. Nous accueillons avec grand plaisir vos questions, vos idées et vos contributions. Parcourez dès maintenant nos derniers articles ci-dessous.</p> </div>')::jsonb,
872
- updated_at = now()
873
- WHERE page_id = 4
874
- AND content::text LIKE '%' || '<p class=''text-lg max-w-xl mx-auto md:mx' || '%';
875
-
876
-
877
- -- Page 5 Block Updates
878
- UPDATE public.blocks
879
- SET content = replace(content::text, '<div class=''max-w-2xl mx-auto text-center''><h2 class=''text-2xl font-bold mb-4''>Open Source & Community Driven</h2><p class=''text-slate-600 dark:text-slate-400 mb-6''>NextBlock™ is built in the open. We rely on developers and editors like you to help us define the roadmap. Whether it''s a bug report, a feature request, or just a shoutout, every message helps us move faster.</p></div>', '<div class=''mt-10 text-slate-300 space-y-4 max-w-3xl mx-auto''> <h2 class=''text-2xl font-bold text-white mb-4 text-center''>Open Source & Community Driven</h2> <p>NextBlock™ is built entirely in the open. We work closely with developers, editors, and teams who use the platform every day. Whether you found a bug, want to request a new feature, or need advice on your project setup, our team is here to help you move forward.</p> <p>We read every message sent through this form. Here is what you can expect when reaching out to our team:</p> <ul class=''space-y-2 list-disc pl-5''> <li><strong>Fast Response Times:</strong> Our core maintainers typically review and reply to inquiries within one to two business days.</li> <li><strong>Technical Support:</strong> For public bugs or community questions, our GitHub Discussions and Issues boards offer fast answers from the entire community.</li> <li><strong>Partnership and Modules:</strong> If your team wants to sponsor a roadmap module or build a custom integration, we can schedule a direct call.</li> <li><strong>Security Disclosures:</strong> For responsible disclosure of potential security vulnerabilities, please flag your message as urgent so we can triage it immediately.</li> </ul> <p>Before submitting, please make sure your email address is typed correctly so our team can get back to you. If your question is about a specific code error, including your environment details and reproduction steps helps us find a solution much faster.</p> <p>You can also connect with us directly on GitHub, Discord, or X (formerly Twitter). We host regular community discussions and share sneak peeks of upcoming platform features. If you are building a custom client project with NextBlock, we would love to hear about your experience.</p> <p>We value your time and privacy. We never share your contact information or use your email for marketing without your consent. Send us a message using the form below and we will get back to you shortly.</p> </div>')::jsonb,
880
- updated_at = now()
881
- WHERE page_id = 5
882
- AND content::text LIKE '%' || '<div class=''max-w-2xl mx-auto text-cente' || '%';
883
-
884
-
885
- -- Page 6 Block Updates
886
- UPDATE public.blocks
887
- SET content = replace(content::text, '<div class=''max-w-2xl mx-auto text-center''><h2 class=''text-2xl font-bold mb-4''>Open Source & Communautaire</h2><p class=''text-slate-600 dark:text-slate-400 mb-6''>NextBlock™ est construit en public. Nous comptons sur les développeurs et éditeurs comme vous pour définir notre roadmap. Qu''il s''agisse d''un bug, d''une suggestion ou d''un simple salut, chaque message compte.</p></div>', '<div class=''mt-10 text-slate-300 space-y-4 max-w-3xl mx-auto''> <h2 class=''text-2xl font-bold text-white mb-4 text-center''>Open Source & Communautaire</h2> <p>NextBlock™ est construit entièrement en public. Nous travaillons avec des développeurs et des équipes qui utilisent le CMS chaque jour. Vous avez trouvé un bug ? Vous souhaitez suggérer une fonction ? Vous avez besoin d''aide pour votre installation ? Notre équipe est là pour vous guider.</p> <p>Nous lisons attentivement chaque message reçu via ce formulaire. Voici nos engagements pour vous répondre au mieux :</p> <ul class=''space-y-2 list-disc pl-5''> <li><strong>Délais de réponse rapides :</strong> Nos mainteneurs étudient et répondent aux demandes en un ou deux jours ouvrés.</li> <li><strong>Support technique :</strong> Pour toute question publique, nos forums GitHub Discussions et Issues offrent une aide rapide de la communauté.</li> <li><strong>Partenariats et modules :</strong> Votre équipe veut sponsoriser un module ou concevoir une intégration sur mesure ? Nous pouvons planifier un échange direct.</li> <li><strong>Signalements de sécurité :</strong> Pour toute alerte de sécurité, signalez votre message comme prioritaire pour un traitement immédiat.</li> </ul> <p>Avant d''envoyer votre message, vérifiez bien votre adresse email. Notre équipe pourra ainsi vous répondre rapidement. Si votre demande concerne une erreur technique, mentionnez votre environnement et les étapes pour la reproduire. Cela nous aide à trouver une solution efficace.</p> <p>Vous pouvez aussi échanger avec nous sur GitHub, Discord ou X. Nous y partageons des nouvelles et les coulisses des prochaines versions. Vous développez un projet client avec NextBlock ? Racontez-nous votre aventure. Notre équipe aime voir ce que vous créez au quotidien. Chaque projet est unique. Prenez le temps de nous dire ce qui vous plaît et ce qui vous manque. Vos retours nous aident à faire un meilleur outil pour tout le monde.</p> <p>Nous respectons votre vie privée. Vos coordonnées ne sont jamais cédées ni réutilisées sans votre accord. Écrivez-nous ci-dessous et nous vous répondrons très vite.</p> </div>')::jsonb,
888
- updated_at = now()
889
- WHERE page_id = 6
890
- AND content::text LIKE '%' || '<div class=''max-w-2xl mx-auto text-cente' || '%';
891
-
892
-
893
- -- Page 7 Block Updates
894
- UPDATE public.blocks
895
- SET content = replace(content::text, '<p style="text-align: center; color: var(--background); opacity: 0.9">Discover our premium selection of developer tools and digital commerce solutions.</p>', '<p style="text-align: center; color: var(--background); opacity: 0.9">Discover our selection of official commercial add-ons and developer tools for NextBlock CMS.</p> <div class=''mt-8 text-slate-300 space-y-4 max-w-3xl mx-auto text-left''> <h2 class=''text-2xl font-bold text-white mb-4''>Power Up Your Web Projects</h2> <p>Welcome to the official NextBlock™ digital store. Here you can purchase licenses for our premium packages, including NextBlock™ Commerce and NextBlock™ Cortex AI. Every commercial license helps fund full-time open-source development on our core CMS while giving your team advanced tools to launch high-performance websites faster.</p> <p>Our premium modules are designed to feel native from day one. You get clean code that fits right into your existing NextBlock project without third-party plugins or complex configuration. When you purchase a license from our store, you receive instant access to everything you need:</p> <ul class=''space-y-2 list-disc pl-5''> <li><strong>Full Source Code:</strong> Inspect, customize, and adapt the modules to your exact requirements.</li> <li><strong>Perpetual Use:</strong> Use the software for your project with full peace of mind.</li> <li><strong>Automated Updates:</strong> Enjoy smooth updates that match each new release of NextBlock and Next.js.</li> <li><strong>Secure Checkout:</strong> Payments are processed safely with Stripe and Freemius with instant receipt generation.</li> </ul> <p>Whether you need multi-currency store features, automated sales tax calculations, or AI block generation in your editor, our modules deliver tested solutions that keep your Lighthouse scores at 100%.</p> <p>All purchases include dedicated onboarding resources, detailed developer docs, and friendly technical support. If you ever run into an issue or need help wiring up a provider webhook, our core engineers are ready to assist you. We also offer a thirty-day refund policy so you can try our tools risk-free.</p> <p>Have questions about license tiers, volume pricing, team seats, or custom agency usage? Contact our support team anytime. Our team is here to answer your questions and help your developers succeed. We are happy to help you pick the best plan for your company. Browse our featured products below to get started today.</p> </div>')::jsonb,
896
- updated_at = now()
897
- WHERE page_id = 7
898
- AND content::text LIKE '%' || '<p style="text-align: center; color: var' || '%';
899
-
900
-
901
- -- Page 8 Block Updates
902
- UPDATE public.blocks
903
- SET content = replace(content::text, '<p style="text-align: center; color: var(--background); opacity: 0.9">Decouvrez notre selection premium d outils de developpement.</p>', '<p style="text-align: center; color: var(--background); opacity: 0.9">Découvrez nos extensions officielles et nos outils pour développeurs conçus pour le CMS NextBlock.</p> <div class=''mt-8 text-slate-300 space-y-4 max-w-3xl mx-auto text-left''> <h2 class=''text-2xl font-bold text-white mb-4''>Accélérez vos projets web</h2> <p>Bienvenue sur la boutique officielle de NextBlock™. Vous pouvez acheter ici des licences pour nos modules professionnels, comme NextBlock™ Commerce et NextBlock™ Cortex AI. Chaque achat aide à financer le travail open-source sur le cœur du CMS. Il donne aussi à votre équipe des outils de pointe pour créer des sites rapides et fiables.</p> <p>Nos modules premium s''intègrent sans effort à votre projet existant. Vous profitez d''un code propre et bien testé, sans plugin externe lourd ni réglage complexe. En choisissant nos outils, vous profitez immédiatement de nombreux avantages :</p> <ul class=''space-y-2 list-disc pl-5''> <li><strong>Code source complet :</strong> Lisez, adaptez et faites évoluer chaque bloc selon vos besoins métier.</li> <li><strong>Licence perpétuelle :</strong> Utilisez le code sur votre projet en toute sérénité.</li> <li><strong>Mises à jour suivies :</strong> Recevez les nouvelles versions au rythme de Next.js et de NextBlock.</li> <li><strong>Paiement sécurisé :</strong> Les achats passent par Stripe et Freemius avec facture instantanée.</li> </ul> <p>Vous voulez vendre dans plusieurs devises ? Vous avez besoin du calcul automatique des taxes ? Vous voulez générer des blocs avec l''IA ? Nos modules offrent des solutions prêtes à l''emploi qui préservent vos scores Lighthouse à 100%.</p> <p>Chaque commande donne accès à une documentation claire et à notre support technique. Si vous avez besoin d''aide pour brancher un webhook ou un mode de paiement, nos développeurs vous répondent rapidement. Notre équipe est à vos côtés pour vous faire gagner du temps. Nous proposons aussi une garantie satisfait ou remboursé de trente jours.</p> <p>Vous avez des questions sur nos tarifs, les licences agence ou les remises en volume ? Écrivez à notre équipe à tout moment. Nous vous guiderons avec grand plaisir vers l''offre idéale pour votre entreprise. Découvrez dès aujourd''hui l''ensemble de nos produits ci-dessous pour bien démarrer votre projet.</p> </div>')::jsonb,
904
- updated_at = now()
905
- WHERE page_id = 8
906
- AND content::text LIKE '%' || '<p style="text-align: center; color: var' || '%';
907
-
908
-
909
- -- Page 9 Block Updates
910
- UPDATE public.blocks
911
- SET content = replace(content::text, 'NextBlock™ CMS ("we", "us", or "our") respects your privacy and is committed to protecting your personal information in accordance with Quebec''s <em>Act respecting the protection of personal information in the private sector</em> (Law 25), the federal <em>Personal Information Protection and Electronic Documents Act</em> (PIPEDA), and Canada''s Anti-Spam Legislation (CASL).', 'NextBlock™ CMS ("we", "us", or "our") respects your privacy. We protect your personal information under Quebec''s Law 25, the federal PIPEDA act, and Canada''s Anti-Spam Legislation (CASL).')::jsonb,
912
- updated_at = now()
913
- WHERE page_id = 9
914
- AND content::text LIKE '%' || 'NextBlock™ CMS ("we", "us", or "our") re' || '%';
915
-
916
- UPDATE public.blocks
917
- SET content = replace(content::text, 'Our Privacy Officer is responsible for our compliance with applicable privacy laws. You may reach them at', 'Our Privacy Officer oversees our compliance with privacy laws. You can reach them at')::jsonb,
918
- updated_at = now()
919
- WHERE page_id = 9
920
- AND content::text LIKE '%' || 'Our Privacy Officer is responsible for o' || '%';
921
-
922
- UPDATE public.blocks
923
- SET content = replace(content::text, '<li><strong>Account information</strong> &mdash; name, email address, and credentials when you register.</li>', '<li><strong>Account information:</strong> Your name, email address, and login details when you register.</li>')::jsonb,
924
- updated_at = now()
925
- WHERE page_id = 9
926
- AND content::text LIKE '%' || '<li><strong>Account information</strong>' || '%';
927
-
928
- UPDATE public.blocks
929
- SET content = replace(content::text, '<li><strong>Usage and device data</strong> &mdash; collected only with your consent through analytics technologies.</li>', '<li><strong>Usage and device data:</strong> Collected only with your consent through analytics tools.</li>')::jsonb,
930
- updated_at = now()
931
- WHERE page_id = 9
932
- AND content::text LIKE '%' || '<li><strong>Usage and device data</stron' || '%';
933
-
934
- UPDATE public.blocks
935
- SET content = replace(content::text, '<li><strong>Communications</strong> &mdash; messages you send us and your marketing preferences.</li>', '<li><strong>Communications:</strong> Messages you send us and your newsletter choices.</li>')::jsonb,
936
- updated_at = now()
937
- WHERE page_id = 9
938
- AND content::text LIKE '%' || '<li><strong>Communications</strong> &mda' || '%';
939
-
940
- UPDATE public.blocks
941
- SET content = replace(content::text, '<h2>3. Why we collect it and your consent</h2>
942
- <p>We collect personal information for clearly identified purposes: to provide and secure our services, to communicate with you, and &mdash; only with your express, opt-in consent &mdash; for analytics and marketing. Consistent with Law 25, non-essential cookies and trackers remain disabled until you actively accept them, and you may withdraw your consent at any time.</p>', '<h2>3. Why we collect data and your consent</h2> <p>We collect personal information for clear reasons: to provide our services, keep accounts secure, and reply to your messages. We use analytics and marketing tools only with your direct, opt-in consent. Under Law 25, optional cookies stay off until you choose to accept them. You can withdraw your consent at any time.</p>')::jsonb,
943
- updated_at = now()
944
- WHERE page_id = 9
945
- AND content::text LIKE '%' || '<h2>3. Why we collect it and your consen' || '%';
946
-
947
- UPDATE public.blocks
948
- SET content = replace(content::text, 'Strictly necessary cookies keep the site working and require no consent. Analytics and marketing technologies are loaded <strong>only after</strong> you opt in through our consent banner. Your choice is recorded so we can honour it and demonstrate accountability.', 'Essential cookies keep the site running and require no consent. Analytics and marketing cookies load only after you opt in via our cookie banner. We record your choice to honor it and follow privacy rules.')::jsonb,
949
- updated_at = now()
950
- WHERE page_id = 9
951
- AND content::text LIKE '%' || 'Strictly necessary cookies keep the site' || '%';
952
-
953
- UPDATE public.blocks
954
- SET content = replace(content::text, 'We do not sell your personal information. We share it only with service providers who help us operate the platform under contractual confidentiality obligations, or where required by law.', 'We do not sell your personal data. We share it only with trusted service providers who help us run the platform under strict confidentiality agreements, or when required by law.')::jsonb,
955
- updated_at = now()
956
- WHERE page_id = 9
957
- AND content::text LIKE '%' || 'We do not sell your personal information' || '%';
958
-
959
- UPDATE public.blocks
960
- SET content = replace(content::text, '<h2>6. Retention</h2>
961
- <p>We keep personal information only for as long as necessary to fulfil the purposes described above or as required by law, after which it is securely destroyed or anonymized.</p>', '<h2>6. Data retention</h2> <p>We keep personal information only as long as needed for the purposes described above or as required by law. After that, we securely delete or anonymize your data.</p>')::jsonb,
962
- updated_at = now()
963
- WHERE page_id = 9
964
- AND content::text LIKE '%' || '<h2>6. Retention</h2>
965
- <p>We keep person' || '%';
966
-
967
- UPDATE public.blocks
968
- SET content = replace(content::text, 'Subject to applicable law, you have the right to access, rectify, and delete your personal information, to withdraw consent, to data portability, and to be informed about automated processing. To exercise these rights, contact our Privacy Officer at', 'Under privacy laws, you have the right to view, correct, and delete your personal information. You can also withdraw consent or ask for a portable copy of your data. To use these rights, write to our Privacy Officer at')::jsonb,
969
- updated_at = now()
970
- WHERE page_id = 9
971
- AND content::text LIKE '%' || 'Subject to applicable law, you have the ' || '%';
972
-
973
- UPDATE public.blocks
974
- SET content = replace(content::text, '<h2>8. Commercial electronic messages (CASL)</h2>
975
- <p>We send commercial electronic messages only with your consent. Every message identifies us and includes a working unsubscribe mechanism that we honour promptly.</p>', '<h2>8. Commercial electronic messages</h2> <p>We send commercial emails only with your permission. Every email clearly identifies us and includes an easy unsubscribe link that takes effect right away.</p>')::jsonb,
976
- updated_at = now()
977
- WHERE page_id = 9
978
- AND content::text LIKE '%' || '<h2>8. Commercial electronic messages (C' || '%';
979
-
980
- UPDATE public.blocks
981
- SET content = replace(content::text, '<h2>9. Safeguards</h2>
982
- <p>We use appropriate physical, organizational, and technological measures &mdash; including encryption in transit and access controls &mdash; to protect personal information against loss, theft, and unauthorized access.</p>', '<h2>9. Security safeguards</h2> <p>We use strong technical and physical protections to keep your data safe. These include encrypted connections and strict access controls to prevent loss, theft, and unauthorized access.</p>')::jsonb,
983
- updated_at = now()
984
- WHERE page_id = 9
985
- AND content::text LIKE '%' || '<h2>9. Safeguards</h2>
986
- <p>We use approp' || '%';
987
-
988
- UPDATE public.blocks
989
- SET content = replace(content::text, 'NextBlock™ CMS is free, open-source software distributed under the GNU Affero General Public License v3. When you self-host NextBlock, you are the operator responsible for the personal information processed by your own deployment, and this policy serves as a starting point you may adapt to your organization.', 'NextBlock™ CMS is free open-source software under the AGPLv3 license. When you self-host NextBlock, you control your own server. You are responsible for the personal data on your deployment, and this policy is a helpful model you can adapt.')::jsonb,
990
- updated_at = now()
991
- WHERE page_id = 9
992
- AND content::text LIKE '%' || 'NextBlock™ CMS is free, open-source soft' || '%';
993
-
994
- UPDATE public.blocks
995
- SET content = replace(content::text, '<h2>11. Changes to this policy</h2>
996
- <p>We may update this policy from time to time. Material changes will be communicated through the site, and the "last updated" date will be revised.</p>', '<h2>11. Policy changes</h2> <p>We may update this policy over time. We announce important changes on our site and update the revision date at the top.</p>')::jsonb,
997
- updated_at = now()
998
- WHERE page_id = 9
999
- AND content::text LIKE '%' || '<h2>11. Changes to this policy</h2>
1000
- <p>' || '%';
1001
-
1002
- UPDATE public.blocks
1003
- SET content = replace(content::text, 'Questions or complaints? Contact NextBlock™ CMS at <a href="mailto:{{privacy_email}}">{{privacy_email}}</a>. You may also contact the Commission d''accès à l''information du Québec or the Office of the Privacy Commissioner of Canada.', 'Have questions or complaints? Contact NextBlock™ at <a href="mailto:{{privacy_email}}">{{privacy_email}}</a>. You can also contact the Commission d''accès à l''information du Québec or the Office of the Privacy Commissioner of Canada.')::jsonb,
1004
- updated_at = now()
1005
- WHERE page_id = 9
1006
- AND content::text LIKE '%' || 'Questions or complaints? Contact NextBlo' || '%';
1007
-
1008
-
1009
- -- Page 10 Block Updates
1010
- UPDATE public.blocks
1011
- SET content = replace(content::text, 'NextBlock™ CMS (« nous ») respecte votre vie privée et s''engage à protéger vos renseignements personnels conformément à la <em>Loi sur la protection des renseignements personnels dans le secteur privé</em> du Québec (Loi 25), à la <em>Loi sur la protection des renseignements personnels et les documents électroniques</em> (LPRPDE) et à la Loi canadienne anti-pourriel (LCAP).', 'NextBlock™ CMS (« nous ») respecte votre vie privée. Nous protégeons vos renseignements personnels selon la Loi 25 du Québec, la loi fédérale LPRPDE et les règles canadiennes anti-pourriel (LCAP).')::jsonb,
1012
- updated_at = now()
1013
- WHERE page_id = 10
1014
- AND content::text LIKE '%' || 'NextBlock™ CMS (« nous ») respecte votre' || '%';
1015
-
1016
- UPDATE public.blocks
1017
- SET content = replace(content::text, 'Notre responsable de la protection des renseignements personnels veille au respect des lois applicables. Vous pouvez le joindre à', 'Notre responsable veille au respect des règles de confidentialité. Vous pouvez lui écrire à')::jsonb,
1018
- updated_at = now()
1019
- WHERE page_id = 10
1020
- AND content::text LIKE '%' || 'Notre responsable de la protection des r' || '%';
1021
-
1022
- UPDATE public.blocks
1023
- SET content = replace(content::text, '<h2>2. Renseignements que nous recueillons</h2>
1024
- <ul>
1025
- <li><strong>Renseignements de compte</strong> &mdash; nom, adresse courriel et identifiants lors de l''inscription.</li>
1026
- <li><strong>Données d''utilisation et d''appareil</strong> &mdash; recueillies uniquement avec votre consentement au moyen de technologies d''analyse.</li>
1027
- <li><strong>Communications</strong> &mdash; les messages que vous nous envoyez et vos préférences marketing.</li>
1028
- </ul>', '<h2>2. Renseignements recueillis</h2> <ul> <li><strong>Renseignements de compte :</strong> Votre nom, votre courriel et vos accès lors de l''inscription.</li> <li><strong>Données d''utilisation et d''appareil :</strong> Recueillies avec votre accord via nos outils de mesure.</li> <li><strong>Communications :</strong> Vos messages reçus et vos choix de suivi par courriel.</li> </ul>')::jsonb,
1029
- updated_at = now()
1030
- WHERE page_id = 10
1031
- AND content::text LIKE '%' || '<h2>2. Renseignements que nous recueillo' || '%';
1032
-
1033
- UPDATE public.blocks
1034
- SET content = replace(content::text, '<p>Nous recueillons des renseignements personnels à des fins clairement déterminées : fournir et sécuriser nos services, communiquer avec vous et &mdash; uniquement avec votre consentement exprès &mdash; à des fins d''analyse et de marketing. Conformément à la Loi 25, les témoins et traceurs non essentiels demeurent désactivés tant que vous ne les avez pas acceptés, et vous pouvez retirer votre consentement en tout temps.</p>', '<p>Nous recueillons vos données pour des motifs clairs : faire fonctionner nos services, sécuriser les accès et vous répondre. Les outils d''analyse et de suivi ne s''activent qu''avec votre accord clair. Selon la Loi 25, les témoins optionnels restent coupés tant que vous ne les acceptez pas. Vous pouvez retirer votre accord en tout temps.</p>')::jsonb,
1035
- updated_at = now()
1036
- WHERE page_id = 10
1037
- AND content::text LIKE '%' || '<p>Nous recueillons des renseignements p' || '%';
1038
-
1039
- UPDATE public.blocks
1040
- SET content = replace(content::text, 'Les témoins strictement nécessaires assurent le fonctionnement du site et ne requièrent aucun consentement. Les technologies d''analyse et de marketing ne sont chargées qu''<strong>après</strong> votre consentement explicite. Votre choix est enregistré afin de le respecter.', 'Les témoins essentiels assurent le bon fonctionnement du site. Ils ne demandent aucun accord préalable. Les témoins d''analyse se chargent seulement après votre choix sur notre bandeau. Nous gardons votre choix en mémoire pour le respecter.')::jsonb,
1041
- updated_at = now()
1042
- WHERE page_id = 10
1043
- AND content::text LIKE '%' || 'Les témoins strictement nécessaires assu' || '%';
1044
-
1045
- UPDATE public.blocks
1046
- SET content = replace(content::text, '<h2>5. Communication à des tiers</h2>
1047
- <p>Nous ne vendons pas vos renseignements personnels. Nous ne les communiquons qu''à des fournisseurs qui nous aident à exploiter la plateforme, sous obligation de confidentialité, ou lorsque la loi l''exige.</p>', '<h2>5. Partage et communication</h2> <p>Nous ne vendons jamais vos données personnelles. Nous les partageons uniquement avec des prestataires de confiance qui nous aident à faire tourner le site sous contrat de secret, ou si la loi l''impose.</p>')::jsonb,
1048
- updated_at = now()
1049
- WHERE page_id = 10
1050
- AND content::text LIKE '%' || '<h2>5. Communication à des tiers</h2>
1051
- <' || '%';
1052
-
1053
- UPDATE public.blocks
1054
- SET content = replace(content::text, '<h2>6. Conservation</h2>
1055
- <p>Nous ne conservons les renseignements personnels que le temps nécessaire aux fins décrites ou exigé par la loi, après quoi ils sont détruits ou anonymisés de façon sécuritaire.</p>', '<h2>6. Durée de conservation</h2> <p>Nous gardons vos données seulement le temps utile pour les buts décrits ou selon la loi. Ensuite, nous les effaçons ou nous les rendons anonymes de façon sûre.</p>')::jsonb,
1056
- updated_at = now()
1057
- WHERE page_id = 10
1058
- AND content::text LIKE '%' || '<h2>6. Conservation</h2>
1059
- <p>Nous ne con' || '%';
1060
-
1061
- UPDATE public.blocks
1062
- SET content = replace(content::text, 'Sous réserve de la loi applicable, vous avez le droit d''accéder à vos renseignements, de les rectifier et de les supprimer, de retirer votre consentement, à la portabilité de vos données et d''être informé du traitement automatisé. Pour exercer ces droits, écrivez à', 'Vous avez le droit de lire, de corriger et de faire effacer vos données. Vous pouvez aussi retirer votre accord ou demander une copie de vos données. Pour exercer vos droits, écrivez à notre responsable à')::jsonb,
1063
- updated_at = now()
1064
- WHERE page_id = 10
1065
- AND content::text LIKE '%' || 'Sous réserve de la loi applicable, vous ' || '%';
1066
-
1067
- UPDATE public.blocks
1068
- SET content = replace(content::text, '<h2>8. Messages électroniques commerciaux (LCAP)</h2>
1069
- <p>Nous n''envoyons des messages électroniques commerciaux qu''avec votre consentement. Chaque message nous identifie et comporte un mécanisme de désabonnement fonctionnel que nous respectons rapidement.</p>', '<h2>8. Messages électroniques</h2> <p>Nous envoyons des courriels informatifs seulement avec votre accord. Chaque courriel montre notre nom et propose un lien simple pour vous désabonner d''un clic.</p>')::jsonb,
1070
- updated_at = now()
1071
- WHERE page_id = 10
1072
- AND content::text LIKE '%' || '<h2>8. Messages électroniques commerciau' || '%';
1073
-
1074
- UPDATE public.blocks
1075
- SET content = replace(content::text, '<h2>9. Mesures de sécurité</h2>
1076
- <p>Nous employons des mesures physiques, organisationnelles et technologiques appropriées &mdash; dont le chiffrement en transit et le contrôle des accès &mdash; pour protéger vos renseignements.</p>', '<h2>9. Mesures de sécurité</h2> <p>Nous utilisons des moyens techniques et physiques solides pour garder vos données en sûreté. Cela comprend des échanges chiffrés et un contrôle strict des accès contre toute fuite ou vol.</p>')::jsonb,
1077
- updated_at = now()
1078
- WHERE page_id = 10
1079
- AND content::text LIKE '%' || '<h2>9. Mesures de sécurité</h2>
1080
- <p>Nous' || '%';
1081
-
1082
- UPDATE public.blocks
1083
- SET content = replace(content::text, 'NextBlock™ CMS est un logiciel libre et à code source ouvert distribué sous la licence publique générale GNU Affero v3. Lorsque vous hébergez NextBlock vous-même, vous êtes l''exploitant responsable des renseignements personnels traités par votre propre instance, et la présente politique vous sert de point de départ adaptable à votre organisation.', 'NextBlock™ CMS est un logiciel libre sous licence AGPLv3. Si vous hébergez NextBlock vous-même, vous gérez votre propre serveur. Vous êtes responsable des données sur votre instance, et ce texte est un modèle que vous pouvez adapter.')::jsonb,
1084
- updated_at = now()
1085
- WHERE page_id = 10
1086
- AND content::text LIKE '%' || 'NextBlock™ CMS est un logiciel libre et ' || '%';
1087
-
1088
- UPDATE public.blocks
1089
- SET content = replace(content::text, '<h2>11. Modifications</h2>
1090
- <p>Nous pouvons mettre à jour cette politique. Les changements importants seront communiqués sur le site et la date de mise à jour sera révisée.</p>', '<h2>11. Mises à jour</h2> <p>Nous pouvons mettre à jour ce texte au fil du temps. Les changements notables seront affichés sur le site avec la nouvelle date en tête de page.</p>')::jsonb,
1091
- updated_at = now()
1092
- WHERE page_id = 10
1093
- AND content::text LIKE '%' || '<h2>11. Modifications</h2>
1094
- <p>Nous pouv' || '%';
1095
-
1096
- UPDATE public.blocks
1097
- SET content = replace(content::text, 'Des questions ou des plaintes ? Contactez NextBlock™ CMS à <a href="mailto:{{privacy_email}}">{{privacy_email}}</a>. Vous pouvez aussi vous adresser à la Commission d''accès à l''information du Québec.', 'Une question ou un avis ? Écrivez à NextBlock™ à <a href="mailto:{{privacy_email}}">{{privacy_email}}</a>. Vous pouvez aussi joindre la Commission d''accès à l''information du Québec.')::jsonb,
1098
- updated_at = now()
1099
- WHERE page_id = 10
1100
- AND content::text LIKE '%' || 'Des questions ou des plaintes ? Contacte' || '%';
1101
-
1102
-
1103
- -- Page 12 Block Updates
1104
- UPDATE public.blocks
1105
- SET content = replace(content::text, 'En accédant à NextBlock™ CMS et aux services que nous fournissons (les « Services ») ou en les utilisant, vous acceptez d''être lié par les présentes conditions d''utilisation. Si vous n''êtes pas d''accord, n''utilisez pas les Services.', 'En utilisant le CMS NextBlock™ et les services associés (les « Services »), vous acceptez ces conditions d''utilisation. Si vous refusez ces règles, veuillez ne pas utiliser les Services.')::jsonb,
1106
- updated_at = now()
1107
- WHERE page_id = 12
1108
- AND content::text LIKE '%' || 'En accédant à NextBlock™ CMS et aux serv' || '%';
1109
-
1110
- UPDATE public.blocks
1111
- SET content = replace(content::text, '<h2>2. Logiciel libre et à code source ouvert</h2>
1112
- <p>NextBlock™ CMS est un logiciel libre et à code source ouvert distribué sous la <strong>licence publique générale GNU Affero, version 3 (AGPL-3.0)</strong> ou, à votre choix, toute version ultérieure. Vous êtes libre d''exécuter, d''étudier, de partager et de modifier le logiciel selon les termes de cette licence. Une copie de la licence est fournie avec le logiciel et est aussi disponible à <a href="https://www.gnu.org/licenses/agpl-3.0.html">gnu.org/licenses/agpl-3.0.html</a>.</p>', '<h2>2. Logiciel libre et code source ouvert</h2> <p>NextBlock™ CMS est un logiciel libre sous <strong>licence publique générale GNU Affero, version 3 (AGPL-3.0)</strong> ou toute version ultérieure. Vous pouvez lancer, étudier, copier et faire évoluer le code selon cette licence. Le texte complet se trouve avec le code et en ligne sur <a href="https://www.gnu.org/licenses/agpl-3.0.html">gnu.org/licenses/agpl-3.0.html</a>.</p>')::jsonb,
1113
- updated_at = now()
1114
- WHERE page_id = 12
1115
- AND content::text LIKE '%' || '<h2>2. Logiciel libre et à code source o' || '%';
1116
-
1117
- UPDATE public.blocks
1118
- SET content = replace(content::text, '<h2>3. Disponibilité du code source</h2>
1119
- <p>Conformément à l''article 13 de l''AGPL-3.0, si vous exploitez une version modifiée de NextBlock™ CMS et la rendez accessible à des utilisateurs sur un réseau, vous devez offrir clairement à ces utilisateurs l''accès au code source correspondant de votre version modifiée, gratuitement, par un moyen usuel de copie de logiciels.</p>', '<h2>3. Partage du code source</h2> <p>Selon l''article 13 de la licence AGPL-3.0, si vous modifiez NextBlock™ CMS et le mettez en ligne pour des usagers sur un réseau, vous devez offrir l''accès libre et sans frais au code source de votre version modifiée.</p>')::jsonb,
1120
- updated_at = now()
1121
- WHERE page_id = 12
1122
- AND content::text LIKE '%' || '<h2>3. Disponibilité du code source</h2>' || '%';
1123
-
1124
- UPDATE public.blocks
1125
- SET content = replace(content::text, '<h2>4. Marques de commerce</h2>
1126
- <p>L''AGPL-3.0 accorde de larges droits sur le code source du logiciel, mais <strong>n''accorde aucun droit</strong> sur nos noms commerciaux, marques de commerce ou marques de service. « NextBlock™ », le nom NextBlock™ CMS et les logos associés demeurent notre propriété et ne peuvent être utilisés d''une manière laissant entendre une approbation ou une affiliation sans notre autorisation écrite préalable.</p>', '<h2>4. Marques et logos</h2> <p>La licence AGPL-3.0 donne de larges droits sur le code. Mais <strong>elle ne donne aucun droit</strong> sur nos noms et marques. Les termes « NextBlock™ », NextBlock™ CMS et les logos restent notre bien exclusif. Ils ne peuvent être repris sans accord écrit préalable.</p>')::jsonb,
1127
- updated_at = now()
1128
- WHERE page_id = 12
1129
- AND content::text LIKE '%' || '<h2>4. Marques de commerce</h2>
1130
- <p>L''AG' || '%';
1131
-
1132
- UPDATE public.blocks
1133
- SET content = replace(content::text, '<h2>5. Comptes et utilisation acceptable</h2>
1134
- <p>Si vous créez un compte, vous êtes responsable de la protection de vos identifiants et de toute activité effectuée à partir de votre compte, et vous vous engagez à nous aviser rapidement de toute utilisation non autorisée. Vous vous engagez à ne pas détourner les Services, notamment en tentant de les perturber, d''y accéder sans autorisation ou de les utiliser à des fins illégales.</p>', '<h2>5. Comptes et bon usage</h2> <p>Si vous ouvrez un compte, vous gardez la garde de vos accès et de toute action faite sous votre nom. Vous devez nous prévenir vite en cas d''usage non permis. Vous vous engagez à ne pas bloquer les Services, ne pas forcer les accès et ne pas agir contre la loi.</p>')::jsonb,
1135
- updated_at = now()
1136
- WHERE page_id = 12
1137
- AND content::text LIKE '%' || '<h2>5. Comptes et utilisation acceptable' || '%';
1138
-
1139
- UPDATE public.blocks
1140
- SET content = replace(content::text, 'Comme l''énonce l''article 15 de l''AGPL-3.0, le logiciel est fourni « tel quel », sans garantie d''aucune sorte, expresse ou implicite, y compris, sans s''y limiter, les garanties implicites de qualité marchande et d''adéquation à un usage particulier. Vous assumez l''entièreté du risque quant à la qualité et au rendement du logiciel.', 'Selon l''article 15 de l''AGPL-3.0, le logiciel est fourni « tel quel », sans garantie d''aucune sorte, expresse ou tacite. Cela inclut les garanties de vente ou d''usage pour un besoin précis. Vous prenez sur vous les risques liés au bon emploi du logiciel.')::jsonb,
1141
- updated_at = now()
1142
- WHERE page_id = 12
1143
- AND content::text LIKE '%' || 'Comme l''énonce l''article 15 de l''AGPL-3.' || '%';
1144
-
1145
- UPDATE public.blocks
1146
- SET content = replace(content::text, '<h2>7. Limitation de responsabilité</h2>
1147
- <p>Comme l''énonce l''article 16 de l''AGPL-3.0, et dans toute la mesure permise par la loi applicable, en aucun cas un titulaire de droits d''auteur ou toute autre partie qui modifie ou transmet le logiciel ne saurait être tenu responsable envers vous de dommages, y compris tout dommage général, spécial, accessoire ou consécutif découlant de l''utilisation ou de l''impossibilité d''utiliser le logiciel.</p>', '<h2>7. Limite de responsabilité</h2> <p>Selon l''article 16 de l''AGPL-3.0 et dans la limite permise par la loi, aucun auteur ou tiers modifiant le code ne peut être tenu pour responsable de vos pertes ou dommages liés à l''usage du logiciel.</p>')::jsonb,
1148
- updated_at = now()
1149
- WHERE page_id = 12
1150
- AND content::text LIKE '%' || '<h2>7. Limitation de responsabilité</h2>' || '%';
1151
-
1152
- UPDATE public.blocks
1153
- SET content = replace(content::text, 'Les présentes conditions sont régies par les lois de la province de Québec et les lois fédérales du Canada qui y sont applicables, sans égard aux règles de conflit de lois. Rien dans les présentes conditions ne limite les droits impératifs de protection du consommateur dont vous pourriez bénéficier en vertu de ces lois.', 'Ces conditions suivent les lois de la province de Québec et les lois du Canada applicables. Rien ici ne réduit vos droits stricts de consommateur selon ces lois.')::jsonb,
1154
- updated_at = now()
1155
- WHERE page_id = 12
1156
- AND content::text LIKE '%' || 'Les présentes conditions sont régies par' || '%';
1157
-
1158
- UPDATE public.blocks
1159
- SET content = replace(content::text, '<h2>9. Modifications</h2>
1160
- <p>Nous pouvons réviser ces conditions de temps à autre. Les changements importants seront communiqués au moyen des Services, et l''utilisation continue des Services après leur entrée en vigueur vaut acceptation.</p>', '<h2>9. Mises à jour</h2> <p>Nous pouvons adapter ces règles au fil du temps. Les changements notables passeront sur le site. Votre usage continu vaut accord avec les nouvelles règles.</p>')::jsonb,
1161
- updated_at = now()
1162
- WHERE page_id = 12
1163
- AND content::text LIKE '%' || '<h2>9. Modifications</h2>
1164
- <p>Nous pouvo' || '%';
1165
-
1166
- UPDATE public.blocks
1167
- SET content = replace(content::text, 'Des questions sur ces conditions ? Contactez NextBlock™ CMS à <a href="mailto:{{privacy_email}}">{{privacy_email}}</a>.', 'Une question sur ces conditions ? Écrivez à NextBlock™ CMS à <a href="mailto:{{privacy_email}}">{{privacy_email}}</a>.')::jsonb,
1168
- updated_at = now()
1169
- WHERE page_id = 12
1170
- AND content::text LIKE '%' || 'Des questions sur ces conditions ? Conta' || '%';
1171
-
1172
- END $$;