PolynomialHQdocs
Guides

Production checklist

Review security, room design, connection states, and observability before you launch.

Use this checklist after your collaborative feature works locally. It focuses on the boundaries that are easy to miss during a prototype: who may join, what happens during a reconnect, and how your interface explains synchronization.

Protect your credentials

  • Keep POLYNOMIAL_SECRET_KEY in a server-only environment variable.
  • Never place the secret in a NEXT_PUBLIC_ variable or browser bundle.
  • Authenticate every request to your token endpoint.
  • Validate the requested room ID before authorizing it.
  • Return 401 when the user is signed out and 403 when they cannot access the room.
  • Issue the least-privileged role the current interface needs.

See Authentication for a complete endpoint.

Choose stable room IDs

A room ID should map cleanly to an authorization boundary in your application:

const roomId = `organization:${organizationId}:document:${documentId}`;

Do not put secrets, email addresses, or mutable display names in room IDs. A user should not gain access simply by guessing an ID; your token endpoint must check application permissions.

Separate ephemeral and durable state

Before shipping, review every collaborative value:

If the value…Put it in
disappears when a person leavesPresence
matters only at the instant it is sentBroadcasts
must survive reconnects or later visitsStorage

Keeping cursor coordinates out of storage prevents unnecessary persistence. Keeping document content out of presence prevents it from disappearing when the last editor leaves.

Design every connection state

Your interface should distinguish:

  • the first connection from a reconnect;
  • loading shared storage from a ready document;
  • synchronizing local changes from a saved document;
  • a temporary network interruption from a terminal error.

Use useRoomStatus(), useStorageStatus(), and useLostConnectionListener() to communicate those states. Avoid replacing the entire editor with a spinner during a brief reconnect; keep the last known document visible and show a small status message.

Gate write affordances on the role your token actually carries. A read token that attempts a broadcast or storage write receives a non-retryable forbidden error, which ends the connection rather than silently failing:

const { role } = useConnectionSnapshot();
const canEdit = role === "write" || role === "admin";

Exercise failure paths

Test these cases before release:

  1. Open the same room in two browser windows.
  2. Edit from both windows and confirm storage converges.
  3. Disable the network, make a change, and reconnect.
  4. Expire or invalidate a token and confirm the UI explains what happened.
  5. Request a room the current user cannot access.
  6. Reload while storage is still synchronizing.
  7. Close one window and confirm its presence disappears.

The reconnection guide includes listener and status examples.

Add useful diagnostics

Record enough context to investigate failures without logging private room contents:

  • application room ID;
  • user ID or an internal correlation ID;
  • connection status transitions;
  • the name of the failed management operation;
  • HTTP status from PolynomialApiError;
  • whether storage was loading, synchronizing, or synchronized.

Do not log tokens, secret keys, or full shared documents.

Watch the cost of chatty state

  • Throttle pointer-driven updatePresence() calls; one frame per pointer event is far more than a display can show.
  • Keep presence objects small — the whole object is sent on every update.
  • Batch related storage writes into one useMutation() call so they form one undo entry and one outgoing update.
  • Keep components that call room hooks small. Any room hook re-renders its component on every room event, including another user's cursor movement.

Final review

  • Token endpoint authenticates and authorizes every request.
  • Secret keys cannot reach the client bundle.
  • Room IDs are stable and map to application permissions.
  • Presence, broadcasts, and storage have distinct responsibilities.
  • Loading, reconnecting, synchronized, and error states are visible.
  • The feature works across two simultaneous sessions.
  • Network interruption and forbidden-room flows have been tested.
  • Logs contain identifiers and status—not credentials or user content.

On this page