@mvtlab/nextjs-orchestrator 0.1.0 → 0.1.2

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 (3) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/README.md +142 -118
  3. package/package.json +1 -1
package/CHANGELOG.md ADDED
@@ -0,0 +1,47 @@
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
+
package/README.md CHANGED
@@ -1,44 +1,14 @@
1
- ## `@mvtlab/nextjs-orchestrator`
2
-
3
- **Next.js / React SDK** to integrate the MVTLab.io CDN engine with optional anti‑flicker support.
4
-
5
- It wraps the plain HTML snippet:
6
-
7
- ```html
8
- <script>
9
- var timeout = 3000;
10
- !(function (h, i, d, e) {
11
- var t,
12
- n = h.createElement('style');
13
- (n.id = e),
14
- (n.innerHTML = 'body{opacity:0}'),
15
- h.head.appendChild(n),
16
- (t = d),
17
- (i.rmfk = function () {
18
- var t = h.getElementById(e);
19
- t && t.parentNode.removeChild(t);
20
- }),
21
- setTimeout(i.rmfk, t);
22
- })(document, window, timeout, 'abhide');
23
- </script>
24
- <script
25
- src="https://staging-svc.mvtlab.io/scripts/engine.js"
26
- data-project-key="Kjnqjkf277nYGYUSoA0IXQ"
27
- data-mvt="engine"
28
- ></script>
29
- ```
1
+ # @mvtlab/nextjs-orchestrator
30
2
 
31
- into a simple React component:
3
+ [![npm version](https://img.shields.io/npm/v/@mvtlab/nextjs-orchestrator.svg)](https://www.npmjs.com/package/@mvtlab/nextjs-orchestrator)
4
+ [![npm downloads](https://img.shields.io/npm/dm/@mvtlab/nextjs-orchestrator.svg)](https://www.npmjs.com/package/@mvtlab/nextjs-orchestrator)
5
+ [![License](https://img.shields.io/npm/l/@mvtlab/nextjs-orchestrator.svg)](LICENSE)
32
6
 
33
- ```tsx
34
- <MVTOrchestrator orchestratorKey="yourProjectKey" antiFlickerEnabled>
35
- {children}
36
- </MVTOrchestrator>
37
- ```
7
+ React component for integrating MVTLab.io CDN engine into Next.js applications with optional anti-flicker support.
38
8
 
39
9
  ---
40
10
 
41
- ### Installation
11
+ ## Installation
42
12
 
43
13
  ```bash
44
14
  npm install @mvtlab/nextjs-orchestrator
@@ -46,38 +16,27 @@ npm install @mvtlab/nextjs-orchestrator
46
16
  yarn add @mvtlab/nextjs-orchestrator
47
17
  ```
48
18
 
49
- `MVTOrchestrator` is a **client component**, so it must be used in a file marked with `'use client';`.
50
-
51
- > **Why client-only?**
52
- > The orchestrator injects `<script>` and `<style>` tags, accesses `window` and `document`, and defines `window.rmfk`.
53
- > These operations only exist in the browser and are not allowed in Next.js server components, so the component must run on the client.
19
+ **Requirements:** Next.js >= 13.0.0, React >= 18.0.0
54
20
 
55
21
  ---
56
22
 
57
- ### Quick start (Next.js App Router)
23
+ ## Quick Start
58
24
 
59
- Recommended usage is to wrap your **entire app at the root** so there is exactly **one project key per website**.
25
+ Wrap your app at the root level. The component must be in a client component file (`'use client';`).
60
26
 
61
- Example in `app/layout.tsx`:
27
+ ### App Router
62
28
 
63
29
  ```tsx
30
+ // app/layout.tsx
64
31
  'use client';
65
32
 
66
- import React from 'react';
67
33
  import { MVTOrchestrator } from '@mvtlab/nextjs-orchestrator';
68
34
 
69
- export default function RootLayout({
70
- children,
71
- }: {
72
- children: React.ReactNode;
73
- }) {
35
+ export default function RootLayout({ children }) {
74
36
  return (
75
37
  <html lang="en">
76
38
  <body>
77
- <MVTOrchestrator
78
- orchestratorKey="Kjnqjkf277nYGYUSoA0IXQ"
79
- antiFlickerEnabled={true}
80
- >
39
+ <MVTOrchestrator orchestratorKey="YOUR_PROJECT_KEY">
81
40
  {children}
82
41
  </MVTOrchestrator>
83
42
  </body>
@@ -86,119 +45,184 @@ export default function RootLayout({
86
45
  }
87
46
  ```
88
47
 
89
- This:
90
-
91
- - **Injects the MVTLab.io engine script** into `<head>` once for the whole site with your project key.
92
- - **Optionally hides the body** until the engine is ready (anti‑flicker).
93
- In this setup your app has **a single `orchestratorKey` at the root**, shared across all pages.
94
-
95
- ---
96
-
97
- ### Usage in Next.js Pages Router
98
-
99
- In a classic `pages/_app.tsx`:
48
+ ### Pages Router
100
49
 
101
50
  ```tsx
102
51
  // pages/_app.tsx
103
52
  'use client';
104
53
 
105
- import type { AppProps } from 'next/app';
106
54
  import { MVTOrchestrator } from '@mvtlab/nextjs-orchestrator';
107
55
 
108
- export default function MyApp({ Component, pageProps }: AppProps) {
56
+ export default function MyApp({ Component, pageProps }) {
109
57
  return (
110
- <MVTOrchestrator
111
- orchestratorKey="Kjnqjkf277nYGYUSoA0IXQ"
112
- antiFlickerEnabled={true}
113
- >
58
+ <MVTOrchestrator orchestratorKey="YOUR_PROJECT_KEY">
114
59
  <Component {...pageProps} />
115
60
  </MVTOrchestrator>
116
61
  );
117
62
  }
118
63
  ```
119
64
 
120
- In this setup your app has **a single `orchestratorKey` at the root**, shared across all pages.
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.
121
66
 
122
67
  ---
123
68
 
69
+ ## API
70
+
124
71
  ### Props
125
72
 
126
- - **`orchestratorKey`** (`string`, required)
127
- - MVTLab.io project key.
128
- - Passed to the script as `data-project-key="<orchestratorKey>"`.
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 |
79
+
80
+ ### TypeScript
129
81
 
130
- - **`antiFlickerEnabled`** (`boolean`, default `true`)
131
- - When `true`, a temporary `<style id="abhide">body{opacity:0}</style>` is injected into `<head>`.
132
- - This mimics the original anti‑flicker snippet and prevents users from briefly seeing the “un‑optimized” variant.
82
+ ```tsx
83
+ import type { MVTOrchestratorProps } from '@mvtlab/nextjs-orchestrator';
84
+ ```
133
85
 
134
- - **`antiFlickerTimeoutMs`** (`number`, default `3000`)
135
- - Timeout (in ms) after which the anti‑flicker style is removed automatically.
136
- - Safety net in case the engine never calls `window.rmfk()`.
86
+ ---
137
87
 
138
- - **`engineUrl`** (`string`, default `https://staging-svc.mvtlab.io/scripts/engine.js`)
139
- - Script URL used to load the MVTLab.io engine.
140
- - You can override this if you have a different environment (e.g. production).
88
+ ## Usage Examples
141
89
 
142
- - **`children`** (`ReactNode`, required)
143
- - The part of your app that should be orchestrated by the engine.
144
- - Usually your entire app tree.
90
+ ### Basic
145
91
 
146
- ---
92
+ ```tsx
93
+ <MVTOrchestrator orchestratorKey="abc123xyz">
94
+ <YourApp />
95
+ </MVTOrchestrator>
96
+ ```
147
97
 
148
- ### How anti‑flicker works
98
+ ### Disable Anti-Flicker
149
99
 
150
- When `antiFlickerEnabled` is `true`:
100
+ ```tsx
101
+ <MVTOrchestrator
102
+ orchestratorKey="abc123xyz"
103
+ antiFlickerEnabled={false}
104
+ >
105
+ <YourApp />
106
+ </MVTOrchestrator>
107
+ ```
151
108
 
152
- - A `<style>` tag with `id="abhide"` and `body{opacity:0}` is injected into `<head>`.
153
- - `window.rmfk` is defined as a function that removes that style element.
154
- - A timeout (`antiFlickerTimeoutMs`, default 3000ms) calls `window.rmfk()` as a fallback.
109
+ ### Custom Timeout
155
110
 
156
- This is a **direct React translation** of the plain HTML snippet you would otherwise manually embed.
111
+ ```tsx
112
+ <MVTOrchestrator
113
+ orchestratorKey="abc123xyz"
114
+ antiFlickerTimeoutMs={5000}
115
+ >
116
+ <YourApp />
117
+ </MVTOrchestrator>
118
+ ```
157
119
 
158
- If you do **not** want anti‑flicker:
120
+ ### Environment Variables
159
121
 
160
122
  ```tsx
161
- <MVTOrchestrator orchestratorKey="yourProjectKey" antiFlickerEnabled={false}>
123
+ // .env.local
124
+ NEXT_PUBLIC_MVT_PROJECT_KEY=your_key_here
125
+ ```
126
+
127
+ ```tsx
128
+ <MVTOrchestrator
129
+ orchestratorKey={process.env.NEXT_PUBLIC_MVT_PROJECT_KEY!}
130
+ >
162
131
  {children}
163
132
  </MVTOrchestrator>
164
- ``>
133
+ ```
165
134
 
166
135
  ---
167
136
 
168
- ### How script loading works
137
+ ## How It Works
138
+
139
+ ### Script Injection
140
+
141
+ On mount (client-side only via `useEffect`):
142
+
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>`
169
150
 
170
- On the client, the component:
151
+ This ensures **one script per page**, even on re-renders.
171
152
 
172
- 1. Checks for an existing `<script>` with `id="mvt-engine-script"`.
173
- 2. If not present, it creates a new `<script>` element with:
174
- - `src` = `engineUrl` (default staging URL),
175
- - `data-project-key` = `orchestratorKey`,
176
- - `data-mvt` = `"engine"`,
177
- - `async = true`.
178
- 3. Appends the script to `<head>`.
153
+ ### Anti-Flicker
179
154
 
180
- This ensures **only one script is injected per page**, even if `MVTOrchestrator` is rendered multiple times.
155
+ When `antiFlickerEnabled={true}`:
156
+
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
161
+
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.
163
+
164
+ ### Project Key Validation
165
+
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)
181
169
 
182
170
  ---
183
171
 
184
- ### FAQ
172
+ ## Troubleshooting
173
+
174
+ **Script not loading?**
175
+ - Ensure `'use client';` is present
176
+ - Verify `orchestratorKey` is correct
177
+ - Check browser console for errors
185
178
 
186
- - **Is this safe with SSR?**
187
- Yes. All DOM access runs inside `useEffect`, so it only executes in the browser, not during server‑side rendering.
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
188
183
 
189
- - **Can I use multiple project keys on the same page or site?**
190
- **No.** The orchestrator is designed to be used **once at the root of your app** with a single `orchestratorKey` for the whole website.
191
- Rendering with different keys on the same page is not supported and will log an error in the console as a safety check.
184
+ **Multiple scripts?**
185
+ - Use `MVTOrchestrator` only once at root
186
+ - Don't use different keys on the same page
192
187
 
193
- - **Can I disable anti‑flicker in development?**
194
- Yes, just pass `antiFlickerEnabled={false}` when you don’t need it.
188
+ **SSR errors?**
189
+ - All DOM access is in `useEffect` (browser-only)
190
+ - Ensure `'use client';` is at the top of the file
195
191
 
196
192
  ---
197
193
 
198
- ### License
194
+ ## FAQ
195
+
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.
199
198
 
200
- This package is **licensed under MVTLab.io**.
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.
201
201
 
202
- Copyright © MVTLab.io. All rights reserved.
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.
203
204
 
205
+ **TypeScript support?**
206
+ Full type definitions included. Import `MVTOrchestratorProps` for type checking.
207
+
208
+ **Browser support?**
209
+ Modern browsers with ES2019+, React 18+, and standard DOM APIs.
210
+
211
+ ---
212
+
213
+ ## License
214
+
215
+ Licensed under MVTLab.io. Copyright © MVTLab.io. All rights reserved.
216
+
217
+ See [LICENSE](LICENSE) for details.
218
+
219
+ ---
220
+
221
+ ## Support
222
+
223
+ - **GitHub:** [MVT-Lab/nextjs-orchestrator](https://github.com/MVT-Lab/nextjs-orchestrator)
224
+ - **MVTLab.io:** Contact your representative
225
+
226
+ ---
204
227
 
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.*
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mvtlab/nextjs-orchestrator",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Next.js SDK to integrate the MVT Lab CDN engine with optional anti-flicker support.",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.mjs",