@nextsparkjs/core 0.1.0-beta.134 → 0.1.0-beta.136

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.
@@ -2,12 +2,11 @@
2
2
  * PageRenderer Component
3
3
  *
4
4
  * Renders pages from the Page Builder by iterating over blocks
5
- * and loading block components from the SSR registry.
5
+ * and directly loading block components from the SSR registry.
6
6
  *
7
- * Block components are loaded via next/dynamic (ssr: true) for per-block
8
- * code splitting. Each block gets its own JS chunk only blocks used on
9
- * the page have their JS loaded by the browser. SSR renders full HTML
10
- * so content is visible without client JS (SEO-safe).
7
+ * Uses direct imports (BLOCK_COMPONENTS_SSR) for synchronous hydration.
8
+ * This ensures zero CLS HTML is fully visible and stable without
9
+ * waiting for async chunk resolution on the client.
11
10
  *
12
11
  * @module core/components/public/pageBuilder
13
12
  */
@@ -1 +1 @@
1
- {"version":3,"file":"PageRenderer.d.ts","sourceRoot":"","sources":["../../../../src/components/public/pageBuilder/PageRenderer.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAsC1D,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE;QACJ,EAAE,EAAE,MAAM,CAAA;QACV,KAAK,EAAE,MAAM,CAAA;QACb,IAAI,EAAE,MAAM,CAAA;QACZ,MAAM,EAAE,aAAa,EAAE,CAAA;QACvB,MAAM,EAAE,MAAM,CAAA;KACf,CAAA;CACF;AAED,wBAAgB,YAAY,CAAC,EAAE,IAAI,EAAE,EAAE,iBAAiB,2CA+BvD"}
1
+ {"version":3,"file":"PageRenderer.d.ts","sourceRoot":"","sources":["../../../../src/components/public/pageBuilder/PageRenderer.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAiC1D,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE;QACJ,EAAE,EAAE,MAAM,CAAA;QACV,KAAK,EAAE,MAAM,CAAA;QACb,IAAI,EAAE,MAAM,CAAA;QACZ,MAAM,EAAE,aAAa,EAAE,CAAA;QACvB,MAAM,EAAE,MAAM,CAAA;KACf,CAAA;CACF;AAED,wBAAgB,YAAY,CAAC,EAAE,IAAI,EAAE,EAAE,iBAAiB,2CA+BvD"}
@@ -1,5 +1,4 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
- import { Suspense } from "react";
3
2
  import { getBlockComponentSSR, normalizeBlockProps } from "../../../lib/blocks/loader.js";
4
3
  function BlockError({ blockSlug }) {
5
4
  return /* @__PURE__ */ jsx("div", { className: "w-full py-12 px-4 bg-destructive/10 border border-destructive/20 rounded", children: /* @__PURE__ */ jsxs("div", { className: "max-w-7xl mx-auto text-center", children: [
@@ -17,7 +16,7 @@ function BlockRenderer({ block }) {
17
16
  return /* @__PURE__ */ jsx(BlockError, { blockSlug: block.blockSlug });
18
17
  }
19
18
  const normalizedProps = normalizeBlockProps(block.props);
20
- return /* @__PURE__ */ jsx(Suspense, { children: /* @__PURE__ */ jsx(BlockComponent, { ...normalizedProps }) });
19
+ return /* @__PURE__ */ jsx(BlockComponent, { ...normalizedProps });
21
20
  }
22
21
  function PageRenderer({ page }) {
23
22
  const blocks = Array.isArray(page.blocks) ? page.blocks : [];
@@ -1,5 +1,5 @@
1
1
  {
2
- "generated": "2026-04-07T15:29:52.891Z",
2
+ "generated": "2026-04-07T17:31:21.161Z",
3
3
  "totalClasses": 1078,
4
4
  "classes": [
5
5
  "!text-2xl",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextsparkjs/core",
3
- "version": "0.1.0-beta.134",
3
+ "version": "0.1.0-beta.136",
4
4
  "description": "NextSpark - The complete SaaS framework for Next.js",
5
5
  "license": "MIT",
6
6
  "author": "NextSpark <hello@nextspark.dev>",
@@ -462,7 +462,7 @@
462
462
  "tailwind-merge": "^3.3.1",
463
463
  "uuid": "^13.0.0",
464
464
  "zod": "^4.1.5",
465
- "@nextsparkjs/testing": "0.1.0-beta.134"
465
+ "@nextsparkjs/testing": "0.1.0-beta.136"
466
466
  },
467
467
  "scripts": {
468
468
  "postinstall": "node scripts/postinstall.mjs || true",
@@ -47,10 +47,6 @@ export const BLOCK_CATEGORIES: string[] = []
47
47
 
48
48
  export const BLOCK_COMPONENTS: Record<string, React.LazyExoticComponent<React.ComponentType<unknown>>> = {}
49
49
 
50
- /**
51
- * Direct-imported block components for SSR rendering
52
- * No React.lazy, no Suspense — HTML is fully visible without JS
53
- */
54
50
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
55
51
  export const BLOCK_COMPONENTS_SSR: Record<string, React.ComponentType<any>> = {}
56
52
 
@@ -64,22 +60,23 @@ export const BLOCK_METADATA = {
64
60
  `
65
61
  }
66
62
 
67
- // Import field definitions and examples (if they exist)
63
+ // Import field definitions, examples, and components
68
64
  const imports = []
65
+ const ssrImports = []
69
66
 
70
67
  blocks.forEach(block => {
71
68
  const slugVar = block.slug.replace(/-/g, '_')
72
69
 
73
- // Always import field definitions
74
70
  imports.push(`import { fieldDefinitions as ${slugVar}_fields } from '${block.paths.fields}'`)
71
+ ssrImports.push(`import { default as ${slugVar}_component } from '${block.paths.component}'`)
75
72
 
76
- // Conditionally import examples if they exist
77
73
  if (block.hasExamples) {
78
74
  imports.push(`import { examples as ${slugVar}_examples } from '${block.paths.examples}'`)
79
75
  }
80
76
  })
81
77
 
82
78
  const fieldImports = imports.join('\n')
79
+ const ssrComponentImports = ssrImports.join('\n')
83
80
 
84
81
  const registryEntries = blocks.map(block => {
85
82
  const slugVar = block.slug.replace(/-/g, '_')
@@ -127,11 +124,13 @@ export const BLOCK_METADATA = {
127
124
  */
128
125
 
129
126
  import React from 'react'
130
- import dynamic from 'next/dynamic'
131
127
  import type { BlockConfig, BlockCategory } from '${convertCorePath('@/core/types', outputFilePath, config)}'
132
128
 
133
129
  ${fieldImports}
134
130
 
131
+ // Direct component imports for SSR — zero CLS, synchronous hydration
132
+ ${ssrComponentImports}
133
+
135
134
  export const BLOCK_REGISTRY: Record<string, BlockConfig> = {
136
135
  ${registryEntries}
137
136
  }
@@ -139,9 +138,8 @@ ${registryEntries}
139
138
  export const BLOCK_CATEGORIES: BlockCategory[] = [${categories.map(c => `'${c}'`).join(', ')}]
140
139
 
141
140
  /**
142
- * Lazy-loaded block components for runtime rendering
143
- * Each component is wrapped with React.lazy for code-splitting
144
- * Uses Object.values to get the first exported component (handles varying naming conventions)
141
+ * Lazy-loaded block components for client-side rendering (admin UI, block picker).
142
+ * Each component is wrapped with React.lazy for code-splitting.
145
143
  */
146
144
  export const BLOCK_COMPONENTS: Record<string, React.LazyExoticComponent<React.ComponentType<any>>> = {
147
145
  ${blocks.map(block => {
@@ -150,14 +148,15 @@ ${blocks.map(block => {
150
148
  }
151
149
 
152
150
  /**
153
- * Code-split block components for SSR rendering via next/dynamic.
154
- * Each block is a separate JS chunk only blocks used on the page are loaded.
155
- * SSR is enabled (default) so HTML is fully visible without client JS.
151
+ * Direct-imported block components for SSR rendering.
152
+ * Static imports ensure synchronous hydrationzero CLS.
153
+ * HTML is fully visible without client JS (SEO-safe, no-JS compatible).
156
154
  */
157
155
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
158
156
  export const BLOCK_COMPONENTS_SSR: Record<string, React.ComponentType<any>> = {
159
157
  ${blocks.map(block => {
160
- return ` '${block.slug}': dynamic(() => import('${block.paths.component}'), { ssr: true })`
158
+ const slugVar = block.slug.replace(/-/g, '_')
159
+ return ` '${block.slug}': ${slugVar}_component`
161
160
  }).join(',\n')}
162
161
  }
163
162