其实有用next.js+react+Material-UI写了一个公司官网,这里总结一下next.js能会碰到的问题。 1 安装 npx create-next-app
2 _app.js _document.js server.js 3 css 这使用了一个名为styled-jsx的库。这是一个“ CSS-in-JS”库-它使您可以在React组件中编写CSS,并且CSS样式将受到限制(其他组件不会受到影响)。Next.js内置了对styled-jsx的支持,但是您也可以使用其他流行的CSS-in-JS库,例如styled-components或情感。
Next.js具有对CSS和Sass的内置支持,可让您导入.css和.scss文件。 还支持使用流行的CSS库,例如Tailwind CSS。 要使用CSS模块,CSS文件名必须以结尾.module.css 要加载全局CSS文件,请创建一个名为_app.js under 的文件
4 _app.js
该App组件是顶级组件,将在所有不同页面上通用。App例如,在页面之间导航时,可以使用此组件来保持状态
5 自定义PostCSS配置 开箱即用,无需配置,Next.js使用PostCSS编译CSS 。
6 搭配material ui
如果不配置,会对样式有影响 我们很清楚这个问题。我们最近引入了SSR API,它创建了更多的约束,更易于使用,并且应该减少出现此类问题的可能性。 虽然您必须在v3中配置_document.js和_app.js,但使用v4配置_document.js就足够了。
_document.js next-js-with-material-ui
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 __document.js /* eslint-disable react/jsx-filename-extension */ import React from 'react'; import Document, { Html, Main, NextScript, } from 'next/document'; import { ServerStyleSheets } from '@material-ui/core/styles'; export default class MyDocument extends Document { render() { return ( <Html lang="en"> <body> <Main /> <NextScript /> </body> </Html> ); } } // `getInitialProps` belongs to `_document` (instead of `_app`), // it's compatible with server-side generation (SSG). MyDocument.getInitialProps = async (ctx) => { // Render app and page and get the context of the page with collected side effects. const sheets = new ServerStyleSheets(); const originalRenderPage = ctx.renderPage; ctx.renderPage = () => originalRenderPage({ enhanceApp: (App) => (props) => sheets.collect(<App {...props} />), }); const initialProps = await Document.getInitialProps(ctx); return { ...initialProps, // Styles fragment is rendered after the app and page rendering finish. styles: [...React.Children.toArray(initialProps.styles), sheets.getStyleElement()], }; };
1 2 3 4 5 6 7 8 _app.js React.useEffect(() => { // Remove the server-side injected CSS. const jssStyles = document.querySelector('#jss-server-side'); if (jssStyles) { jssStyles.parentElement.removeChild(jssStyles); } }, []);
要自定义PostCSS配置,您可以创建一个名为的顶级文件postcss.config.js。如果您正在使用Tailwind CSS之类的库,这将很有用。
7 获取数据 node-fetch
8 国际化 (1)报错
1 2 3 4 You have not declared a namespacesRequired array on your page-level component: withI18nextTranslation(Home). This will cause all namespaces to be sent down to the client, possibly negatively impacting the performance of your app. For more info, see: https://github.com/isaachinman/next-i18next#4-declaring-namespace-dependencies
解决
1 2 3 Custom404.getInitialProps = async () => ({ namespacesRequired: ['common'], })
(2)版本6.02开始 无服务器 设置 _app.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 // import React, { useEffect } from 'react'; // import '../styles/global.css' // import { appWithTranslation } from '../i18n' // function App({ Component, pageProps }) { // useEffect(() => { // const jssStyles = document.querySelector('#jss-server-side'); // if (jssStyles) { // jssStyles.parentElement.removeChild(jssStyles); // } // }, []); // return <Component {...pageProps} /> // } // export default appWithTranslation(App) import App from 'next/app' import React, { useEffect } from 'react'; import { appWithTranslation } from '../i18n' const MyApp = ({ Component, pageProps }) => { useEffect(() => { const jssStyles = document.querySelector('#jss-server-side'); if (jssStyles) { jssStyles.parentElement.removeChild(jssStyles); } }, []); return <Component {...pageProps} /> } MyApp.getInitialProps = async (appContext) => ({ ...await App.getInitialProps(appContext) }) export default appWithTranslation(MyApp)
设置next.config.js
1 2 3 4 5 6 7 8 9 10 const { nextI18NextRewrites } = require('next-i18next/rewrites') const localeSubpaths = {} module.exports = { rewrites: async () => nextI18NextRewrites(localeSubpaths), publicRuntimeConfig: { localeSubpaths, }, }
i18n.js
1 2 3 4 5 6 7 8 9 10 11 12 const i18n = require('i18next') const NextI18Next = require('next-i18next').default const detector = require('i18next-browser-languagedetector') const { localeSubpaths } = require('next/config').default().publicRuntimeConfig const path = require('path') module.exports = new NextI18Next({ defaultLanguage: 'en', otherLanguages: ['de'], fallbackLng: "en", browserLanguageDetection: true, localePath: path.resolve('./public/static/locales') })
(3)设置_error.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 import PropTypes from 'prop-types' import { withTranslation } from '../i18n' const Error = ({ statusCode, t }) => ( <p> {statusCode ? t('error-with-status', { statusCode }) : t('error-without-status')} </p> ) Error.getInitialProps = async ({ res, err }) => { let statusCode = null if (res) { ({ statusCode } = res) } else if (err) { ({ statusCode } = err) } return { namespacesRequired: ['common'], statusCode, } } Error.defaultProps = { statusCode: null, } Error.propTypes = { statusCode: PropTypes.number, t: PropTypes.func.isRequired, } export default withTranslation('common')(Error)
设置404.js
pages/404` can not have getInitialProps/getServerSideProps,
1 2 3 4 5 6 7 function Custom404() { return <h1>404 - Page Not Found</h1> } Custom404.getInitialProps = async () => ({ namespacesRequired: ['common'], }) export default Custom404