Next.js Discord

Discord Forum

Implementing Chat

Unanswered
Broad-snouted Caiman posted this in #help-forum
Open in Discord
Broad-snouted CaimanOP
Hello, I've been working on this feature for the past 2 days and been going around in circles so wanted to see if anyone could give me some help/direction.

It's basically an AI chat which I have most of the functionality built out already but I wanted to make it where the landing page /chat would have an empty chat then when the user sends a message the page would route to /chat/[chatId] and then start streaming the response from the AI. ChatGBT does the same thing if you want a visual representation.

Relative tech: Using Nextjs 15 app router and useChat hook from '@ai-sdk/react'.

Issue: I can't get it working with streaming + chat history + page route. Usually I can get 2 of them working but not all 3 at the same time.

Due to message limit See next message for what I've tried.

4 Replies

Broad-snouted CaimanOP
## What I've tried
### Version 1 - hook

Using the hook in chat-view.tsx component that accepts the intial messages through a prop that was fetched on the server component. Then the hook handles the state and just using the params hook I check if we're on /chat or /chat/[chatId]. If on /chat/[chatId] just send the message & chatId to route, save user message on route and stream response and on stream finish it saves the response to the db.

But if on /chat then create a chat entry in db, return the id, then send message & chatId to same route. Then without awaiting just route.replace(/chat/[conversationId]).

The route changes causes the streaming to not be received for some reason which isn't fully clear to me. If I just comment out the route.replace(/chat/[conversationId]) then the streaming is received.

### Version 2 - context

The same hook (with small adjustments) now lives in a provider that wraps the layout.tsx children under /chat. Provider reads the route params then feeds it into the chat hook. Due to living in layout context it now lives between page routing so sending message in /chat will route to /chat/[chatId] and updating the state with user message and receive the stream.

But the issue is now is loading the initial messages. From my understanding its generally bad to fetch data in the layout so not sure how I'm suppose to feed the context/hook the intial messages from the db. So wasn't fully sure if its approach is the correct one.
I've found there's another way to share state across components here https://ai-sdk.dev/cookbook/next/use-shared-chat-context but I feel like I've been running in circles and a bit lost now so unsure if this is the correct way to go.
Western paper wasp
In the App Router, there is no equivalent of router.route. If the goal is to determine the page type, such as list or detail, at a shared layout level, the most robust approach is to rely on the route segment structure rather than string based path checks.
useSelectedLayoutSegments() is designed exactly for this purpose. It returns an array of segments like ['blog', 'slug'] or ['blog'], which scales naturally to multi level and catch-all routes without hardcoding paths
Broad-snouted CaimanOP
Sorry a bit confused as I used the useRouter hook for router.replace() from https://nextjs.org/docs/15/app/api-reference/functions/use-router.

Also the goal is to have an empty chat on /chat then when the user sends a message the path changes to /chat/[id] while also receiving a stream response from a route.ts.

Would useSelectedLayoutSegments() help in this instance? I looked at the documentation a bit and at first glance it doesn't seem like it but maybe I'm not fully understanding it.