-
-
Notifications
You must be signed in to change notification settings - Fork 32.4k
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
[examples] Add Next.js 13 starter project #34983
Closed
Closed
Changes from 11 commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
d416262
[release] v5.10.12
mnajdova a4ac85f
Remove autogenerated text
mnajdova 9d0d4f3
Merge branch 'master' into release/5.10.12
mnajdova 7e1815a
Updated changelog
mnajdova 4a6bafb
Merge branch 'master' into release/5.10.12
mnajdova 1e556dc
Updated changelog
mnajdova bf55df5
Merge branch 'release/5.10.12' of https://github.com/mnajdova/materia…
mnajdova 257ec6b
[examples] Add Next.js 13 example
mnajdova dfe6378
prettier fixes
mnajdova 5e37a98
lint issues
mnajdova a43deca
Fix fonts & lint
mnajdova e31d2c8
Add missing import
mnajdova File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. | ||
|
||
# dependencies | ||
/node_modules | ||
/.pnp | ||
.pnp.js | ||
|
||
# testing | ||
/coverage | ||
|
||
# next.js | ||
/.next/ | ||
/out/ | ||
|
||
# production | ||
/build | ||
|
||
# misc | ||
.DS_Store | ||
*.pem | ||
|
||
# debug | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
|
||
# local env files | ||
.env.local | ||
.env.development.local | ||
.env.test.local | ||
.env.production.local | ||
|
||
# vercel | ||
.vercel |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
# Next.js example | ||
|
||
## How to use | ||
|
||
Download the example [or clone the repo](https://github.com/mui/material-ui): | ||
|
||
<!-- #default-branch-switch --> | ||
|
||
```sh | ||
curl https://codeload.github.com/mui/material-ui/tar.gz/master | tar -xz --strip=2 material-ui-master/examples/nextjs-13 | ||
cd nextjs | ||
``` | ||
|
||
Install it and run: | ||
|
||
```sh | ||
npm install | ||
npm run dev | ||
``` | ||
|
||
or: | ||
|
||
<!-- #default-branch-switch --> | ||
|
||
[![Edit on StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/mui/material-ui/tree/master/examples/nextjs-13) | ||
|
||
[![Edit on CodeSandbox](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/mui/material-ui/tree/master/examples/nextjs-13) | ||
|
||
## The idea behind the example | ||
|
||
The project uses [Next.js](https://github.com/vercel/next.js), which is a framework for server-rendered React apps. | ||
It includes `@mui/material` and its peer dependencies, including `emotion`, the default style engine in MUI v5. | ||
If you prefer, you can [use styled-components instead](https://mui.com/material-ui/guides/interoperability/#styled-components). | ||
This examples uses the new experimental features of Next.js 13 - the app directory and client components. | ||
|
||
## The link component | ||
|
||
The [example folder](https://github.com/mui/material-ui/tree/HEAD/examples/nextjs-with-typescript) provides an adapter for the use of [Next.js's Link component](https://nextjs.org/docs/api-reference/next/link) with MUI. | ||
More information [in the documentation](https://mui.com/material-ui/guides/routing/#next-js). | ||
|
||
## What's next? | ||
|
||
<!-- #default-branch-switch --> | ||
|
||
You now have a working example project. | ||
You can head back to the documentation, continuing browsing it from the [templates](https://mui.com/material-ui/getting-started/templates/) section. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
'use client'; | ||
|
||
import * as React from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import { CacheProvider } from '@emotion/react'; | ||
import { useServerInsertedHTML } from 'next/navigation'; | ||
import createEmotionCache from '../src/createEmotionCache'; | ||
|
||
export default function RootStyleRegistry({ children }) { | ||
const [cache] = React.useState(() => { | ||
const c = createEmotionCache(); | ||
c.compat = true; | ||
return c; | ||
}); | ||
|
||
useServerInsertedHTML(() => { | ||
return ( | ||
<style | ||
data-emotion={`${cache.key} ${Object.keys(cache.inserted).join(' ')}`} | ||
// eslint-disable-next-line react/no-danger | ||
dangerouslySetInnerHTML={{ | ||
__html: Object.values(cache.inserted).join(' '), | ||
}} | ||
/> | ||
); | ||
}); | ||
|
||
return <CacheProvider value={cache}>{children}</CacheProvider>; | ||
} | ||
|
||
RootStyleRegistry.propTypes = { | ||
children: PropTypes.node, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
'use client'; | ||
|
||
import * as React from 'react'; | ||
import RootStyleRegistry from './emotion'; | ||
import theme, { roboto } from '../src/theme'; | ||
import { ThemeProvider } from '@mui/material/styles'; | ||
import CssBaseline from '@mui/material/CssBaseline'; | ||
|
||
export default function RootLayout({ children }) { | ||
return ( | ||
<html lang="en" className={roboto.className}> | ||
<head> | ||
<meta name="emotion-insertion-point" content="" /> | ||
</head> | ||
<body> | ||
<RootStyleRegistry> | ||
<ThemeProvider theme={theme}> | ||
<CssBaseline /> | ||
{children} | ||
</ThemeProvider> | ||
</RootStyleRegistry> | ||
</body> | ||
</html> | ||
); | ||
} | ||
|
||
RootLayout.propTypes = { | ||
children: PropTypes.node, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
'use client'; | ||
|
||
import * as React from 'react'; | ||
import Container from '@mui/material/Container'; | ||
import Typography from '@mui/material/Typography'; | ||
import Box from '@mui/material/Box'; | ||
import Button from '@mui/material/Button'; | ||
import ProTip from '../../src/ProTip'; | ||
import Link from '../../src/Link'; | ||
import Copyright from '../../src/Copyright'; | ||
|
||
export default function About() { | ||
return ( | ||
<Container maxWidth="sm"> | ||
<Box sx={{ my: 4 }}> | ||
<Typography variant="h4" component="h1" gutterBottom> | ||
Next.js app page example | ||
</Typography> | ||
<Button variant="outlined" component={Link} noLinkStyle href="/"> | ||
Go to the main page | ||
</Button> | ||
<ProTip /> | ||
<Copyright /> | ||
</Box> | ||
</Container> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
module.exports = { | ||
reactStrictMode: true, | ||
experimental: { | ||
appDir: true, | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
{ | ||
"name": "nextjs-13", | ||
"private": true, | ||
"scripts": { | ||
"dev": "next dev", | ||
"build": "next build", | ||
"start": "next start", | ||
"lint": "next lint" | ||
}, | ||
"dependencies": { | ||
"@emotion/react": "latest", | ||
"@emotion/server": "latest", | ||
"@emotion/styled": "latest", | ||
"@mui/material": "latest", | ||
"@next/font": "latest", | ||
"next": "latest", | ||
"react": "latest", | ||
"react-dom": "latest" | ||
}, | ||
"devDependencies": { | ||
"eslint": "latest", | ||
"eslint-config-next": "latest" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import * as React from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import Head from 'next/head'; | ||
import { ThemeProvider } from '@mui/material/styles'; | ||
import CssBaseline from '@mui/material/CssBaseline'; | ||
import { CacheProvider } from '@emotion/react'; | ||
import theme from '../src/theme'; | ||
import createEmotionCache from '../src/createEmotionCache'; | ||
|
||
// Client-side cache, shared for the whole session of the user in the browser. | ||
const clientSideEmotionCache = createEmotionCache(); | ||
|
||
export default function MyApp(props) { | ||
const { Component, emotionCache = clientSideEmotionCache, pageProps } = props; | ||
|
||
return ( | ||
<CacheProvider value={emotionCache}> | ||
<Head> | ||
<meta name="viewport" content="initial-scale=1, width=device-width" /> | ||
</Head> | ||
<ThemeProvider theme={theme}> | ||
{/* CssBaseline kickstart an elegant, consistent, and simple baseline to build upon. */} | ||
<CssBaseline /> | ||
<Component {...pageProps} /> | ||
</ThemeProvider> | ||
</CacheProvider> | ||
); | ||
} | ||
|
||
MyApp.propTypes = { | ||
Component: PropTypes.elementType.isRequired, | ||
emotionCache: PropTypes.object, | ||
pageProps: PropTypes.object.isRequired, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import * as React from 'react'; | ||
import Document, { Html, Head, Main, NextScript } from 'next/document'; | ||
import createEmotionServer from '@emotion/server/create-instance'; | ||
import theme, { roboto } from '../src/theme'; | ||
import createEmotionCache from '../src/createEmotionCache'; | ||
|
||
export default class MyDocument extends Document { | ||
render() { | ||
return ( | ||
<Html lang="en" className={roboto.className}> | ||
<Head> | ||
{/* PWA primary color */} | ||
<meta name="theme-color" content={theme.palette.primary.main} /> | ||
<link rel="shortcut icon" href="/favicon.ico" /> | ||
<meta name="emotion-insertion-point" content="" /> | ||
{this.props.emotionStyleTags} | ||
</Head> | ||
<body> | ||
<Main /> | ||
<NextScript /> | ||
</body> | ||
</Html> | ||
); | ||
} | ||
} | ||
|
||
// `getInitialProps` belongs to `_document` (instead of `_app`), | ||
// it's compatible with static-site generation (SSG). | ||
MyDocument.getInitialProps = async (ctx) => { | ||
// Resolution order | ||
// | ||
// On the server: | ||
// 1. app.getInitialProps | ||
// 2. page.getInitialProps | ||
// 3. document.getInitialProps | ||
// 4. app.render | ||
// 5. page.render | ||
// 6. document.render | ||
// | ||
// On the server with error: | ||
// 1. document.getInitialProps | ||
// 2. app.render | ||
// 3. page.render | ||
// 4. document.render | ||
// | ||
// On the client | ||
// 1. app.getInitialProps | ||
// 2. page.getInitialProps | ||
// 3. app.render | ||
// 4. page.render | ||
|
||
const originalRenderPage = ctx.renderPage; | ||
|
||
// You can consider sharing the same Emotion cache between all the SSR requests to speed up performance. | ||
// However, be aware that it can have global side effects. | ||
const cache = createEmotionCache(); | ||
const { extractCriticalToChunks } = createEmotionServer(cache); | ||
|
||
ctx.renderPage = () => | ||
originalRenderPage({ | ||
enhanceApp: (App) => | ||
function EnhanceApp(props) { | ||
return <App emotionCache={cache} {...props} />; | ||
}, | ||
}); | ||
|
||
const initialProps = await Document.getInitialProps(ctx); | ||
// This is important. It prevents Emotion to render invalid HTML. | ||
// See https://github.com/mui/material-ui/issues/26561#issuecomment-855286153 | ||
const emotionStyles = extractCriticalToChunks(initialProps.html); | ||
const emotionStyleTags = emotionStyles.styles.map((style) => ( | ||
<style | ||
data-emotion={`${style.key} ${style.ids.join(' ')}`} | ||
key={style.key} | ||
// eslint-disable-next-line react/no-danger | ||
dangerouslySetInnerHTML={{ __html: style.css }} | ||
/> | ||
)); | ||
|
||
return { | ||
...initialProps, | ||
emotionStyleTags, | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import * as React from 'react'; | ||
import Container from '@mui/material/Container'; | ||
import Typography from '@mui/material/Typography'; | ||
import Box from '@mui/material/Box'; | ||
import Button from '@mui/material/Button'; | ||
import ProTip from '../src/ProTip'; | ||
import Link from '../src/Link'; | ||
import Copyright from '../src/Copyright'; | ||
|
||
export default function About() { | ||
return ( | ||
<Container maxWidth="sm"> | ||
<Box sx={{ my: 4 }}> | ||
<Typography variant="h4" component="h1" gutterBottom> | ||
Next.js example | ||
</Typography> | ||
<Button variant="outlined" component={Link} noLinkStyle href="/"> | ||
Go to the main page | ||
</Button> | ||
<ProTip /> | ||
<Copyright /> | ||
</Box> | ||
</Container> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction | ||
|
||
export default function handler(req, res) { | ||
res.status(200).json({ name: 'John Doe' }); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import * as React from 'react'; | ||
import Container from '@mui/material/Container'; | ||
import Typography from '@mui/material/Typography'; | ||
import Box from '@mui/material/Box'; | ||
import Stack from '@mui/material/Stack'; | ||
import ProTip from '../src/ProTip'; | ||
import Link from '../src/Link'; | ||
import Copyright from '../src/Copyright'; | ||
|
||
export default function Index() { | ||
return ( | ||
<Container maxWidth="sm"> | ||
<Box sx={{ my: 4 }}> | ||
<Typography variant="h4" component="h1" gutterBottom> | ||
Next.js example | ||
</Typography> | ||
<Stack gap={1}> | ||
<Link href="/about" color="secondary"> | ||
Go to the about page | ||
</Link> | ||
<Link href="/next13" color="secondary"> | ||
Go to an app page | ||
</Link> | ||
</Stack> | ||
<ProTip /> | ||
<Copyright /> | ||
</Box> | ||
</Container> | ||
); | ||
} |
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We shouldn't move forward with this PR before we are able to get rid of this directive. The layout shouldn't be a client component.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple of thoughts:
It could maybe make sense to provide a WIP demo. For example, to benefit from nested routes. Mantine as a WIP example mantinedev/mantine#2815 (comment). It could also resonate with https://mui.zendesk.com/agent/tickets/5883
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Exactly!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Per #34905 (comment), I think that it would be great to merge to have this demo, even if with
use client
. The /app folder has more to offer beyond server-side components.