@stackone/hub 1.4.0 → 1.5.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
@@ -1,10 +1,6 @@
1
1
  # StackOne HUB
2
2
 
3
- > 👉 **BETA SOFTWARE**
4
- > This project is currently in **beta stage**. It is evolving quickly, and new versions may include breaking changes.
5
-
6
3
  ![License](https://img.shields.io/badge/license-MIT-blue.svg)
7
- ![Status](https://img.shields.io/badge/status-beta-blue.svg)
8
4
  ![Node Version](https://img.shields.io/badge/node-%3E%3D22.14.0-brightgreen.svg)
9
5
 
10
6
  StackOne HUB is a React-based integration component library that provides a web component wrapper for seamless integration into any web application. It enables developers to easily embed StackOne's integrations hub.
@@ -13,18 +9,20 @@ StackOne HUB is a React-based integration component library that provides a web
13
9
 
14
10
  - [StackOne HUB](#stackone-hub)
15
11
  - [📋 Table of Contents](#-table-of-contents)
16
- - [⚠️ Beta Notice](#️-beta-notice)
17
12
  - [🚀 Quick Start](#-quick-start)
18
13
  - [📦 Installation](#-installation)
19
14
  - [Prerequisites](#prerequisites)
20
15
  - [Setup](#setup)
21
16
  - [🛠️ Development](#️-development)
22
17
  - [Environment Setup](#environment-setup)
18
+ - [Next.js SSR Sandbox](#nextjs-ssr-sandbox)
23
19
  - [🏗️ Build](#️-build)
24
20
  - [Build Output](#build-output)
25
21
  - [📖 Usage](#-usage)
26
22
  - [🌐 Web Component Integration](#-web-component-integration)
27
23
  - [⚛️ React Component Integration](#️-react-component-integration)
24
+ - [▲ Next.js (App Router) Integration](#-nextjs-app-router-integration)
25
+ - [⚠️ "Invalid hook call" — duplicate React](#️-invalid-hook-call--duplicate-react)
28
26
  - [💻 Local Development Usage](#-local-development-usage)
29
27
  - [Web Component (Local)](#web-component-local)
30
28
  - [React Component (Local)](#react-component-local)
@@ -34,16 +32,6 @@ StackOne HUB is a React-based integration component library that provides a web
34
32
  - [Getting Started](#getting-started)
35
33
  - [📄 License](#-license)
36
34
 
37
- ## ⚠️ Beta Notice
38
-
39
- **This software is in active development and should be considered beta quality.**
40
-
41
- - 🚧 **Breaking changes** may occur in any release
42
- - 📚 **Documentation** is updated regularly
43
- - 🔄 **APIs are subject to change** without prior notice
44
-
45
- Please report issues and provide feedback to help us improve!
46
-
47
35
  ## 🚀 Quick Start
48
36
 
49
37
  ```bash
@@ -98,7 +86,25 @@ npm run dev
98
86
  npm run dev
99
87
  ```
100
88
 
101
- The development server will start at [http://localhost:3000](http://localhost:3000) (default port).
89
+ The Vite dev server starts at [http://localhost:3001](http://localhost:3001).
90
+
91
+ ### Next.js SSR Sandbox
92
+
93
+ A second sandbox lives in `dev/nextjs/` and runs the hub inside a Next.js 15 + React 19 App Router app. Use it to verify server-side rendering behaviour.
94
+
95
+ From the repo root:
96
+
97
+ ```bash
98
+ # First time (builds the hub and installs sandbox deps)
99
+ npm run dev:nextjs:setup
100
+
101
+ # Subsequent runs
102
+ npm run dev:nextjs
103
+ ```
104
+
105
+ The Next.js sandbox runs at [http://localhost:3002](http://localhost:3002). Set `STACKONE_API_KEY` in `dev/nextjs/.env` (see `dev/nextjs/.env.example`) to have the page fetch a connect-session token server-side, or paste one into the input on the page.
106
+
107
+ After editing hub source, rerun `npm run build` from the repo root — the sandbox is linked via `file:../..` so it picks up the new `dist/` automatically.
102
108
 
103
109
  ## 🏗️ Build
104
110
 
@@ -114,9 +120,10 @@ The build generates multiple bundles in the `dist/` directory:
114
120
 
115
121
  | File | Description | Use Case |
116
122
  |------|-------------|----------|
117
- | `StackOneHub.esm.js` | ES module bundle | Modern React applications |
118
- | `StackOneHub.cjs.js` | CommonJS module | Node.js/legacy environments |
119
- | `StackOneHub.web.js` | Web component bundle | Vanilla HTML/JS integration |
123
+ | `dist/index.esm.js` | ES module bundle (with `'use client'` banner) | Modern React apps, Next.js, Vite |
124
+ | `dist/index.js` | CommonJS module (with `'use client'` banner) | Node.js / legacy environments |
125
+ | `dist/index.d.ts` | TypeScript declarations | Type-checking |
126
+ | `dist/webcomponent.js` | Web component bundle (IIFE, React inlined) | Vanilla HTML/JS integration |
120
127
 
121
128
  ## 📖 Usage
122
129
 
@@ -131,24 +138,24 @@ For vanilla HTML/JavaScript applications:
131
138
  <title>StackOne HUB Integration</title>
132
139
  </head>
133
140
  <body>
134
- <script src="<TBD>/StackOneHub.web.js"></script>
135
- <my-component></my-component>
141
+ <script src="<TBD>/webcomponent.js"></script>
142
+ <stackone-hub token="..."></stackone-hub>
136
143
  </body>
137
144
  </html>
138
145
  ```
139
146
 
140
147
  ### ⚛️ React Component Integration
141
148
 
142
- For React applications:
149
+ For React applications (CSR — Vite, CRA, etc.):
143
150
 
144
151
  ```tsx
145
- import StackOneHub from "@stackone/StackOneHub";
152
+ import { StackOneHub } from "@stackone/hub";
146
153
 
147
154
  function App() {
148
155
  return (
149
156
  <div className="app">
150
157
  <h1>My Application</h1>
151
- <StackOneHub />
158
+ <StackOneHub token={token} />
152
159
  </div>
153
160
  );
154
161
  }
@@ -156,20 +163,134 @@ function App() {
156
163
  export default App;
157
164
  ```
158
165
 
166
+ `StackOneHub` is a client-side component — it ships with a `'use client'` directive and is safe to import directly in any framework that supports server-side rendering.
167
+
168
+ ### ▲ Next.js (App Router) Integration
169
+
170
+ `StackOneHub` is annotated with `'use client'` so you can import it directly from any Server Component. The token can be created server-side (recommended — keeps your API key off the client and avoids the CORS-protected `/connect_sessions` endpoint), and passed as a prop to a small Client Component that renders the hub.
171
+
172
+ **Important:** Add `suppressHydrationWarning` to the `<html>` tag in your root layout. The hub applies its theme CSS custom properties to `document.documentElement` after hydration, which would otherwise trigger a hydration warning on the `<html>` element (the warning only suppresses the `<html>` tag itself, not its children):
173
+
174
+ ```tsx
175
+ // app/layout.tsx
176
+ export default function RootLayout({ children }) {
177
+ return (
178
+ <html lang="en" suppressHydrationWarning>
179
+ <body>{children}</body>
180
+ </html>
181
+ );
182
+ }
183
+ ```
184
+
185
+ **`app/page.tsx`** (Server Component):
186
+
187
+ ```tsx
188
+ import HubWrapper from "./HubWrapper";
189
+
190
+ export default async function Page() {
191
+ const res = await fetch("https://api.stackone.com/connect_sessions", {
192
+ method: "POST",
193
+ headers: {
194
+ "Content-Type": "application/json",
195
+ Authorization: `Basic ${Buffer.from(process.env.STACKONE_API_KEY!).toString("base64")}`,
196
+ },
197
+ body: JSON.stringify({
198
+ origin_owner_id: "your_customer_id",
199
+ origin_owner_name: "Your Customer",
200
+ origin_username: "your_username",
201
+ }),
202
+ cache: "no-store",
203
+ });
204
+ const { token } = await res.json();
205
+
206
+ return <HubWrapper token={token} />;
207
+ }
208
+ ```
209
+
210
+ **`app/HubWrapper.tsx`** (Client Component):
211
+
212
+ ```tsx
213
+ "use client";
214
+
215
+ import { StackOneHub } from "@stackone/hub";
216
+
217
+ export default function HubWrapper({ token }: { token: string }) {
218
+ return (
219
+ <StackOneHub
220
+ token={token}
221
+ mode="integration-picker"
222
+ onSuccess={(account) => console.log("connected", account)}
223
+ />
224
+ );
225
+ }
226
+ ```
227
+
228
+ If you prefer to opt the hub out of SSR entirely (Pages Router, or to skip the server pre-render):
229
+
230
+ ```tsx
231
+ import dynamic from "next/dynamic";
232
+
233
+ const StackOneHub = dynamic(
234
+ () => import("@stackone/hub").then((m) => m.StackOneHub),
235
+ { ssr: false },
236
+ );
237
+ ```
238
+
239
+ A working example lives in [`dev/nextjs/`](./dev/nextjs).
240
+
241
+ ### ⚠️ "Invalid hook call" — duplicate React
242
+
243
+ `@stackone/hub` declares `react` and `react-dom` as **peer dependencies** and the bundle imports them at runtime — your app's copy must be the only copy that ends up loaded. In a standard `npm install` your bundler will hoist React and you won't see this. But the following setups can leave you with **two copies of React** and trip the "Invalid hook call" error:
244
+
245
+ - **Monorepos** (npm workspaces, Yarn workspaces, Turborepo) where multiple packages each have their own `node_modules/react`.
246
+ - **pnpm** with strict isolation — a transitive copy can shadow the root copy.
247
+ - **`file:` / `link:` dependencies** pointing at a directory that has its own `node_modules/react` (this is what bit our local Vite sandbox).
248
+
249
+ Fixes by bundler:
250
+
251
+ **Vite** — add `resolve.dedupe` to your config:
252
+
253
+ ```ts
254
+ // vite.config.ts
255
+ export default defineConfig({
256
+ resolve: {
257
+ dedupe: ['react', 'react-dom', 'react-hook-form'],
258
+ },
259
+ });
260
+ ```
261
+
262
+ **Webpack / Next.js** — usually handled automatically. If not, alias `react` and `react-dom` to a single absolute path:
263
+
264
+ ```js
265
+ // next.config.mjs
266
+ import path from "node:path";
267
+ export default {
268
+ webpack: (config) => {
269
+ config.resolve.alias["react"] = path.resolve("./node_modules/react");
270
+ config.resolve.alias["react-dom"] = path.resolve("./node_modules/react-dom");
271
+ return config;
272
+ },
273
+ };
274
+ ```
275
+
276
+ **pnpm** — set `public-hoist-pattern[]=react*` in `.npmrc`, or `shamefully-hoist=true`.
277
+
278
+ To diagnose, run `npm ls react` (or `pnpm why react`) at your app's root — if you see more than one entry resolved to a different path, that's the cause.
279
+
159
280
  ### 💻 Local Development Usage
160
281
 
161
282
  #### Web Component (Local)
162
283
  ```html
163
- <script src="dist/StackOneHub.web.js"></script>
164
- <my-component></my-component>
284
+ <script src="dist/webcomponent.js"></script>
285
+ <stackone-hub token="..."></stackone-hub>
165
286
  ```
166
287
 
167
288
  #### React Component (Local)
168
289
  ```tsx
169
- import StackOneHub from "dist/StackOneHub.esm";
290
+ import { StackOneHub } from "../dist/index.esm.js";
170
291
 
171
292
  function App() {
172
- return <StackOneHub />;
293
+ return <StackOneHub token={token} />;
173
294
  }
174
295
  ```
175
296
 
@@ -198,9 +319,8 @@ DASHBOARD_URL=https://dashboard.stackone.com
198
319
 
199
320
  ## 🤝 Contributing
200
321
 
201
- Since this project is in beta, we welcome contributions and feedback! However, please keep in mind:
322
+ We welcome contributions and feedback! Please keep in mind:
202
323
 
203
- - 🔄 **Frequent changes**: The codebase may change rapidly
204
324
  - 📋 **No formal process yet**: Contribution guidelines are still being established
205
325
  - 💬 **Communication is key**: Please open an issue before submitting large changes
206
326