← Back to blog
INTEGRATION6 min read

Add Realtime to a React App with NoLag

HB
Henco Burger
July 28, 2026

React apps built with Vite, Create React App, or any other bundler can add realtime with a small custom hook. The hook owns the connection lifecycle so your components just render messages and call a publish function. This works in any React setup; if you are on Next.js, see the Next.js guide for the extra server-token step.

1. Install the SDK

npm install @nolag/js-sdk

2. A reusable hook

import { useEffect, useRef, useState, useCallback } from 'react'
import { NoLag } from '@nolag/js-sdk'

export function useNoLagRoom(token: string, app: string, roomName: string, topic: string) {
  const [messages, setMessages] = useState<any[]>([])
  const roomRef = useRef<any>(null)

  useEffect(() => {
    let client: ReturnType<typeof NoLag> | undefined
    let active = true

    ;(async () => {
      client = NoLag(token)
      await client.connect()
      if (!active) return

      const room = client.setApp(app).setRoom(roomName)
      room.subscribe(topic)
      room.on(topic, (data: any) => setMessages((m) => [...m, data]))
      roomRef.current = room
    })()

    return () => {
      active = false
      roomRef.current = null
      client?.disconnect?.()
    }
  }, [token, app, roomName, topic])

  const publish = useCallback(
    (data: unknown) => roomRef.current?.emit(topic, data),
    [topic],
  )

  return { messages, publish }
}

3. Use it in a component

function Chat({ token }: { token: string }) {
  const { messages, publish } = useNoLagRoom(token, 'chat', 'general', 'message')

  return (
    <div>
      <ul>
        {messages.map((m, i) => (
          <li key={i}>{m.text}</li>
        ))}
      </ul>
      <button onClick={() => publish({ text: 'Hello!' })}>Send</button>
    </div>
  )
}

Keep the token off the client

Fetch the token from your own backend rather than hardcoding a project key in the bundle. Any server can mint one by calling the NoLag REST API, and for browser sessions the production pattern is a short-lived client token scoped to what that user may do.

Why the cleanup matters

The hook's cleanup function runs on unmount and when the dependencies change. Clearing the room ref and disconnecting prevents duplicate subscriptions and leaked WebSocket connections as users navigate around your app.

Next steps