Next.js
Integrate the General Wisdom Provider SDK in a Next.js 14 App Router project. The SDK requires browser APIs, so it must run inside a 'use client' component boundary.
Prerequisites
- Node.js 20+
- A Next.js 14+ project with the App Router (or create one below)
- Your Application ID and API Key from the Provider Dashboard
Quick Setup
npx create-next-app@latest my-gw-app --typescript --app
cd my-gw-app
npm install @mission_sciences/provider-sdk
npm run dev
Complete Example
Client Component
The SDK interacts with the DOM and browser APIs, so it must live in a Client Component:
'use client';
import { useEffect } from 'react';
import { MarketplaceSDK } from '@mission_sciences/provider-sdk';
const APP_ID = 'YOUR_APP_ID';
const API_KEY = 'YOUR_API_KEY';
export default function SessionClient() {
useEffect(() => {
const sdk = new MarketplaceSDK({
applicationId: APP_ID,
apiKey: API_KEY,
environment: 'production', // 'demo' | 'production'
autoStart: true,
themeMode: 'auto', // 'light' | 'dark' | 'auto'
warningThresholdSeconds: 300, // warn user 5 min before expiry
enableHeartbeat: false, // keep-alive ping
heartbeatIntervalSeconds: 30,
debug: false,
});
sdk.initialize().catch(console.error);
return () => {
sdk.destroy();
};
}, []);
return (
<div>
{/* Your application content */}
</div>
);
}
Server Page
The page itself remains a Server Component. It renders the Client Component that manages the SDK:
import SessionClient from './SessionClient';
export default function Page() {
return <SessionClient />;
}
Swap YOUR_APP_ID and YOUR_API_KEY with the credentials from your Provider Dashboard.
Pattern Breakdown
Why a separate Client Component?
Next.js App Router defaults to Server Components. The SDK requires:
windowand DOM access (browser-only APIs)useEffectfor lifecycle management- Client-side JavaScript execution
By isolating the SDK in a dedicated 'use client' component, the rest of your page can benefit from server rendering, streaming, and reduced JavaScript bundle on first load.
Architecture Diagram
┌─────────────────────────────────────────┐
│ page.tsx (Server Component) │
│ - Fetches data, renders layout │
│ - Zero client JS for static portions │
│ │
│ ┌───────────────────────────────────┐ │
│ │ SessionClient.tsx ('use client') │ │
│ │ - MarketplaceSDK lifecycle │ │
│ │ - useEffect mount/unmount │ │
│ └───────────────────────────────────┘ │
└─────────────────────────────────────────┘
Why not initialize in a layout?
You can place the SDK in layout.tsx to persist across page navigations. However, this keeps the session alive even on pages that do not need it. Prefer placing the SDK in the specific route that requires an active session.
Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
applicationId | string | — | Your registered application ID |
apiKey | string | — | Your API key |
environment | 'demo' | 'production' | 'production' | Target environment |
autoStart | boolean | true | Start session automatically on init |
themeMode | 'light' | 'dark' | 'auto' | 'auto' | UI theme preference |
warningThresholdSeconds | number | 300 | Seconds before expiry to show warning |
enableHeartbeat | boolean | false | Enable keep-alive pings |
heartbeatIntervalSeconds | number | 30 | Interval between heartbeat pings |
debug | boolean | false | Enable verbose console logging |
Common Gotchas
Missing 'use client' directive
Without the directive at the top of the file, Next.js treats the component as a Server Component. Any use of useEffect, useState, or browser globals will fail at build time with:
Error: useState/useEffect only works in Client Components. Add the "use client" directive.
SSR hydration mismatches
The SDK renders UI elements into the DOM after mount. If your component returns different markup on the server vs. the client, you will see hydration warnings. Keep the initial render minimal and let the SDK inject its UI post-mount.
Environment variables
In Next.js, client-accessible env vars must be prefixed with NEXT_PUBLIC_:
NEXT_PUBLIC_GW_APP_ID=app_abc123
NEXT_PUBLIC_GW_API_KEY=key_xyz789
const APP_ID = process.env.NEXT_PUBLIC_GW_APP_ID!;
const API_KEY = process.env.NEXT_PUBLIC_GW_API_KEY!;
Environment variables without the NEXT_PUBLIC_ prefix are server-only and will be undefined in Client Components.
Dynamic imports for code splitting
If you want to defer loading the SDK until the component actually mounts (reducing initial bundle size):
import dynamic from 'next/dynamic';
const SessionClient = dynamic(() => import('./SessionClient'), {
ssr: false,
});
export default function Page() {
return <SessionClient />;
}
Setting ssr: false skips server rendering entirely for this component, which avoids any SSR-related issues with browser APIs.
Next Steps
- Session Lifecycle — understand session states and transitions
- React Guide — simpler setup without App Router
- Playground — experiment with SDK options interactively