t3-oss / create-t3-turbo

Clean and simple starter repo using the T3 Stack along with Expo React Native
https://turbo.t3.gg
MIT License
4.65k stars 396 forks source link

Question: How does one transition the repo to NextJS 13 App Router and React Server Components? #299

Closed peterkibuchi closed 1 year ago

peterkibuchi commented 1 year ago

NextJS 13 App router is close to hitting stable, and I speculate they will announce it at the upcoming Vercel Launch Event (1st - 5th May). Transitioning to the App router and React Server Components introduces breaking changes to the way the repo is currently set up; I'd like to ask for the community's insight on how to address them.

I am currently working on an project built off this repo, with a NextJS "admin" app for creating content, and an Expo "consumer" mobile app for viewing it. I decided to use @shadcn/ui as my UI library (for NextJS), and as such was forced to transition to the App router and RSCs.

I quickly ran into some issues, the first one being that auth with NextAuth broke. I had assumed that since auth is implemented separately, simply moving the api folder from the pages to the app directory, then wrapping the app with SessionProvider (within app/layout.tsx) would be sufficient:

// app/layout.tsx
interface RootLayoutProps {
  children: React.ReactNode;
  session: Session;
}

const RootLayout = ({ children, session }: RootLayoutProps) => {
  return (
    <>
      <html lang="en" suppressHydrationWarning>
        <SessionProvider session={session}>
          <head />
          <body>
            <ThemeProvider>
              <div className="relative flex min-h-screen flex-col">
                <div className="flex-1">{children}</div>
              </div>
            </ThemeProvider>
          </body>
        </SessionProvider>
      </html>
    </>
  );
};

export default api.withTRPC(RootLayout);

but it wasn't. I got the following error:

error - .apps/nextjs/src/utils/api.ts
ReactServerComponentsError:
You're importing a component that needs useState. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default.

It appears @trpc/next uses useState under the hood and that's a No Bueno when it comes to RSCs. So I tried adding "use client" to the top of ./apps/nextjs/src/utils/api.ts, and got this error instead:

error - Error: Attempted to call withTRPC() from the server but withTRPC is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.
  1. How does one transition the current implementation of auth with NextAuth to RSCs?
  2. Will any other packages — aside from the NextJS app — be affected? e.g packages/auth
  3. At the very least is it possible to use tRPC routes, as they are set up right now, with RSCs?

Theo discussed a few ideas on how the transition might happen but a lot's still up in the air. I think it would be great if someone could come up with a Work In Progress PR of what the transition might look like. That way the community could chip in and we could all start to get a practical idea of what the T3 Monorepo will shape up to be. Theo has an experimental repo on what that could look like (though it's a single NextJS app running Clerk for auth) in case anyone's interested.

juliusmarminge commented 1 year ago
  1. For next-auth, see here: https://next-auth.js.org/configuration/nextjs#in-app-directory.

  2. @trpc/next is for the pages/ directory. It uses getInitialProps which isn't a thing in app/. We got a few experimental repos on the trpc org that showcase how you can use it both with and without react query: https://github.com/trpc/next-13, https://github.com/trpc/trpc/tree/next13-experiment/examples/next-13-starter

  3. Not many libs wrap their stuff in "use client" so you'll prob need some barrel exports that exports the component with a "use client" directive. See here for example: https://github.com/juliusmarminge/jumr.dev/blob/main/app/use-client.tsx

I decided to use @shadcn/ui as my UI library (for NextJS), and as such was forced to transition to the App router and RSCs.

I dont understand, why were you forced to use the app/ directory? shadcn/ui works in every react project..

I am working on another playground for a bunch of these new tech here, might give you some ideas.

peterkibuchi commented 1 year ago

This is incredibly useful, thank you.

I dont understand, why were you forced to use the app/ directory? shadcn/ui works in every react project.

Forced was perhaps the wrong choice of word. I wasn't implying they don't work with the pages directory. It's just that Shad uses the App router and RSCs on the shadcn/ui site, which I'm taking inspiration from, so I took it as an opportunity to start learning about them.

PS:

I am working on another playground for a bunch of these new tech here, might give you some ideas.

This is brilliant! It's exactly the kind of inspiration I was looking for. Thanks.

juliusmarminge commented 1 year ago

This repo now uses app dir