@nextsparkjs/core 0.1.0-beta.132 → 0.1.0-beta.133

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,7 +2,12 @@
2
2
  * PageRenderer Component
3
3
  *
4
4
  * Renders pages from the Page Builder by iterating over blocks
5
- * and dynamically loading block components from the registry.
5
+ * and directly loading block components from the SSR registry.
6
+ *
7
+ * Uses direct imports (BLOCK_COMPONENTS_SSR) instead of React.lazy
8
+ * so that all HTML is visible in the initial server response without JS.
9
+ * React.lazy puts content inside hidden <template> tags that require
10
+ * client-side JS to reveal — breaking no-JS rendering and hurting SEO.
6
11
  *
7
12
  * @module core/components/public/pageBuilder
8
13
  */
@@ -1 +1 @@
1
- {"version":3,"file":"PageRenderer.d.ts","sourceRoot":"","sources":["../../../../src/components/public/pageBuilder/PageRenderer.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAmD1D,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;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAkC1D,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,13 +1,5 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
- import { Suspense } from "react";
3
- import { getBlockComponent, normalizeBlockProps } from "../../../lib/blocks/loader.js";
4
- function BlockSkeleton() {
5
- return /* @__PURE__ */ jsx("div", { className: "w-full py-12 px-4 animate-pulse", children: /* @__PURE__ */ jsxs("div", { className: "max-w-7xl mx-auto", children: [
6
- /* @__PURE__ */ jsx("div", { className: "h-8 bg-muted rounded w-3/4 mb-4" }),
7
- /* @__PURE__ */ jsx("div", { className: "h-4 bg-muted rounded w-full mb-2" }),
8
- /* @__PURE__ */ jsx("div", { className: "h-4 bg-muted rounded w-5/6" })
9
- ] }) });
10
- }
2
+ import { getBlockComponentSSR, normalizeBlockProps } from "../../../lib/blocks/loader.js";
11
3
  function BlockError({ blockSlug }) {
12
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: [
13
5
  /* @__PURE__ */ jsxs("p", { className: "text-destructive", children: [
@@ -18,13 +10,13 @@ function BlockError({ blockSlug }) {
18
10
  ] }) });
19
11
  }
20
12
  function BlockRenderer({ block }) {
21
- const BlockComponent = getBlockComponent(block.blockSlug);
13
+ const BlockComponent = getBlockComponentSSR(block.blockSlug);
22
14
  if (!BlockComponent) {
23
15
  console.warn(`Block component not found for slug: ${block.blockSlug}`);
24
16
  return /* @__PURE__ */ jsx(BlockError, { blockSlug: block.blockSlug });
25
17
  }
26
18
  const normalizedProps = normalizeBlockProps(block.props);
27
- return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(BlockSkeleton, {}), children: /* @__PURE__ */ jsx(BlockComponent, { ...normalizedProps }) });
19
+ return /* @__PURE__ */ jsx(BlockComponent, { ...normalizedProps });
28
20
  }
29
21
  function PageRenderer({ page }) {
30
22
  const blocks = Array.isArray(page.blocks) ? page.blocks : [];
@@ -22,6 +22,15 @@ export declare function getBlockComponents(): Record<string, BlockComponent>;
22
22
  * @returns The block component or undefined if not found
23
23
  */
24
24
  export declare function getBlockComponent(slug: string): BlockComponent | undefined;
25
+ /**
26
+ * Get all SSR block components (direct imports, no React.lazy)
27
+ * Use for public page rendering where no-JS SSR is required
28
+ */
29
+ export declare function getBlockComponentsSSR(): Record<string, BlockComponent>;
30
+ /**
31
+ * Get a specific SSR block component by slug (direct import, no React.lazy)
32
+ */
33
+ export declare function getBlockComponentSSR(slug: string): BlockComponent | undefined;
25
34
  /**
26
35
  * Check if a block exists in the registry
27
36
  *
@@ -1 +1 @@
1
- {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/lib/blocks/loader.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAIrC,KAAK,cAAc,GAAG,aAAa,CAAC,GAAG,CAAC,CAAA;AAExC;;;;;GAKG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAEnE;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAE1E;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE9C;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAgD3F"}
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/lib/blocks/loader.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAIrC,KAAK,cAAc,GAAG,aAAa,CAAC,GAAG,CAAC,CAAA;AAExC;;;;;GAKG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAEnE;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAE1E;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAEtE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAE7E;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE9C;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAgD3F"}
@@ -1,10 +1,16 @@
1
- import { BLOCK_COMPONENTS } from "@nextsparkjs/registries/block-registry";
1
+ import { BLOCK_COMPONENTS, BLOCK_COMPONENTS_SSR } from "@nextsparkjs/registries/block-registry";
2
2
  function getBlockComponents() {
3
3
  return BLOCK_COMPONENTS;
4
4
  }
5
5
  function getBlockComponent(slug) {
6
6
  return BLOCK_COMPONENTS[slug];
7
7
  }
8
+ function getBlockComponentsSSR() {
9
+ return BLOCK_COMPONENTS_SSR;
10
+ }
11
+ function getBlockComponentSSR(slug) {
12
+ return BLOCK_COMPONENTS_SSR[slug];
13
+ }
8
14
  function hasBlock(slug) {
9
15
  return slug in BLOCK_COMPONENTS;
10
16
  }
@@ -48,7 +54,9 @@ function normalizeBlockProps(props) {
48
54
  }
49
55
  export {
50
56
  getBlockComponent,
57
+ getBlockComponentSSR,
51
58
  getBlockComponents,
59
+ getBlockComponentsSSR,
52
60
  hasBlock,
53
61
  normalizeBlockProps
54
62
  };
@@ -1,5 +1,5 @@
1
1
  {
2
- "generated": "2026-04-01T20:21:39.786Z",
2
+ "generated": "2026-04-06T20:21:52.643Z",
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.132",
3
+ "version": "0.1.0-beta.133",
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.132"
465
+ "@nextsparkjs/testing": "0.1.0-beta.133"
466
466
  },
467
467
  "scripts": {
468
468
  "postinstall": "node scripts/postinstall.mjs || true",
@@ -47,6 +47,13 @@ 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
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
55
+ export const BLOCK_COMPONENTS_SSR: Record<string, React.ComponentType<any>> = {}
56
+
50
57
  export const BLOCK_METADATA = {
51
58
  totalBlocks: 0,
52
59
  categories: [],
@@ -59,6 +66,8 @@ export const BLOCK_METADATA = {
59
66
 
60
67
  // Import field definitions and examples (if they exist)
61
68
  const imports = []
69
+ // Direct component imports for SSR (no React.lazy)
70
+ const ssrImports = []
62
71
 
63
72
  blocks.forEach(block => {
64
73
  const slugVar = block.slug.replace(/-/g, '_')
@@ -66,6 +75,9 @@ export const BLOCK_METADATA = {
66
75
  // Always import field definitions
67
76
  imports.push(`import { fieldDefinitions as ${slugVar}_fields } from '${block.paths.fields}'`)
68
77
 
78
+ // Direct component import for SSR rendering
79
+ ssrImports.push(`import { default as ${slugVar}_component } from '${block.paths.component}'`)
80
+
69
81
  // Conditionally import examples if they exist
70
82
  if (block.hasExamples) {
71
83
  imports.push(`import { examples as ${slugVar}_examples } from '${block.paths.examples}'`)
@@ -73,6 +85,7 @@ export const BLOCK_METADATA = {
73
85
  })
74
86
 
75
87
  const fieldImports = imports.join('\n')
88
+ const ssrComponentImports = ssrImports.join('\n')
76
89
 
77
90
  const registryEntries = blocks.map(block => {
78
91
  const slugVar = block.slug.replace(/-/g, '_')
@@ -124,6 +137,9 @@ import type { BlockConfig, BlockCategory } from '${convertCorePath('@/core/types
124
137
 
125
138
  ${fieldImports}
126
139
 
140
+ // Direct component imports for SSR (no React.lazy, no Suspense needed)
141
+ ${ssrComponentImports}
142
+
127
143
  export const BLOCK_REGISTRY: Record<string, BlockConfig> = {
128
144
  ${registryEntries}
129
145
  }
@@ -141,6 +157,19 @@ ${blocks.map(block => {
141
157
  }).join(',\n')}
142
158
  }
143
159
 
160
+ /**
161
+ * Direct-imported block components for SSR rendering
162
+ * No React.lazy, no Suspense — HTML is fully visible without JS.
163
+ * Use with SSRPageRenderer for public pages where SEO and no-JS rendering matter.
164
+ */
165
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
166
+ export const BLOCK_COMPONENTS_SSR: Record<string, React.ComponentType<any>> = {
167
+ ${blocks.map(block => {
168
+ const slugVar = block.slug.replace(/-/g, '_')
169
+ return ` '${block.slug}': ${slugVar}_component`
170
+ }).join(',\n')}
171
+ }
172
+
144
173
  /**
145
174
  * Block registry metadata
146
175
  */
@@ -133,7 +133,7 @@ export interface PluginRegistryEntry {
133
133
  hasAssets: boolean
134
134
  }
135
135
 
136
- export const PLUGIN_REGISTRY = {
136
+ export const PLUGIN_REGISTRY: Record<string, PluginRegistryEntry> = {
137
137
  ${registryEntries}
138
138
  }
139
139
 
@@ -6,6 +6,8 @@ export const BLOCK_REGISTRY: Record<string, any> = {}
6
6
 
7
7
  export const BLOCK_COMPONENTS: Record<string, any> = {}
8
8
 
9
+ export const BLOCK_COMPONENTS_SSR: Record<string, any> = {}
10
+
9
11
  export const BLOCK_METADATA = {
10
12
  generated: new Date().toISOString(),
11
13
  totalBlocks: 0,