├── .gitignore
├── .idea
├── .gitignore
├── misc.xml
├── modules.xml
└── nextjs-material-ui.iml
├── README.md
├── package.json
├── pages
├── _app.js
├── _document.js
├── about.js
└── index.js
└── src
├── Copyright.js
├── Link.js
├── ProTip.js
└── theme.js
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 |
6 | # misc
7 | .DS_Store
8 | .env.local
9 | .env.development.local
10 | .env.test.local
11 | .env.production.local
12 |
13 | npm-debug.log*
14 | yarn-debug.log*
15 | yarn-error.log*
16 |
17 | # Next.js
18 | /.next
19 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Editor-based HTTP Client requests
5 | /httpRequests/
6 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/nextjs-material-ui.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Next.js example
2 |
3 | ## How to use
4 |
5 | Download the example [or clone the repo](https://github.com/mui-org/material-ui):
6 |
7 | ```sh
8 | curl https://codeload.github.com/mui-org/material-ui/tar.gz/master | tar -xz --strip=2 material-ui-master/examples/nextjs
9 | cd nextjs
10 | ```
11 |
12 | Install it and run:
13 |
14 | ```sh
15 | npm install
16 | npm run dev
17 | ```
18 |
19 | or:
20 |
21 | [](https://codesandbox.io/s/github/mui-org/material-ui/tree/master/examples/nextjs)
22 |
23 | ## The idea behind the example
24 |
25 | [Next.js](https://github.com/zeit/next.js) is a framework for server-rendered React apps.
26 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "nextjs",
3 | "version": "4.0.0",
4 | "private": true,
5 | "dependencies": {
6 | "@material-ui/core": "latest",
7 | "clsx": "latest",
8 | "next": "latest",
9 | "prop-types": "latest",
10 | "react": "latest",
11 | "react-dom": "latest"
12 | },
13 | "scripts": {
14 | "dev": "next",
15 | "build": "next build",
16 | "start": "next start",
17 | "post-update": "echo \"codesandbox preview only, need an update\" && yarn upgrade --latest"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/pages/_app.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import Head from 'next/head';
4 | import { ThemeProvider } from '@material-ui/core/styles';
5 | import CssBaseline from '@material-ui/core/CssBaseline';
6 | import theme from '../src/theme';
7 |
8 | export default function MyApp(props) {
9 | const { Component, pageProps } = props;
10 |
11 | React.useEffect(() => {
12 | // Remove the server-side injected CSS.
13 | const jssStyles = document.querySelector('#jss-server-side');
14 | if (jssStyles) {
15 | jssStyles.parentElement.removeChild(jssStyles);
16 | }
17 | }, []);
18 |
19 | return (
20 |
21 |
22 | My page
23 |
24 |
25 |
26 | {/* CssBaseline kickstart an elegant, consistent, and simple baseline to build upon. */}
27 |
28 |
29 |
30 |
31 | );
32 | }
33 |
34 | MyApp.propTypes = {
35 | Component: PropTypes.elementType.isRequired,
36 | pageProps: PropTypes.object.isRequired,
37 | };
38 |
--------------------------------------------------------------------------------
/pages/_document.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Document, { Html, Head, Main, NextScript } from 'next/document';
3 | import { ServerStyleSheets } from '@material-ui/core/styles';
4 | import theme from '../src/theme';
5 |
6 | export default class MyDocument extends Document {
7 | render() {
8 | return (
9 |
10 |
11 | {/* PWA primary color */}
12 |
13 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | );
24 | }
25 | }
26 |
27 | // `getInitialProps` belongs to `_document` (instead of `_app`),
28 | // it's compatible with server-side generation (SSG).
29 | MyDocument.getInitialProps = async (ctx) => {
30 | // Resolution order
31 | //
32 | // On the server:
33 | // 1. app.getInitialProps
34 | // 2. page.getInitialProps
35 | // 3. document.getInitialProps
36 | // 4. app.render
37 | // 5. page.render
38 | // 6. document.render
39 | //
40 | // On the server with error:
41 | // 1. document.getInitialProps
42 | // 2. app.render
43 | // 3. page.render
44 | // 4. document.render
45 | //
46 | // On the client
47 | // 1. app.getInitialProps
48 | // 2. page.getInitialProps
49 | // 3. app.render
50 | // 4. page.render
51 |
52 | // Render app and page and get the context of the page with collected side effects.
53 | const sheets = new ServerStyleSheets();
54 | const originalRenderPage = ctx.renderPage;
55 |
56 | ctx.renderPage = () =>
57 | originalRenderPage({
58 | enhanceApp: (App) => (props) => sheets.collect(),
59 | });
60 |
61 | const initialProps = await Document.getInitialProps(ctx);
62 |
63 | return {
64 | ...initialProps,
65 | // Styles fragment is rendered after the app and page rendering finish.
66 | styles: [...React.Children.toArray(initialProps.styles), sheets.getStyleElement()],
67 | };
68 | };
69 |
--------------------------------------------------------------------------------
/pages/about.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Container from '@material-ui/core/Container';
3 | import Typography from '@material-ui/core/Typography';
4 | import Box from '@material-ui/core/Box';
5 | import Button from '@material-ui/core/Button';
6 | import ProTip from '../src/ProTip';
7 | import Link from '../src/Link';
8 | import Copyright from '../src/Copyright';
9 |
10 | export default function About() {
11 | return (
12 |
13 |
14 |
15 | Next.js example
16 |
17 |
20 |
21 |
22 |
23 |
24 | );
25 | }
26 |
--------------------------------------------------------------------------------
/pages/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Container from '@material-ui/core/Container';
3 | import Typography from '@material-ui/core/Typography';
4 | import Box from '@material-ui/core/Box';
5 | import ProTip from '../src/ProTip';
6 | import Link from '../src/Link';
7 | import Copyright from '../src/Copyright';
8 |
9 | export default function Index() {
10 | return (
11 |
12 |
13 |
14 | Next.js example
15 |
16 |
17 | Go to the about page
18 |
19 |
20 |
21 |
22 |
23 | );
24 | }
25 |
--------------------------------------------------------------------------------
/src/Copyright.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Typography from '@material-ui/core/Typography';
3 | import MuiLink from '@material-ui/core/Link';
4 |
5 | export default function Copyright() {
6 | return (
7 |
8 | {'Copyright © '}
9 |
10 | Your Website
11 | {' '}
12 | {new Date().getFullYear()}
13 | {'.'}
14 |
15 | );
16 | }
17 |
--------------------------------------------------------------------------------
/src/Link.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable jsx-a11y/anchor-has-content */
2 | import React from 'react';
3 | import PropTypes from 'prop-types';
4 | import clsx from 'clsx';
5 | import { useRouter } from 'next/router';
6 | import NextLink from 'next/link';
7 | import MuiLink from '@material-ui/core/Link';
8 |
9 | const NextComposed = React.forwardRef(function NextComposed(props, ref) {
10 | const { as, href, ...other } = props;
11 |
12 | return (
13 |
14 |
15 |
16 | );
17 | });
18 |
19 | NextComposed.propTypes = {
20 | as: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
21 | href: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
22 | prefetch: PropTypes.bool,
23 | };
24 |
25 | // A styled version of the Next.js Link component:
26 | // https://nextjs.org/docs/#with-link
27 | function Link(props) {
28 | const {
29 | href,
30 | activeClassName = 'active',
31 | className: classNameProps,
32 | innerRef,
33 | naked,
34 | ...other
35 | } = props;
36 |
37 | const router = useRouter();
38 | const pathname = typeof href === 'string' ? href : href.pathname;
39 | const className = clsx(classNameProps, {
40 | [activeClassName]: router.pathname === pathname && activeClassName,
41 | });
42 |
43 | if (naked) {
44 | return ;
45 | }
46 |
47 | return (
48 |
49 | );
50 | }
51 |
52 | Link.propTypes = {
53 | activeClassName: PropTypes.string,
54 | as: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
55 | className: PropTypes.string,
56 | href: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
57 | innerRef: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
58 | naked: PropTypes.bool,
59 | onClick: PropTypes.func,
60 | prefetch: PropTypes.bool,
61 | };
62 |
63 | export default React.forwardRef((props, ref) => );
64 |
--------------------------------------------------------------------------------
/src/ProTip.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { makeStyles } from '@material-ui/core/styles';
3 | import Link from '@material-ui/core/Link';
4 | import SvgIcon from '@material-ui/core/SvgIcon';
5 | import Typography from '@material-ui/core/Typography';
6 |
7 | function LightBulbIcon(props) {
8 | return (
9 |
10 |
11 |
12 | );
13 | }
14 |
15 | const useStyles = makeStyles((theme) => ({
16 | root: {
17 | margin: theme.spacing(6, 0, 3),
18 | },
19 | lightBulb: {
20 | verticalAlign: 'middle',
21 | marginRight: theme.spacing(1),
22 | },
23 | }));
24 |
25 | export default function ProTip() {
26 | const classes = useStyles();
27 | return (
28 |
29 |
30 | Pro tip: See more{' '}
31 | templates on the
32 | Material-UI documentation.
33 |
34 | );
35 | }
36 |
--------------------------------------------------------------------------------
/src/theme.js:
--------------------------------------------------------------------------------
1 | import { createMuiTheme } from '@material-ui/core/styles';
2 | import { red } from '@material-ui/core/colors';
3 |
4 | // Create a theme instance.
5 | const theme = createMuiTheme({
6 | palette: {
7 | primary: {
8 | main: '#556cd6',
9 | },
10 | secondary: {
11 | main: '#19857b',
12 | },
13 | error: {
14 | main: red.A400,
15 | },
16 | background: {
17 | default: '#fff',
18 | },
19 | },
20 | });
21 |
22 | export default theme;
23 |
--------------------------------------------------------------------------------