Skip to content

fix: enable multi-user chat with unique client IDs and message styling#16

Merged
rainbowFi merged 6 commits into
mainfrom
fix/multi-user-chat
Apr 22, 2026
Merged

fix: enable multi-user chat with unique client IDs and message styling#16
rainbowFi merged 6 commits into
mainfrom
fix/multi-user-chat

Conversation

@rainbowFi

@rainbowFi rainbowFi commented Apr 16, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Replaced hardcoded clientId: 'ably-nextjs-demo' in the token endpoint with a randomly generated ID per browser session so each tab gets a unique Ably identity
  • Update authentication code to use recommended JWT approach
  • Added sent vs received message styling in ChatBox: your messages appear right-aligned in blue, others' appear left-aligned in grey

Builds on #15. See BUG-BRIEFING.md for the full diagnosis.

Test plan

  • Open http://localhost:3000 in two browser tabs
  • Send a message from each tab
  • Confirm your own messages appear right-aligned (blue) and the other tab's messages appear left-aligned (grey)
  • Confirm message history loads correctly on page refresh

🤖 Generated with Claude Code

@vercel

vercel Bot commented Apr 16, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
next-js-chat-app Ready Ready Preview, Comment Apr 22, 2026 7:14am

Request Review

@splindsay-92 splindsay-92 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just some minor changes here please :)

Comment thread app/api/route.js Outdated
const tokenRequestData = await client.auth.createTokenRequest({
clientId: 'ably-nextjs-demo',
});
const tokenRequestData = await client.auth.createTokenRequest({ clientId });

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should actually avoid ably token generation, instead preferring JWTs. As an example, see

Comment thread components/Chat.jsx

useEffect(() => {
const realtimeClient = new Ably.Realtime({ authUrl: '/api' });
const clientId = `ably-chat-demo-user-${Math.random().toString(36).substring(2, 10)}`;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR description suggests clientId's are generated with crypto.randomUUID(), can we update the PR description please :)

rainbowFi and others added 5 commits April 21, 2026 09:50
…message styling

Generate a unique client ID per token request instead of using a hardcoded
value, so each browser tab gets its own identity. Distinguish sent vs
received messages in the UI by comparing message.clientId against the
current user's client ID and applying right-aligned styling for sent messages.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
useChatClient() now returns { clientId } instead of the full client
object.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Previously the auth route minted a new clientId via crypto.randomUUID()
on every token request, so a user's identity changed on every token
refresh and their own messages stopped being recognised as theirs.

The browser now generates a clientId once per mount and passes it to
/api as a query param. Matches the pattern used in nextjs-chat-app-netlify.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Lost inadvertently in 98d1291. The comment documents why the route
opts out of Vercel's caching.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace createTokenRequest with signed JWTs as recommended by the Chat
SDK. The route handler now signs claims with HS256 and returns
application/jwt, and the client uses authCallback to consume it.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

@splindsay-92 splindsay-92 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just one tiny comment, should be a quick fix :)

Comment thread app/api/route.js Outdated

const now = Math.floor(Date.now() / 1000);
const claims = {
'x-ably-capability': JSON.stringify({ '*': ['*'] }),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, can we set this to something like ({ 'chat:*': ['*'] }) please

Narrow the token capability from '*' (all channels) to 'chat-demo:*'
which matches the Chat SDK's channel naming pattern for this room.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
rainbowFi added a commit to ably-labs/nextjs-chat-app-netlify that referenced this pull request Apr 22, 2026
Switch from Ably SDK's createTokenRequest to direct JWT signing using
the jsonwebtoken library, matching the pattern in ably-labs/NextJS-chat-app#16
and the Chat SDK docs.

- Auth function now signs a JWT with the Ably key secret instead of
  instantiating an Ably.Rest client
- Chat component uses authCallback instead of authUrl to pass the
  JWT token string directly to the Ably realtime client

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@rainbowFi rainbowFi requested a review from splindsay-92 April 22, 2026 07:28
Base automatically changed from fix/nextjs-patterns-ait-540 to main April 22, 2026 07:30

@splindsay-92 splindsay-92 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@rainbowFi rainbowFi merged commit af26af0 into main Apr 22, 2026
3 checks passed
@rainbowFi rainbowFi deleted the fix/multi-user-chat branch April 22, 2026 11:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants