├── .babelrc ├── .gitignore ├── README.md ├── next.config.js ├── package.json ├── pages ├── _app.js ├── _document.js ├── about.js └── index.js └── src ├── Link.js └── theme.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["next/babel"], 3 | "plugins": [["styled-components", { "ssr": true }]] 4 | } 5 | -------------------------------------------------------------------------------- /.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 | /out -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Next.js with material-ui and styled-components 2 | 3 | ## How to use 4 | 5 | Download the example [or clone the repo](https://github.com/MarchWorks/nextjs-with-material-ui-styled-components): 6 | 7 | Install it and run: 8 | 9 | ```sh 10 | npm install 11 | npm run dev 12 | ``` 13 | -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | module.exports = {}; 2 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nextjs-with-material-ui-styled-components", 3 | "version": "1.0.0", 4 | "dependencies": { 5 | "@material-ui/core": "latest", 6 | "next": "latest", 7 | "prop-types": "latest", 8 | "react": "latest", 9 | "react-dom": "latest", 10 | "styled-components": "latest" 11 | }, 12 | "devDependencies": { 13 | "babel-plugin-styled-components": "latest" 14 | }, 15 | "scripts": { 16 | "dev": "next", 17 | "build": "next build", 18 | "start": "next start" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /pages/_app.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import App from 'next/app'; 3 | import Head from 'next/head'; 4 | import { ThemeProvider } from '@material-ui/styles'; 5 | import CssBaseline from '@material-ui/core/CssBaseline'; 6 | import theme from '../src/theme'; 7 | 8 | class MyApp extends App { 9 | componentDidMount() { 10 | // Remove the server-side injected CSS. 11 | const jssStyles = document.querySelector('#jss-server-side'); 12 | if (jssStyles) { 13 | jssStyles.parentNode.removeChild(jssStyles); 14 | } 15 | } 16 | 17 | render() { 18 | const { Component, pageProps } = this.props; 19 | 20 | return ( 21 | <> 22 | 23 | My page 24 | 28 | 29 | 30 | {/* CssBaseline kickstart an elegant, consistent, and simple baseline to build upon. */} 31 | 32 | 33 | 34 | 35 | ); 36 | } 37 | } 38 | 39 | export default MyApp; 40 | -------------------------------------------------------------------------------- /pages/_document.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Document, { Html, Head, Main, NextScript } from 'next/document'; 3 | import { ServerStyleSheet } from 'styled-components' 4 | import { ServerStyleSheets } from '@material-ui/styles'; 5 | import theme from '../src/theme'; 6 | 7 | class MyDocument extends Document { 8 | static async getInitialProps (ctx) { 9 | const styledComponentsSheet = new ServerStyleSheet() 10 | const materialSheets = new ServerStyleSheets() 11 | const originalRenderPage = ctx.renderPage; 12 | 13 | try { 14 | ctx.renderPage = () => originalRenderPage({ 15 | enhanceApp: App => props => styledComponentsSheet.collectStyles(materialSheets.collect()) 16 | }) 17 | const initialProps = await Document.getInitialProps(ctx) 18 | return { 19 | ...initialProps, 20 | styles: ( 21 | 22 | {initialProps.styles} 23 | {materialSheets.getStyleElement()} 24 | {styledComponentsSheet.getStyleElement()} 25 | 26 | ) 27 | } 28 | } finally { 29 | styledComponentsSheet.seal() 30 | } 31 | } 32 | 33 | render() { 34 | return ( 35 | 36 | 37 | 38 | {/* PWA primary color */} 39 | 43 | 47 | 48 | 49 |
50 | 51 | 52 | 53 | ); 54 | } 55 | } 56 | 57 | export default MyDocument; 58 | -------------------------------------------------------------------------------- /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 MuiLink from '@material-ui/core/Link'; 6 | import Link from '../src/Link'; 7 | 8 | 9 | export default function About() { 10 | return ( 11 | 12 | 13 | 14 | Next.js v4-beta example 15 | 16 | Go to the main page 17 | 18 | 19 | ); 20 | } -------------------------------------------------------------------------------- /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 MuiLink from '@material-ui/core/Link'; 6 | import Link from '../src/Link'; 7 | import styled from 'styled-components' 8 | 9 | const Title = styled.h1` 10 | color: red; 11 | font-size: 50px; 12 | ` 13 | 14 | export default function Index() { 15 | return ( 16 | 17 | Home Page Title with styled-components 18 | 19 | 20 | Next.js v4-beta example 21 | 22 | 23 | Go to the about page 24 | 25 | 26 | 27 | ); 28 | } -------------------------------------------------------------------------------- /src/Link.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import clsx from 'clsx'; 4 | import { withRouter } from 'next/router'; 5 | import NextLink from 'next/link'; 6 | import MuiLink from '@material-ui/core/Link'; 7 | 8 | const NextComposed = React.forwardRef(function NextComposed(props, ref) { 9 | const { as, href, prefetch, ...other } = props; 10 | 11 | return ( 12 | 13 | 14 | 15 | ); 16 | }); 17 | 18 | NextComposed.propTypes = { 19 | as: PropTypes.string, 20 | href: PropTypes.string, 21 | prefetch: PropTypes.bool, 22 | }; 23 | 24 | // A styled version of the Next.js Link component: 25 | // https://nextjs.org/docs/#with-link 26 | function Link(props) { 27 | const { activeClassName, router, className: classNameProps, innerRef, naked, ...other } = props; 28 | 29 | const className = clsx(classNameProps, { 30 | [activeClassName]: router.pathname === props.href && activeClassName, 31 | }); 32 | 33 | if (naked) { 34 | return ; 35 | } 36 | 37 | return ; 38 | } 39 | 40 | Link.propTypes = { 41 | activeClassName: PropTypes.string, 42 | as: PropTypes.string, 43 | className: PropTypes.string, 44 | href: PropTypes.string, 45 | innerRef: PropTypes.oneOfType([PropTypes.func, PropTypes.object]), 46 | naked: PropTypes.bool, 47 | onClick: PropTypes.func, 48 | prefetch: PropTypes.bool, 49 | router: PropTypes.shape({ 50 | pathname: PropTypes.string.isRequired, 51 | }).isRequired, 52 | }; 53 | 54 | Link.defaultProps = { 55 | activeClassName: 'active', 56 | }; 57 | 58 | const RouterLink = withRouter(Link); 59 | 60 | export default React.forwardRef((props, ref) => ); -------------------------------------------------------------------------------- /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; --------------------------------------------------------------------------------