-
-
Notifications
You must be signed in to change notification settings - Fork 32.3k
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
Improve Next.js support #34905
Comments
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
There have been some movement on emotion's side for supporting it in I would appreciate feedback if someone wants to try it. I personally want to try this on the blog page in the https://mui.com site to verify that everything works. I will create an example project based on the stackblitz later this week. |
@mnajdova That's a great news! I hope some day we can use mui in app dir for real :) EDIT: Not sure if that helps in any way, maybe there is just a problem in that layout package but I thought I will share it anyway. |
After doing some more investigation, I noticed that not all Material UI components can be render as server components. I was lucky in the example that the |
Based on emotion-js/emotion#2928 (comment)
Looks like the best way forward is to add the "use client" directive to all Material UI components, at least until emotion supports server components. |
You don't have to add it to all the client components (although that's certainly the easiest solution here). If you have a set of completely headless components that don't rely on Emotion (nor on Styled-Components or other CSS-in-JS libs) then, to the best of my current understanding, you don't have to add that directive there. Server Components were designed in a way that is at fundamental odds with CSS-in-JS. So don't expect Emotion (or other popular CSS-in-JS libs) to introduce support for them. They just don't allow us to integrate with them anyhow. However, that doesn't mean that you can't SSR client components using Emotion. The initial HTML response from the server can freely use the rendered client components. The problem is only when it comes to "server component (re)fetches" (where I'm not even exactly sure how to trigger them, although Next.js probably does those on navigation or smth). You can still do this: function ServerComponent({ id }) {
const data = use(fetchData(id))
return <ClientComponent data={data} />
} Basically, with server components, you might want to move your data-loading concerns out of your client components. That's it. Note that server components are also unique as they support using async/await - so I expect that many people will want to split those concerns anyway (regardless of the fact if they are using CSS-in-JS or not). Of course, full support of server components would be neat and would make things easier for consumers - and would only require "splitting" if you really want to use |
I've started experimenting with this using a large app at work and there is an initial FOUC before the styles are applied which is proving tricky to debug. I don't see this on the Stackblitz example shared above but I'll see if I can provide an example, although it may be something the |
I can't address something that I can't debug 😉 If you provide a repro case then I will happily jump onto it |
Totally 👍 MUI Base components that don’t have any interactions could be server components. All Material UI components anyway load emotion, my comment was referring to them.
100% agree with this. I think the misconception comes from the difference that using plain CSS would allow you do convert the UI components too. |
Hey @Andarist @mnajdova here's a repo that shows the FOUC: https://github.com/robcaldecott/nextjs-mui-app-folder It's a single page with I also see the following console error which may be relevant:
I am using the |
Yeah, this is very well put. It's true that some components with "plain css" can be rendered using server components but the majority of them just can't. From my PoV... I wouldn't like to bother thinking in those terms when writing components in the first place. It's creating a mental overhead - "can I use styles in this server component?". It's much easier to just "forbid" this in the code and make the distinction clear (even with a lint rule or something). Having to restructure your server component with plain CSS just because you want to add some interactivity would also be a chore - it's just, IMHO, easier to start with an explicit split between those concerns and leave server components as something without styles at all. @robcaldecott this was an interesting case to investigate! You need to add an explicit diff --git a/app/layout.tsx b/app/layout.tsx
index 9c052a8..68bb86c 100644
--- a/app/layout.tsx
+++ b/app/layout.tsx
@@ -4,6 +4,7 @@ import EmotionRootStyleRegistry from "./EmotionRootStyleRegistry";
export default function RootLayout({ children }: { children: ReactNode }) {
return (
<html>
+ <head></head>
<body>
<EmotionRootStyleRegistry>{children}</EmotionRootStyleRegistry>
</body> |
@Andarist OMG thank you so much! I thought the original example had left that in by mistake, ha! |
### Update We removed the `<head>` element checking for root layout in #41621. Since we also need `<head>` for preload in the future, and also css-in-js will require that. We're adding back the `head` element checking to make sure user always provide valid root layout including it. ### Issue An issue was reported [here](mui/material-ui#34905 (comment)) that the Emotion/MUI site was suffering from FOUC. After an inspection, I noticed that the SSRed HTML didn't contain the inserted styles at all - despite them being inserted through `useServerInsertedHTML`. I managed to debug it down and discovered that their layout was missing `<head></head>` and thus the stream transformer skipped the insertion altogether cause of this check: https://github.com/vercel/next.js/blob/fbc98abab31a54dbc2b6c88a064b579a10f34871/packages/next/server/node-web-streams-helper.ts#L177-L183 I've figured that at the very least we could surface this as a console error in development to nudge the user to fix the missing `<head/>` cc @huozhi Co-authored-by: Jiachi Liu <[email protected]>
|
@garronej You link navigates to a 404 page. Url was encoded and hash was replaced ;) |
@barthicus, would you mind creating a code sandbox for the same? I have used the same example mentioned in the document but couldn't SSR the MUI component. I'm still getting the same error:
Here is the sandbox for the same: https://codesandbox.io/s/white-meadow-ft6ok7?file=/app/layout.tsx |
@ayushrajniwal-jtg There you go, You can't use providers in server components: https://beta.nextjs.org/docs/rendering/server-and-client-components#rendering-third-party-context-providers-in-server-components |
Thanks for looking into it @garronej. However, the playground is not working either. Getting the same error as mentioned above
|
@ayushrajniwal-jtg there you go a working demo: https://github.com/garronej/mui-next-appdir-demo Screen.Recording.2022-12-23.at.12.05.46.mov |
I want to use this However, I tried running your demo and ran into an issue. I see it load initially then it runs into an error when trying to render the client components: I'm using node |
Hi @francismanansala, I'm running it on MacOS with node v16.15.1 |
@mwskwong yes, we are about to post the RFC for it today/next week. |
This comment was marked as off-topic.
This comment was marked as off-topic.
Moving this umbrella issue out of v6 as it includes both package and documentation issues. We'll review each issue separately to decide if it's included in the v6 scope. |
Does anyone have a working example of how to integrate NextJS' I haven't found an official example. The simple forward ref example I have been using neither supports the props exposed by NextJS' import { createTheme } from '@mui/material/styles';
import NextLink from 'next/link';
import { forwardRef } from 'react';
const LinkBehaviour = forwardRef(function LinkBehaviour(props, ref) {
return <NextLink ref={ref} prefetch={false} {...props} />;
});
const theme = createTheme({
components: {
MuiLink: {
defaultProps: {
component: LinkBehaviour
}
},
MuiButtonBase: {
defaultProps: {
LinkComponent: LinkBehaviour
}
}
}
}); |
@sgoodrow if it's appdir router, have you tried the following? <Link component={NextLink} href="/" underline="hover" color="white">Home</Link> |
Not exactly, but I did set that as the default component for the Is there no way to do this via the theme? |
Summary 💡
This issue will serve as an umbrella for all issues related to Next.js app router integration. It will be easier to have an overview of all the problems in one place.
Done
next/font
set up steps #38082Opportunities to make it even better
@mui/joy/node
bundle is included in the client bundle when Joy UI component is being imported into a RSC #37934legacyBehavior={true}
[docs] Update docs related to using Next.js's Link with Material UI #38092@mui/material-nextjs
material-ui/docs/src/modules/components/AppFrame.js
Lines 40 to 46 in d37dd5c
The text was updated successfully, but these errors were encountered: