Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support plan for Next.js app router #4069

Closed
meiyingqishi opened this issue Dec 16, 2023 · 12 comments
Closed

Support plan for Next.js app router #4069

meiyingqishi opened this issue Dec 16, 2023 · 12 comments
Labels

Comments

@meiyingqishi
Copy link

Is there a plan for Primer Design System components to support Next.js?

Using client-side components on Next.js has become quite painful.

@broccolinisoup
Copy link
Member

Hi @meiyingqishi 👋 We support Next.js and you can also access our internal example of Next.js to see how we set up the project and utilize Primer React components there. I'm going to go ahead and close this issue but please report back if you are having any specific issues with compatibility of our components with Next.js.

@broccolinisoup broccolinisoup closed this as not planned Won't fix, can't repro, duplicate, stale Dec 19, 2023
@meiyingqishi
Copy link
Author

Thank you for your response. @broccolinisoup

  • The example you provided is from a Next.js pages project. The current mainstream approach is using Next.js app projects, and the situation has changed. Components are now defaulting to server-side components, while the Primer Design System components are client-side components. When the implementation of a component involves the use of React's client-side APIs, such as hooks like useState, it will result in runtime errors (Server Error
    Error: createContext only works in Client Components. Add the "use client" directive at the top of the file to use it. Read more: https://nextjs.org/docs/messages/context-in-server-component).

  • The solution is to create a separate file and add 'use client' at the beginning of the file. Then, import this file in the page.tsx where it is used. However, creating a file like this for each component can become tedious and cumbersome.

  • I have reviewed the official documentation for the Primer Design System and did not find such a description or solution. My question is, do you have any plans to default to adding 'use client' in the component code files in the future? This would help alleviate many potential issues when using the components in the future.

@broccolinisoup
Copy link
Member

Hi @meiyingqishi 👋 Sorry when I read the issue, it didn't occur to me that you are talking about the new app router and React Server Components! I appreciate you provided details. I am chatting about this with my team to see how we can support it. I'll re-open the issue and rename it to "Support for Next.js app router" and you can subscribe to this issue to get updates on the support. Thanks for bringing it up and raising the issue.

@broccolinisoup broccolinisoup changed the title Support plan for Next.js ? Support plan for Next.js app router Dec 21, 2023
@broccolinisoup
Copy link
Member

Hi @meiyingqishi, we have another issue opened that dives deeper into the server components, feel free to have a read.

We also have a draft PR that addresses the issue you mentioned here.

@broccolinisoup broccolinisoup removed their assignment Jan 15, 2024
@joshblack
Copy link
Member

joshblack commented Jan 26, 2024

Hi there! 👋 Just wanted to follow up on this now that: #4128 is merged and available in v36.6.0

Components should be directly usable from @primer/react without requiring a 'use client' directive on the page or in components that call it when using app router with Next.js.

Going to close this out but feel free to leave a comment or provide any feedback if this is not working as expected!

@meiyingqishi
Copy link
Author

Thank you! It worked.

@peterbe
Copy link
Contributor

peterbe commented Feb 23, 2024

👋 Pardon the ignorance. But how does one use it though?

I followed https://nextjs.org/docs/app/building-your-application/styling/css-in-js#styled-components to get styled-components into my App router based Next.js v14 app.
(Note; those instructions are for styled-components@6 which I don't think @primer/react is compatible with)

Now that there's no longer an _app.tsx, where do you put the...

<ThemeProvider>
  <BaseStyles>
    ...
  </BaseStyles>
</ThemeProvider>

If someone has an example that combines @primer/react with next@14 that uses the App router, that would be great. I can't get it to work.

@meiyingqishi
Copy link
Author

meiyingqishi commented Feb 24, 2024

  1. Create and initialize the front-end project (primer-app) in terminal by pnpm: pn create next-app;
  2. Navigate to the directory: cd primer-app;
  3. Add dependencies: pn add @primer/react @primer/css @primer/octicons-react styled-components@^5;
  4. Import the project into vscode:code .;
  5. Modify layout.tsx:
import {
  BaseStyles,
  ThemeProvider,
} from "@primer/react";

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en">
      <body>
        <ThemeProvider>
          <BaseStyles>{children}</BaseStyles>
        </ThemeProvider>
      </body>
    </html>
  );
}
  1. Modify page.tsx:
import { 
  Button, 
} from "@primer/react";

export default function Home() {
  return (
    <main>
      <Button>Hello Button</Button>
    </main>
  );
}
  1. Run in vs code terminal: pn dev;
  2. View in browser: http://localhost:3000.

@peterbe
Copy link
Contributor

peterbe commented Feb 26, 2024

@meiyingqishi That doesn't solve the SSR problem. You get CSS-in-JS where the styling is injected at runtime, on the client.

You actually get pretty far with:

import StyledComponentsRegistry from "@/lib/registry";

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en">
      <body>
        <StyledComponentsRegistry>
          <ThemeProvider>
            <BaseStyles>
              <Inner>{children}</Inner>
            </BaseStyles>
          </ThemeProvider>
        </StyledComponentsRegistry>
      </body>
    </html>
  );
}

It works. But I get very strange warnings in development mode that I don't understand.

Full page with dev tools open

@joshblack
Copy link
Member

Hi there, @peterbe! We have an App Router example over at: https://github.com/primer/react/tree/main/examples/app-router if it's helpful (there is one change that needs to happen from #4307)

Would love to hear any feedback you have for that example and if it works or doesn't work for your use-case. I believe it should handle the SSR case for styles using the guide from Next.js but let me know if there are any issues!

@peterbe
Copy link
Contributor

peterbe commented Feb 27, 2024

Hi there, @peterbe! We have an App Router example over at: https://github.com/primer/react/tree/main/examples/app-router if it's helpful (there is one change that needs to happen from #4307)

Yay!

Now I can't even remember how I stumbled into https://github.com/primer/react/tree/main/examples/nextjs in the first place. Perhaps by a Google search??

Would love to hear any feedback you have for that example and if it works or doesn't work for your use-case. I believe it should handle the SSR case for styles using the guide from Next.js but let me know if there are any issues!

I got things working. SSR and all. Used your draft from #4307 and not a warning or error in sight.

What tripped me up, and can be seen in my screenshot above, was that the link on https://primer.style/react/getting-started#static-css-rendering to styled-components made me think I had to use styled-components@6 when it's styled-components@5 that is a must.

@meiyingqishi
Copy link
Author

Hi @joshblack ,

I accidentally tried the primer design system again and found there's still an issue. When using individual components like Button, there are no problems. However, errors occur when using composite components (involving child components, using a period), for example:

<ActionList>
    <ActionList.Item>Copy link</ActionList.Item>
    <ActionList.Item>Quote reply</ActionList.Item>
    <ActionList.Item>Edit comment</ActionList.Item>
</ActionList>

The issue lies with the ActionList.Item here. I've encountered this problem while using other components (such as react-bootstrap) as well. Their solution is to add additional components (for example: ActionListItem).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants