Using a newer version? See the updated quickstart for Next.js 13+.
1. Install LiveKit SDK
Install the necessary LiveKit SDKs for the web frontend and for the server APIs:
yarn add livekit-server-sdk @livekit/components-react @livekit/components-styles
2. Keys and Configuration
To start, your app needs an LiveKit API key and secret, as well as your LiveKit project URL.
Create a new file at .env.development.local
with the following content. Do not commit this file!
LIVEKIT_API_KEY=<your API Key>LIVEKIT_API_SECRET=<your API Secret>NEXT_PUBLIC_LIVEKIT_URL=<your LiveKit server URL>
3. Create token endpoint
Create a new file at /api/get_lk_token.ts
with the following content:
import { NextApiRequest, NextApiResponse } from 'next';import { AccessToken } from 'livekit-server-sdk';// Do not cache endpoint result// See https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config#revalidateexport const revalidate = 0;export default async function handler(req: NextApiRequest, res: NextApiResponse) {const room = req.query.room as string;const username = req.query.username as string;if (req.method !== 'GET') {return res.status(400).json({ error: 'Invalid method' });} else if (!room) {return res.status(400).json({ error: 'Missing "room" query parameter' });} else if (!username) {return res.status(400).json({ error: 'Missing "username" query parameter' });}const apiKey = process.env.LIVEKIT_API_KEY;const apiSecret = process.env.LIVEKIT_API_SECRET;const wsUrl = process.env.NEXT_PUBLIC_LIVEKIT_URL;if (!apiKey || !apiSecret || !wsUrl) {return res.status(500).json({ error: 'Server misconfigured' });}const at = new AccessToken(apiKey, apiSecret, { identity: username });at.addGrant({ room, roomJoin: true, canPublish: true, canSubscribe: true });res.setHeader({ 'Cache-Control': 'no-store' });res.status(200).json({ token: await at.toJwt() });}
4. Make a page in your web app
Make a new file at /pages/room.tsx
with the following content:
import {ControlBar,GridLayout,ParticipantTile,RoomAudioRenderer,useTracks,RoomContext,} from '@livekit/components-react';import { Room, Track } from 'livekit-client';import '@livekit/components-styles';import { useEffect, useState } from 'react';export default () => {// TODO: get user input for room and nameconst room = 'quickstart-room';const name = 'quickstart-user';const [token, setToken] = useState('');const [roomInstance] = useState(() => new Room({// Optimize video quality for each participant's screenadaptiveStream: true,// Enable automatic audio/video quality optimizationdynacast: true,}));useEffect(() => {let mounted = true;(async () => {try {const resp = await fetch(`/api/get_lk_token?room=${room}&username=${name}`);const data = await resp.json();if (!mounted) return;setToken(data.token);if (data.token) {await roomInstance.connect(process.env.NEXT_PUBLIC_LIVEKIT_URL, data.token);}} catch (e) {console.error(e);}})();return () => {mounted = false;roomInstance.disconnect();};}, [roomInstance]);if (token === '') {return <div>Getting token...</div>;}return (<RoomContext.Provider value={roomInstance}><div data-lk-theme="default" style={{ height: '100dvh' }}>{/* Your custom component with basic video conferencing functionality. */}<MyVideoConference />{/* The RoomAudioRenderer takes care of room-wide audio for you. */}<RoomAudioRenderer />{/* Controls for the user to start/stop audio, video, and screen share tracks */}<ControlBar /></div></RoomContext.Provider>);};function MyVideoConference() {// `useTracks` returns all camera and screen share tracks. If a user// joins without a published camera track, a placeholder track is returned.const tracks = useTracks([{ source: Track.Source.Camera, withPlaceholder: true },{ source: Track.Source.ScreenShare, withPlaceholder: false },],{ onlySubscribed: false },);return (<GridLayout tracks={tracks} style={{ height: 'calc(100vh - var(--lk-control-bar-height))' }}>{/* The GridLayout accepts zero or one child. The child is usedas a template to render all passed in tracks. */}<ParticipantTile /></GridLayout>);}
5. Load the page and connect
Start your server with:
yarn dev
And then open localhost:8000/room
in your browser.
6. Next Steps
If you're looking to dive deeper into building your LiveKit app with React, check out the React Components reference section. There you'll find a comprehensive list of available components and React hooks, along with examples of how to use them. This is a great resource for building more complex and advanced apps. Happy coding!