OvidijusParsiunas / deep-chat

Fully customizable AI chatbot component for your website
https://deepchat.dev
MIT License
1.27k stars 176 forks source link

Next.js "app router" version #33

Closed mcapodici closed 7 months ago

mcapodici commented 8 months ago

It would be cool to have a second Next.js example for the new app router.

One thing the app router solves is the need for this:

  // Need to import the component dynamically as it uses the 'window' property.
  // If you have found a better way of adding the component in next, please create a new issue ticket so we can update the example!
  const DeepChat = dynamic(() => import('deep-chat-react').then((mod) => mod.DeepChat), {
    ssr: false,
  });

Instead you can create a new file call DeepChat.tsx like this:

"use client"

export { DeepChat } from 'deep-chat-react';

I have locally converted one of the API calls to use the app router for a personal project.

I am happy to help or do a PR for the whole thing.

OvidijusParsiunas commented 8 months ago

Hi @mcapodici. Thankyou very much for this information!

I think a NextJs App Router example would be a great addition to this project.

My only question is - how different would the new App Router project be to the existing Page Router example? The reason why I am asking this is because all of the example server projects in this repo contain extensive code examples on how to connect to a variety of AI APIs etc. (for ease of integration and consistency purposes) and if the new App Router's code is minimal, I would lean on editing the existing example instead of creating an additional one; where devs would have the ability to choose between alternative client code files or uncomment code in one file for their Router preference.

I am more than eager to implement this but since you raised the issue I can let you have a go at it first to see what is possible and can then perhaps add changes myself to your PR. Otherwise if you are busy I can do this later myself. Let me know what you prefer.

Thanks!

mcapodici commented 8 months ago

@OvidijusParsiunas ,

You have a good point there. And having a second Next.js project is just more maintenance work.

I think it is possible to have an app that uses both the pages and app routers in one project. I have read on Reddit that you can do this, some people don't recommend it, I don't remember why, but since this is not a production app and just an example I don't see a problem.

What could be done is add a single additional example (e.g. one of the chat bots, maybe the OpenAI one) that uses the app router. From that, people can deduce how to use this in general for the app router.

mcapodici commented 8 months ago

If you are going to do it, then I might as well give you some of what I learned. I would give you the code but I have customized it a lot now, so it wouldn't fit but basically:

Back End

Front End

  const DeepChat = dynamic(() => import('deep-chat-react').then((mod) => mod.DeepChat), {
    ssr: false,
  });
OvidijusParsiunas commented 8 months ago

Thankyou for sharing this information!

This is much more involved than I anticipated at first glance. If all the routes would need to be written differently for the App Router then I would probably vouch for creating a separate project instead to not overcomplicate things :/ I'm currently working on a couple of features for the component as we speak so I won't be able to get to this at the moment, but I will pick it up as soon as they are finished (alternatively you can always raise a PR if you want to).

On the topic of Nextjs, I am also going to try implementing a Nextjs specific npm package called deep-chat-next. It will be a little experimental, but I will explore the possibility of utilizing the new APIs for mixing concerns to encapsulate the UI code and the Server code in the same package. This should allow the API keys to be injected safely from the environment variables into the preset edge functions and the user will only ever need to care about managing the UI side of things. The following segment of this video got me interested about it.

mcapodici commented 7 months ago

By the way, although it "works" in terms of the UI working, I get errors in the Next.js console when using this:

"use client"

export { DeepChat } from 'deep-chat-react';

So I went back to using dynamic again :-(

Errors are like this:

ReferenceError: navigator is not defined
    at __webpack_require__ (.next\server\webpack-runtime.js:33:43)
    at __webpack_require__ (.next\server\webpack-runtime.js:33:43)
    at eval (./src/components/DeepChat.tsx:5:73)
OvidijusParsiunas commented 7 months ago

Interesting, it appears the component is still being rendered in the server. I had a quick read at how are client components rendered and based on my understanding - the html is still pre-rendered?

I am no expert in NextJs, but if rendering behaviour is dependent on the parent website's architecture I would say it'd be best to recommend developers to use the dynamic import approach for now as it's more reliable.

Thankyou very much for this info @mcapodici!

I'll close this issue for now if you don't mind, but will be happy to re-open it if I or anyone else comes across a reliable way of using the App Router without the need for a dynamic component import.

Thankyou once again @mcapodici!