@mvtlab/nextjs-orchestrator 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
  [![npm downloads](https://img.shields.io/npm/dm/@mvtlab/nextjs-orchestrator.svg)](https://www.npmjs.com/package/@mvtlab/nextjs-orchestrator)
5
5
  [![License](https://img.shields.io/npm/l/@mvtlab/nextjs-orchestrator.svg)](LICENSE)
6
6
 
7
- React component for integrating MVTLab.io CDN engine into Next.js applications with optional anti-flicker support.
7
+ React SDK for integrating the MVTLab.io CDN engine into Next.js applications with anti-flicker support.
8
8
 
9
9
  ---
10
10
 
@@ -22,35 +22,34 @@ yarn add @mvtlab/nextjs-orchestrator
22
22
 
23
23
  ## Quick Start
24
24
 
25
- Wrap your app at the root level. The component must be in a client component file (`'use client';`).
25
+ ### Recommended App Router (SSR-safe, no flicker)
26
26
 
27
- ### App Router
27
+ Use `MVTScripts` in your root `layout.tsx`. It is a **Server Component** — no `'use client'`
28
+ needed — so the anti-flicker style and engine script are injected into the server-rendered
29
+ HTML and execute before React hydration, preventing any content flash.
28
30
 
29
31
  ```tsx
30
32
  // app/layout.tsx
31
- 'use client';
32
-
33
- import { MVTOrchestrator } from '@mvtlab/nextjs-orchestrator';
33
+ import { MVTScripts } from '@mvtlab/nextjs-orchestrator';
34
34
 
35
35
  export default function RootLayout({ children }) {
36
36
  return (
37
37
  <html lang="en">
38
38
  <body>
39
- <MVTOrchestrator orchestratorKey="YOUR_PROJECT_KEY">
40
- {children}
41
- </MVTOrchestrator>
39
+ <MVTScripts orchestratorKey="YOUR_PROJECT_KEY" />
40
+ {children}
42
41
  </body>
43
42
  </html>
44
43
  );
45
44
  }
46
45
  ```
47
46
 
47
+ That's it. No `'use client'` required.
48
+
48
49
  ### Pages Router
49
50
 
50
51
  ```tsx
51
52
  // pages/_app.tsx
52
- 'use client';
53
-
54
53
  import { MVTOrchestrator } from '@mvtlab/nextjs-orchestrator';
55
54
 
56
55
  export default function MyApp({ Component, pageProps }) {
@@ -62,150 +61,192 @@ export default function MyApp({ Component, pageProps }) {
62
61
  }
63
62
  ```
64
63
 
65
- > **Why `'use client'`?** The component injects scripts and styles, accesses `window`/`document`, and defines `window.rmfk`—all browser-only operations that can't run in server components.
66
-
67
64
  ---
68
65
 
69
- ## API
66
+ ## Components
70
67
 
71
- ### Props
68
+ ### `MVTScripts` — Server Component ✅ Recommended
72
69
 
73
- | Prop | Type | Required | Default | Description |
74
- |------|------|----------|---------|-------------|
75
- | `orchestratorKey` | `string` | ✅ | - | MVTLab.io project key (passed as `data-project-key`) |
76
- | `children` | `ReactNode` | ✅ | - | App content to wrap |
77
- | `antiFlickerEnabled` | `boolean` | ❌ | `true` | Inject temporary `body{opacity:0}` style until engine ready |
78
- | `antiFlickerTimeoutMs` | `number` | ❌ | `3000` | Fallback timeout to remove anti-flicker style |
70
+ Place once at the top of `<body>` in your root `layout.tsx`.
79
71
 
80
- ### TypeScript
72
+ Renders two script tags directly into the server HTML:
73
+
74
+ 1. An **inline anti-flicker script** that sets `body { opacity: 0 }` and exposes
75
+ `window.rmfk()` — runs synchronously before any page content is visible.
76
+ 2. The **MVT engine `<script async>`** that loads the CDN, applies variant changes,
77
+ then calls `window.rmfk()` to reveal the page.
81
78
 
82
79
  ```tsx
83
- import type { MVTOrchestratorProps } from '@mvtlab/nextjs-orchestrator';
80
+ import { MVTScripts } from '@mvtlab/nextjs-orchestrator';
81
+
82
+ <MVTScripts
83
+ orchestratorKey="YOUR_PROJECT_KEY"
84
+ antiFlickerEnabled={true} // default
85
+ antiFlickerTimeoutMs={3000} // default
86
+ />
84
87
  ```
85
88
 
86
- ---
89
+ | Prop | Type | Default | Description |
90
+ | --- | --- | --- | --- |
91
+ | `orchestratorKey` | `string` | — | MVTLab project key |
92
+ | `antiFlickerEnabled` | `boolean` | `true` | Inject `body{opacity:0}` before hydration |
93
+ | `antiFlickerTimeoutMs` | `number` | `3000` | Fallback timeout to reveal page if engine stalls |
94
+ | `engineUrl` | `string` | staging CDN URL | Override engine script URL |
87
95
 
88
- ## Usage Examples
96
+ ### `MVTOrchestrator` — Client Component
97
+
98
+ A `'use client'` component that handles script injection client-side and enforces a single
99
+ project key per page. Use this for **Pages Router** apps or when you cannot modify `layout.tsx`.
89
100
 
90
- ### Basic
101
+ > **Note:** When used without `MVTScripts` in layout, the anti-flicker fires after React
102
+ > hydration and will not prevent the initial SSR content flash. For full flicker prevention
103
+ > use `MVTScripts` in `layout.tsx`.
104
+ >
105
+ > When used **together with `MVTScripts`**, `MVTOrchestrator` automatically detects the
106
+ > server-injected script and skips re-injection — no duplicate scripts.
91
107
 
92
108
  ```tsx
93
- <MVTOrchestrator orchestratorKey="abc123xyz">
94
- <YourApp />
109
+ import { MVTOrchestrator } from '@mvtlab/nextjs-orchestrator';
110
+
111
+ <MVTOrchestrator
112
+ orchestratorKey="YOUR_PROJECT_KEY"
113
+ antiFlickerEnabled={true} // default
114
+ antiFlickerTimeoutMs={3000} // default
115
+ >
116
+ {children}
95
117
  </MVTOrchestrator>
96
118
  ```
97
119
 
98
- ### Disable Anti-Flicker
120
+ | Prop | Type | Default | Description |
121
+ | --- | --- | --- | --- |
122
+ | `orchestratorKey` | `string` | — | MVTLab project key |
123
+ | `children` | `ReactNode` | — | App content to wrap |
124
+ | `antiFlickerEnabled` | `boolean` | `true` | Enable anti-flicker |
125
+ | `antiFlickerTimeoutMs` | `number` | `3000` | Fallback timeout |
126
+ | `engineUrl` | `string` | staging CDN URL | Override engine script URL |
127
+
128
+ ---
129
+
130
+ ## Usage Examples
131
+
132
+ ### With environment variable
99
133
 
100
134
  ```tsx
101
- <MVTOrchestrator
102
- orchestratorKey="abc123xyz"
103
- antiFlickerEnabled={false}
104
- >
105
- <YourApp />
106
- </MVTOrchestrator>
135
+ // .env.local
136
+ NEXT_PUBLIC_MVT_PROJECT_KEY=your_key_here
137
+ ```
138
+
139
+ ```tsx
140
+ <MVTScripts orchestratorKey={process.env.NEXT_PUBLIC_MVT_PROJECT_KEY!} />
107
141
  ```
108
142
 
109
- ### Custom Timeout
143
+ ### Disable anti-flicker
110
144
 
111
145
  ```tsx
112
- <MVTOrchestrator
113
- orchestratorKey="abc123xyz"
114
- antiFlickerTimeoutMs={5000}
115
- >
116
- <YourApp />
117
- </MVTOrchestrator>
146
+ <MVTScripts orchestratorKey="abc123xyz" antiFlickerEnabled={false} />
118
147
  ```
119
148
 
120
- ### Environment Variables
149
+ ### Custom timeout
121
150
 
122
151
  ```tsx
123
- // .env.local
124
- NEXT_PUBLIC_MVT_PROJECT_KEY=your_key_here
152
+ <MVTScripts orchestratorKey="abc123xyz" antiFlickerTimeoutMs={5000} />
125
153
  ```
126
154
 
155
+ ### TypeScript
156
+
127
157
  ```tsx
128
- <MVTOrchestrator
129
- orchestratorKey={process.env.NEXT_PUBLIC_MVT_PROJECT_KEY!}
130
- >
131
- {children}
132
- </MVTOrchestrator>
158
+ import type { MVTScriptsProps, MVTOrchestratorProps } from '@mvtlab/nextjs-orchestrator';
133
159
  ```
134
160
 
135
161
  ---
136
162
 
137
163
  ## How It Works
138
164
 
139
- ### Script Injection
165
+ ### `MVTScripts` (Server Component)
166
+
167
+ Server-renders two `<script>` tags into the HTML response:
168
+
169
+ ```html
170
+ <!-- Anti-flicker: runs synchronously before any content is shown -->
171
+ <script id="mvt-anti-flicker">
172
+ var timeout=3000;!(function(h,i,d,e){ ... body{opacity:0} ... window.rmfk ... })(...)
173
+ </script>
174
+
175
+ <!-- Engine: async, loads CDN, applies variants, calls window.rmfk() -->
176
+ <script
177
+ id="mvt-engine-script"
178
+ src="https://staging-svc.mvtlab.io/scripts/engine.js"
179
+ data-project-key="YOUR_KEY"
180
+ data-mvt="engine"
181
+ data-mvt-engine="true"
182
+ data-flicker-class="abtest-hidden"
183
+ crossorigin="anonymous"
184
+ async
185
+ ></script>
186
+ ```
187
+
188
+ Sequence: **body hidden → engine loads → variants applied → body revealed**
140
189
 
141
- On mount (client-side only via `useEffect`):
190
+ ### `MVTOrchestrator` (Client Component)
142
191
 
143
- 1. Checks for existing script with `id="mvt-engine-script"`
144
- 2. If missing, creates `<script>` with:
145
- - `src="https://staging-svc.mvtlab.io/scripts/engine.js"`
146
- - `data-project-key={orchestratorKey}`
147
- - `data-mvt="engine"`
148
- - `async={true}`
149
- 3. Appends to `<head>`
192
+ Injects the same scripts via `useEffect` (after hydration). Detects if `MVTScripts` already
193
+ ran (`id="mvt-engine-script"` present) and skips re-injection.
150
194
 
151
- This ensures **one script per page**, even on re-renders.
195
+ Sequence when standalone: **SSR renders hydration useEffect → scripts injected**
152
196
 
153
- ### Anti-Flicker
197
+ ### Anti-Flicker Detail
154
198
 
155
- When `antiFlickerEnabled={true}`:
199
+ - `<style id="abhide">body{opacity:0}</style>` is injected into `<head>`
200
+ - `window.rmfk()` is defined to remove that style element
201
+ - The engine calls `window.rmfk()` once variants are applied
202
+ - A safety timeout removes the style if the engine never responds
156
203
 
157
- 1. Injects `<style id="abhide">body{opacity:0}</style>` into `<head>`
158
- 2. Defines `window.rmfk()` to remove the style element
159
- 3. Engine calls `window.rmfk()` when ready
160
- 4. Safety timeout (default 3000ms) calls `window.rmfk()` as fallback
204
+ ---
161
205
 
162
- The `id="abhide"` matches the original HTML snippet's style identifier. The function name `rmfk` stands for "remove flicker"—a callback the engine uses to signal readiness.
206
+ ## Troubleshooting
163
207
 
164
- ### Project Key Validation
208
+ **Engine not loading?**
165
209
 
166
- - Stores `orchestratorKey` in `window.__mvtOrchestratorKey` on mount
167
- - If a different key is detected, logs error and skips script injection
168
- - Enforces **one key per website** (wrap once at root)
210
+ - Verify `orchestratorKey` is the correct project key from your MVTLab dashboard
211
+ - Check the Network tab for the `engine.js` request and any errors
212
+ - Ensure the project's domain matches the `websiteUrl` configured in MVTLab
169
213
 
170
- ---
214
+ **Anti-flicker not working (page flashes)?**
171
215
 
172
- ## Troubleshooting
216
+ - Switch from `MVTOrchestrator` to `MVTScripts` in `layout.tsx` — the client-side approach cannot prevent the initial SSR flash
217
+ - Confirm `antiFlickerEnabled={true}` (default)
173
218
 
174
- **Script not loading?**
175
- - Ensure `'use client';` is present
176
- - Verify `orchestratorKey` is correct
177
- - Check browser console for errors
219
+ **Duplicate scripts in DOM?**
178
220
 
179
- **Anti-flicker not working?**
180
- - Confirm `antiFlickerEnabled={true}`
181
- - Check if `window.rmfk()` is called (inspect console)
182
- - Increase `antiFlickerTimeoutMs` if engine loads slowly
221
+ - Use `MVTScripts` or `MVTOrchestrator` once at root, not both independently
222
+ - If using both together, `MVTOrchestrator` auto-detects `MVTScripts` and skips injection
183
223
 
184
- **Multiple scripts?**
185
- - Use `MVTOrchestrator` only once at root
186
- - Don't use different keys on the same page
224
+ **Pages Router / no layout.tsx?**
187
225
 
188
- **SSR errors?**
189
- - All DOM access is in `useEffect` (browser-only)
190
- - Ensure `'use client';` is at the top of the file
226
+ - Use `MVTOrchestrator` in `pages/_app.tsx`
191
227
 
192
228
  ---
193
229
 
194
230
  ## FAQ
195
231
 
196
- **Is this SSR-safe?**
197
- Yes. DOM operations run in `useEffect`, which only executes in the browser. Server renders `{children}`; script injection is client-only.
232
+ **Do I need `'use client'` with `MVTScripts`?**
233
+ No. `MVTScripts` is a Server Component. Add it directly to your `layout.tsx` without any directive.
234
+
235
+ **Can I use `MVTScripts` and `MVTOrchestrator` together?**
236
+ Yes. Put `MVTScripts` in `layout.tsx` for correct timing and use `MVTOrchestrator` elsewhere for
237
+ client-side key enforcement. The orchestrator detects the server-injected script and won't duplicate it.
198
238
 
199
- **Can I use multiple project keys?**
200
- No. Use one `orchestratorKey` at the root for the entire website. Different keys on the same page will log an error.
239
+ **Can I use multiple project keys?**
240
+ No. Use one `orchestratorKey` for the entire site. Different keys on the same page will log an error.
201
241
 
202
- **What if the engine fails to load?**
203
- The timeout (default 3000ms) removes the anti-flicker style, so the page becomes visible. Engine features won't be available.
242
+ **What if the engine fails to load?**
243
+ The timeout (default 3000ms) removes the anti-flicker style so the page becomes visible.
244
+ Experiment variants won't be applied.
204
245
 
205
- **TypeScript support?**
206
- Full type definitions included. Import `MVTOrchestratorProps` for type checking.
246
+ **TypeScript support?**
247
+ Full type definitions included. Both `MVTScriptsProps` and `MVTOrchestratorProps` are exported.
207
248
 
208
- **Browser support?**
249
+ **Browser support?**
209
250
  Modern browsers with ES2019+, React 18+, and standard DOM APIs.
210
251
 
211
252
  ---
@@ -225,4 +266,6 @@ See [LICENSE](LICENSE) for details.
225
266
 
226
267
  ---
227
268
 
228
- *This package wraps the standard MVTLab.io HTML integration snippet into a React component. The original snippet uses an IIFE pattern with `document`, `window`, and a timeout—this SDK translates that into React hooks and TypeScript types.*
269
+ *`MVTScripts` renders the standard MVTLab.io HTML snippet server-side so it runs before
270
+ hydration. `MVTOrchestrator` translates the same snippet into React hooks for client-side
271
+ or Pages Router use.*
@@ -7,8 +7,12 @@ export type MVTOrchestratorProps = {
7
7
  orchestratorKey: string;
8
8
  /**
9
9
  * Enable or disable the anti-flicker style injection.
10
- * When enabled, a temporary style is applied to hide the body until
11
- * the engine (or timeout) removes it, similar to the plain HTML snippet.
10
+ * When enabled and MVTScripts is NOT present in layout.tsx, a temporary
11
+ * style is applied client-side to hide the body until the engine removes it.
12
+ * Note: when used standalone (without MVTScripts), anti-flicker fires after
13
+ * React hydration and will not prevent the initial SSR content flash.
14
+ * For full flicker prevention use MVTScripts in your root layout.tsx instead.
15
+ * Defaults to true.
12
16
  */
13
17
  antiFlickerEnabled?: boolean;
14
18
  /**
@@ -8,48 +8,62 @@ export const MVTOrchestrator = ({ orchestratorKey, antiFlickerEnabled = true, an
8
8
  if (typeof window === 'undefined' || typeof document === 'undefined') {
9
9
  return;
10
10
  }
11
- // Anti-flicker: inject style to hide body and set up removal function
11
+ // Detect whether MVTScripts server component already injected the engine.
12
+ // If the <script id="mvt-engine-script"> is present, the server-side path
13
+ // ran (correct timing). We skip script injection but still ensure window.rmfk
14
+ // is available for the engine to call and set the timeout fallback.
15
+ const engineAlreadyInjected = !!document.getElementById('mvt-engine-script');
16
+ // Anti-flicker: only inject client-side when MVTScripts was NOT used.
17
+ // When MVTScripts is in layout.tsx the anti-flicker script is server-rendered
18
+ // and window.rmfk is already defined — we just need to set the timeout fallback.
12
19
  if (antiFlickerEnabled) {
13
- const existing = document.getElementById(ANTI_FLICKER_STYLE_ID);
14
- if (!existing) {
15
- const style = document.createElement('style');
16
- style.id = ANTI_FLICKER_STYLE_ID;
17
- style.innerHTML = 'body{opacity:0}';
18
- document.head.appendChild(style);
20
+ if (!engineAlreadyInjected) {
21
+ // Standalone mode: inject anti-flicker client-side (fires after hydration —
22
+ // does not prevent the initial SSR flash, but still protects against variant
23
+ // flicker on client-side navigations).
24
+ const existing = document.getElementById(ANTI_FLICKER_STYLE_ID);
25
+ if (!existing) {
26
+ const style = document.createElement('style');
27
+ style.id = ANTI_FLICKER_STYLE_ID;
28
+ style.innerHTML = 'body{opacity:0}';
29
+ document.head.appendChild(style);
30
+ }
19
31
  }
20
- // Expose rmfk on window to allow the engine to remove the flicker style
32
+ // Expose window.rmfk so the engine can remove the anti-flicker style.
33
+ // MVTScripts also defines this via the inline script; redefining here is safe.
21
34
  window.rmfk = function rmfk() {
22
35
  const el = document.getElementById(ANTI_FLICKER_STYLE_ID);
23
36
  if (el && el.parentNode) {
24
37
  el.parentNode.removeChild(el);
25
38
  }
26
39
  };
27
- // Safety timeout to remove if engine never calls rmfk
40
+ // Safety timeout: remove anti-flicker if the engine never calls rmfk.
28
41
  window.setTimeout(() => {
29
- if (typeof window.rmfk === 'function') {
30
- window.rmfk();
42
+ const rmfk = window.rmfk;
43
+ if (typeof rmfk === 'function') {
44
+ rmfk();
31
45
  }
32
46
  }, antiFlickerTimeoutMs);
33
47
  }
34
- // Enforce a single project key per page
35
- const globalKeyProp = '__mvtOrchestratorKey';
36
48
  const w = window;
37
- if (w[globalKeyProp] && w[globalKeyProp] !== orchestratorKey) {
49
+ if (w.__mvtOrchestratorKey && w.__mvtOrchestratorKey !== orchestratorKey) {
38
50
  // eslint-disable-next-line no-console
39
51
  console.error('[MVTOrchestrator] Multiple different project keys on the same page are not supported. ' +
40
- `Existing key: "${w[globalKeyProp]}", new key: "${orchestratorKey}".`);
52
+ `Existing key: "${w.__mvtOrchestratorKey}", new key: "${orchestratorKey}".`);
41
53
  return;
42
54
  }
43
- w[globalKeyProp] = orchestratorKey;
44
- // Inject the engine script only once per page load / key
45
- const scriptId = 'mvt-engine-script';
46
- if (!document.getElementById(scriptId)) {
55
+ w.__mvtOrchestratorKey = orchestratorKey;
56
+ // Inject the engine script only when MVTScripts did not already do so.
57
+ if (!engineAlreadyInjected) {
47
58
  const script = document.createElement('script');
48
- script.id = scriptId;
59
+ script.id = 'mvt-engine-script';
49
60
  script.src = engineUrl;
50
61
  script.async = true;
62
+ script.crossOrigin = 'anonymous';
51
63
  script.setAttribute('data-project-key', orchestratorKey);
52
64
  script.setAttribute('data-mvt', 'engine');
65
+ script.setAttribute('data-mvt-engine', 'true');
66
+ script.setAttribute('data-flicker-class', 'abtest-hidden');
53
67
  document.head.appendChild(script);
54
68
  }
55
69
  }, [orchestratorKey, antiFlickerEnabled, antiFlickerTimeoutMs, engineUrl]);
@@ -0,0 +1,46 @@
1
+ import React from 'react';
2
+ export type MVTScriptsProps = {
3
+ /**
4
+ * Project key used by the MVT engine.
5
+ */
6
+ orchestratorKey: string;
7
+ /**
8
+ * Enable or disable the anti-flicker style injection.
9
+ * Defaults to true.
10
+ */
11
+ antiFlickerEnabled?: boolean;
12
+ /**
13
+ * Timeout in milliseconds to automatically remove the anti-flicker style
14
+ * if the engine never calls window.rmfk(). Defaults to 3000ms.
15
+ */
16
+ antiFlickerTimeoutMs?: number;
17
+ /**
18
+ * Custom engine script URL.
19
+ * Defaults to the staging endpoint.
20
+ */
21
+ engineUrl?: string;
22
+ };
23
+ /**
24
+ * Server Component — place at the top of your root layout.tsx <body>.
25
+ *
26
+ * Renders the anti-flicker inline script and the MVT engine <script> tag
27
+ * directly into the server-generated HTML so they execute before React
28
+ * hydration, eliminating the content flash that useEffect-based injection
29
+ * cannot prevent.
30
+ *
31
+ * Usage in app/layout.tsx:
32
+ *
33
+ * import { MVTScripts } from '@mvtlab/nextjs-orchestrator';
34
+ *
35
+ * export default function RootLayout({ children }) {
36
+ * return (
37
+ * <html>
38
+ * <body>
39
+ * <MVTScripts orchestratorKey="YOUR_PROJECT_KEY" />
40
+ * {children}
41
+ * </body>
42
+ * </html>
43
+ * );
44
+ * }
45
+ */
46
+ export declare const MVTScripts: React.FC<MVTScriptsProps>;
@@ -0,0 +1,34 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ const DEFAULT_ENGINE_URL = 'https://staging-svc.mvtlab.io/scripts/engine.js';
3
+ /**
4
+ * Server Component — place at the top of your root layout.tsx <body>.
5
+ *
6
+ * Renders the anti-flicker inline script and the MVT engine <script> tag
7
+ * directly into the server-generated HTML so they execute before React
8
+ * hydration, eliminating the content flash that useEffect-based injection
9
+ * cannot prevent.
10
+ *
11
+ * Usage in app/layout.tsx:
12
+ *
13
+ * import { MVTScripts } from '@mvtlab/nextjs-orchestrator';
14
+ *
15
+ * export default function RootLayout({ children }) {
16
+ * return (
17
+ * <html>
18
+ * <body>
19
+ * <MVTScripts orchestratorKey="YOUR_PROJECT_KEY" />
20
+ * {children}
21
+ * </body>
22
+ * </html>
23
+ * );
24
+ * }
25
+ */
26
+ export const MVTScripts = ({ orchestratorKey, antiFlickerEnabled = true, antiFlickerTimeoutMs = 3000, engineUrl = DEFAULT_ENGINE_URL, }) => {
27
+ // Matches the exact anti-flicker snippet used in the plain HTML pages:
28
+ // hides body{opacity:0}, exposes window.rmfk() for the engine to call,
29
+ // and falls back to auto-removal after the timeout.
30
+ const antiFlickerHtml = `var timeout=${antiFlickerTimeoutMs};!(function(h,i,d,e){var t,n=h.createElement("style");(n.id=e),(n.innerHTML="body{opacity:0}"),h.head.appendChild(n),(t=d),(i.rmfk=function(){var t=h.getElementById(e);t&&t.parentNode.removeChild(t)}),setTimeout(i.rmfk,t)})(document,window,timeout,"abhide");`;
31
+ return (_jsxs(_Fragment, { children: [antiFlickerEnabled && (
32
+ // eslint-disable-next-line react/no-danger
33
+ _jsx("script", { id: "mvt-anti-flicker", dangerouslySetInnerHTML: { __html: antiFlickerHtml } })), _jsx("script", { id: "mvt-engine-script", src: engineUrl, "data-project-key": orchestratorKey, "data-mvt": "engine", "data-mvt-engine": "true", "data-flicker-class": "abtest-hidden", crossOrigin: "anonymous", async: true })] }));
34
+ };
package/dist/index.d.ts CHANGED
@@ -1 +1,2 @@
1
1
  export * from './MVTOrchestrator';
2
+ export * from './MVTScripts';
package/dist/index.js CHANGED
@@ -1 +1,2 @@
1
1
  export * from './MVTOrchestrator';
2
+ export * from './MVTScripts';
package/package.json CHANGED
@@ -1,10 +1,20 @@
1
1
  {
2
2
  "name": "@mvtlab/nextjs-orchestrator",
3
- "version": "0.1.2",
3
+ "version": "0.2.0",
4
4
  "description": "Next.js SDK to integrate the MVT Lab CDN engine with optional anti-flicker support.",
5
- "main": "dist/index.cjs",
6
- "module": "dist/index.mjs",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js",
12
+ "default": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
8
18
  "sideEffects": false,
9
19
  "scripts": {
10
20
  "build": "tsc -p tsconfig.build.json"
@@ -26,5 +36,6 @@
26
36
  "cdn-engine"
27
37
  ],
28
38
  "author": "MVT Lab",
29
- "license": "MVTLab.io"
39
+ "license": "MVTLab.io",
40
+ "packageManager": "yarn@4.12.0"
30
41
  }
package/CHANGELOG.md DELETED
@@ -1,47 +0,0 @@
1
- # Changelog
2
-
3
- All notable changes to this project will be documented in this file.
4
-
5
- The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
- and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
-
8
- ## [Unreleased]
9
-
10
- ## [0.1.2] - 2024-11-26
11
-
12
- ### Changed
13
-
14
- - Included README in published npm package so documentation appears on npmjs.com
15
- - Minor documentation polish and packaging tweaks (no runtime changes)
16
-
17
- ## [0.1.1] - 2024-11-26
18
-
19
- ### Changed
20
-
21
- - Updated README documentation for improved clarity and simplicity
22
- - Removed engine URL configuration references
23
- - Enhanced technical documentation with implementation details
24
- - Added easter eggs explaining technical internals (`rmfk`, `abhide`, IIFE translation)
25
-
26
- ## [0.1.0] - 2024-11-26
27
-
28
- ### Added
29
-
30
- - Initial release of `@mvtlab/nextjs-orchestrator`
31
- - `MVTOrchestrator` React component for Next.js integration
32
- - Anti-flicker support with configurable timeout
33
- - Automatic script injection for MVTLab.io CDN engine
34
- - Project key validation to enforce single key per website
35
- - TypeScript type definitions (`MVTOrchestratorProps`)
36
- - Support for both Next.js App Router and Pages Router
37
- - SSR-safe implementation (all DOM operations in `useEffect`)
38
- - Duplicate script prevention (idempotent script injection)
39
- - Full documentation and examples
40
-
41
- ### Technical Details
42
-
43
- - Wraps the standard MVTLab.io HTML integration snippet into a React component
44
- - Translates IIFE pattern with `document`/`window` access into React hooks
45
- - Implements `window.rmfk()` callback for engine readiness signaling
46
- - Uses `id="abhide"` style tag matching original snippet behavior
47
-