Next.js SDK — Getting Started
Use @video/video-client-react in a Next.js app — App Router or Pages Router. The React hooks and components are the same as the React guide; the one Next.js-specific step is keeping the SDK out of server rendering. This guide gets you to a working broadcaster in under 10 minutes.
Grab these from your account before you start:
- An authentication token (JWT) — a broadcaster token to stream, a viewer token to watch.
- A stream key for your stream.
- Your backend endpoint, e.g.
https://your-subdomain.example.com.
Next.js 13+ (App Router) or 12+ (Pages Router), on React 16.8+.
1. Configure the registry
Add the private registry to your project's .npmrc:
@video:registry=https://npm-packages.example.com/
2. Install
npm install @video/video-client-react
The SDK uses WebRTC and browser media APIs (navigator.mediaDevices, RTCPeerConnection), which don't exist on the server. Rendering it during SSR throws window is not defined or navigator is not defined. The fix is the same in both routers: render the video component on the client only, via next/dynamic with ssr: false.
3. Create the video component
Put the broadcaster in its own component. The 'use client' directive is required by the App Router and is harmless under the Pages Router, so a single file works for both.
'use client';
import React, { useMemo } from 'react';
import {
usePreviewPlayer,
useAuthClient,
useCreateCall,
useBroadcast
} from '@video/video-client-react/hooks';
import {
MediaStreamControllerAPIProvider,
PlayerAPIProvider
} from '@video/video-client-react/context';
import { Video } from '@video/video-client-react/components';
export default function Broadcaster() {
const { mediaStreamController, previewPlayer } = usePreviewPlayer();
const authClient = useAuthClient('your-broadcaster-token');
// useCreateCall and useBroadcast pin their inputs at first render, so memoize
// these — a fresh object literal every render means later changes are
// silently ignored instead of recreating the call.
const callOptions = useMemo(() => ({
streamKey: 'your-stream-key',
backendEndpoints: ['https://your-subdomain.example.com'],
auth: authClient,
user: { userId: 'user-1', displayName: 'Broadcaster' }
}), [authClient]);
const broadcastOptions = useMemo(() => ({ streamName: 'default' }), []);
const { call, status, error } = useCreateCall(authClient == null ? null : callOptions);
useBroadcast(call, mediaStreamController, broadcastOptions);
if (status === 'error') {
return <div>Could not start the call: {String(error)}</div>;
}
return (
<MediaStreamControllerAPIProvider mediaStreamController={mediaStreamController}>
<PlayerAPIProvider player={previewPlayer}>
<div>
<h1>My First Livestream</h1>
<Video /> {/* Camera preview */}
{call != null && <p>Call ID: <code>{call.id}</code></p>}
</div>
</PlayerAPIProvider>
</MediaStreamControllerAPIProvider>
);
}
useCallControls?Earlier versions of this guide imported a useCallControls hook from the SDK. The SDK does not
export one — it is a helper defined inside the demo app, so that import could never resolve. Start
and stop are driven by useCreateCall and useBroadcast instead, as above. There are no ready-made
buttons: build your own from the lifecycle functions those two hooks return — start and dispose
from useCreateCall, start and stop from useBroadcast.
4. Load it client-side only
Import the component with next/dynamic and ssr: false so Next.js never tries to render it on the server.
- App Router
- Pages Router
import dynamic from 'next/dynamic';
// ssr: false keeps the WebRTC/browser-only SDK off the server.
const Broadcaster = dynamic(() => import('../../components/Broadcaster'), {
ssr: false,
loading: () => <p>Loading…</p>
});
export default function BroadcastPage() {
return <Broadcaster />;
}
import dynamic from 'next/dynamic';
// ssr: false keeps the WebRTC/browser-only SDK off the server.
const Broadcaster = dynamic(() => import('../components/Broadcaster'), {
ssr: false,
loading: () => <p>Loading…</p>
});
export default function BroadcastPage() {
return <Broadcaster />;
}
Run npm run dev and open /broadcast — you'll see your camera preview and, once the call connects,
the call ID to hand to your viewer.
5. Add a viewer
A viewer follows the exact same pattern: build the component with the React viewer code, then load it through dynamic(..., { ssr: false }). Reuse the Viewer component from the React guide and wire it into a page the same way as above.
Next steps
- Browse the generated React API reference — Next.js uses the same package.
- See the Core API reference for the underlying client.
- Compare with the plain React getting started guide.