diff --git a/errors/react-hydration-error.md b/errors/react-hydration-error.md index 38ea8e05540b..5b0ae7b6a500 100644 --- a/errors/react-hydration-error.md +++ b/errors/react-hydration-error.md @@ -41,8 +41,9 @@ Common causes with css-in-js libraries: - When using Styled Components / Emotion - When css-in-js libraries are not set up for pre-rendering (SSR/SSG) it will often lead to a hydration mismatch. In general this means the application has to follow the Next.js example for the library. For example if `pages/_document` is missing and the Babel plugin is not added. - - Possible fix for Styled Components: https://github.com/vercel/next.js/tree/canary/examples/with-styled-components - - If you want to leverage Styled Components with the new Next.js Compiler in Next.js 12 there is an [experimental flag available](https://github.com/vercel/next.js/discussions/30174#discussion-3643870) + - Possible fix for Styled Components: + - If you want to leverage Styled Components with SWC in Next.js 12.1+ you need to [add it to your Next.js config under compiler options](https://nextjs.org/docs/advanced-features/compiler#styled-components): https://github.com/vercel/next.js/tree/canary/examples/with-styled-components + - If you want to use Styled Components with Babel, you need `pages/_document` and the Babel plugin: https://github.com/vercel/next.js/tree/canary/examples/with-styled-components-babel - Possible fix for Emotion: https://github.com/vercel/next.js/tree/canary/examples/with-emotion - When using other css-in-js libraries - Similar to Styled Components / Emotion css-in-js libraries generally need configuration specified in their examples in the [examples directory](https://github.com/vercel/next.js/tree/canary/examples) diff --git a/examples/with-styled-components/.babelrc b/examples/with-styled-components-babel/.babelrc similarity index 100% rename from examples/with-styled-components/.babelrc rename to examples/with-styled-components-babel/.babelrc diff --git a/examples/with-styled-components-babel/.gitignore b/examples/with-styled-components-babel/.gitignore new file mode 100644 index 000000000000..1437c53f70bc --- /dev/null +++ b/examples/with-styled-components-babel/.gitignore @@ -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 diff --git a/examples/with-styled-components-babel/README.md b/examples/with-styled-components-babel/README.md new file mode 100644 index 000000000000..f9f489ed9459 --- /dev/null +++ b/examples/with-styled-components-babel/README.md @@ -0,0 +1,29 @@ +# Example app with styled-components using babel + +This example features how you use a different styling solution than [styled-jsx](https://github.com/vercel/styled-jsx) that also supports universal styles. That means we can serve the required styles for the first render within the HTML and then load the rest in the client. In this case we are using [styled-components](https://github.com/styled-components/styled-components). + +For this purpose we are extending the `` and injecting the server side rendered styles into the ``, and also adding the `babel-plugin-styled-components` (which is required for server side rendering). Additionally we set up a global [theme](https://www.styled-components.com/docs/advanced#theming) for styled-components using NextJS custom [``](https://nextjs.org/docs/advanced-features/custom-app) component. + +## Preview + +Preview the example live on [StackBlitz](http://stackblitz.com/): + +[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/vercel/next.js/tree/canary/examples/with-styled-components-babel) + +## Deploy your own + +Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example): + +[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https://github.com/vercel/next.js/tree/canary/examples/with-styled-components-babel&project-name=with-styled-components-babel&repository-name=with-styled-components-babel) + +## How to use + +Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example: + +```bash +npx create-next-app --example with-styled-components-babel with-styled-components-babel-app +# or +yarn create next-app --example with-styled-components-babel with-styled-components-babel-app +``` + +Deploy it to the cloud with [Vercel](https://vercel.com/new?utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)). diff --git a/examples/with-styled-components-babel/package.json b/examples/with-styled-components-babel/package.json new file mode 100644 index 000000000000..83bbeb7b6a61 --- /dev/null +++ b/examples/with-styled-components-babel/package.json @@ -0,0 +1,18 @@ +{ + "private": true, + "scripts": { + "dev": "next", + "build": "next build", + "start": "next start" + }, + "dependencies": { + "next": "latest", + "react": "^17.0.2", + "react-dom": "^17.0.2", + "react-is": "^17.0.2", + "styled-components": "^5.2.3" + }, + "devDependencies": { + "babel-plugin-styled-components": "^1.12.0" + } +} diff --git a/examples/with-styled-components-babel/pages/_app.js b/examples/with-styled-components-babel/pages/_app.js new file mode 100644 index 000000000000..019f78b2afc6 --- /dev/null +++ b/examples/with-styled-components-babel/pages/_app.js @@ -0,0 +1,26 @@ +import { createGlobalStyle, ThemeProvider } from 'styled-components' + +const GlobalStyle = createGlobalStyle` + body { + margin: 0; + padding: 0; + box-sizing: border-box; + } +` + +const theme = { + colors: { + primary: '#0070f3', + }, +} + +export default function App({ Component, pageProps }) { + return ( + <> + + + + + + ) +} diff --git a/examples/with-styled-components/pages/_document.js b/examples/with-styled-components-babel/pages/_document.js similarity index 100% rename from examples/with-styled-components/pages/_document.js rename to examples/with-styled-components-babel/pages/_document.js diff --git a/examples/with-styled-components-babel/pages/index.js b/examples/with-styled-components-babel/pages/index.js new file mode 100644 index 000000000000..8d1e94ba0110 --- /dev/null +++ b/examples/with-styled-components-babel/pages/index.js @@ -0,0 +1,10 @@ +import styled from 'styled-components' + +const Title = styled.h1` + font-size: 50px; + color: ${({ theme }) => theme.colors.primary}; +` + +export default function Home() { + return My page +} diff --git a/examples/with-styled-components/README.md b/examples/with-styled-components/README.md index 243e34b97d70..5a0542590fca 100644 --- a/examples/with-styled-components/README.md +++ b/examples/with-styled-components/README.md @@ -2,7 +2,9 @@ This example features how you use a different styling solution than [styled-jsx](https://github.com/vercel/styled-jsx) that also supports universal styles. That means we can serve the required styles for the first render within the HTML and then load the rest in the client. In this case we are using [styled-components](https://github.com/styled-components/styled-components). -For this purpose we are extending the `` and injecting the server side rendered styles into the ``, and also adding the `babel-plugin-styled-components` (which is required for server side rendering). Additionally we set up a global [theme](https://www.styled-components.com/docs/advanced#theming) for styled-components using NextJS custom [``](https://nextjs.org/docs/advanced-features/custom-app) component. +This example uses the Rust-based [SWC](https://nextjs.org/docs/advanced-features/compiler#styled-components) in Next.js for better performance than Babel. + +Currently, only the `ssr` and `displayName` transforms have been implemented. These two transforms are the main requirement for using `styled-components` in Next.js. ## Preview diff --git a/examples/with-styled-components/next.config.js b/examples/with-styled-components/next.config.js new file mode 100644 index 000000000000..52503c2612a3 --- /dev/null +++ b/examples/with-styled-components/next.config.js @@ -0,0 +1,10 @@ +/** @type {import('next').NextConfig} */ + +const nextConfig = { + reactStrictMode: true, + compiler: { + styledComponents: true, + }, +} + +module.exports = nextConfig diff --git a/examples/with-styled-components/package.json b/examples/with-styled-components/package.json index 83bbeb7b6a61..c5b30dc1b2c7 100644 --- a/examples/with-styled-components/package.json +++ b/examples/with-styled-components/package.json @@ -11,8 +11,5 @@ "react-dom": "^17.0.2", "react-is": "^17.0.2", "styled-components": "^5.2.3" - }, - "devDependencies": { - "babel-plugin-styled-components": "^1.12.0" } } diff --git a/examples/with-typescript-styled-components/.babelrc b/examples/with-typescript-styled-components/.babelrc deleted file mode 100644 index 854cb73a8103..000000000000 --- a/examples/with-typescript-styled-components/.babelrc +++ /dev/null @@ -1,4 +0,0 @@ -{ - "presets": ["next/babel"], - "plugins": [["styled-components", { "ssr": true }]] -} diff --git a/examples/with-typescript-styled-components/next.config.js b/examples/with-typescript-styled-components/next.config.js new file mode 100644 index 000000000000..52503c2612a3 --- /dev/null +++ b/examples/with-typescript-styled-components/next.config.js @@ -0,0 +1,10 @@ +/** @type {import('next').NextConfig} */ + +const nextConfig = { + reactStrictMode: true, + compiler: { + styledComponents: true, + }, +} + +module.exports = nextConfig diff --git a/examples/with-typescript-styled-components/package.json b/examples/with-typescript-styled-components/package.json index 18ad75ca09f7..76f91cde30c1 100644 --- a/examples/with-typescript-styled-components/package.json +++ b/examples/with-typescript-styled-components/package.json @@ -17,7 +17,6 @@ "@types/react": "17.0.4", "@types/react-dom": "17.0.3", "@types/styled-components": "5.1.9", - "babel-plugin-styled-components": "^1.12.0", - "typescript": "4.2.4" + "typescript": "^4.5.5" } } diff --git a/examples/with-typescript-styled-components/pages/_document.tsx b/examples/with-typescript-styled-components/pages/_document.tsx deleted file mode 100644 index eb67e4c6d739..000000000000 --- a/examples/with-typescript-styled-components/pages/_document.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import Document, { DocumentContext } from 'next/document' -import { ServerStyleSheet } from 'styled-components' - -export default class MyDocument extends Document { - static async getInitialProps(ctx: DocumentContext) { - const sheet = new ServerStyleSheet() - const originalRenderPage = ctx.renderPage - - try { - ctx.renderPage = () => - originalRenderPage({ - enhanceApp: (App) => (props) => - sheet.collectStyles(), - }) - - const initialProps = await Document.getInitialProps(ctx) - return { - ...initialProps, - styles: ( - <> - {initialProps.styles} - {sheet.getStyleElement()} - - ), - } - } finally { - sheet.seal() - } - } -} diff --git a/test/e2e/yarn-pnp/test/with-styled-components.test.ts b/test/e2e/yarn-pnp/test/with-styled-components-babel.test.ts similarity index 61% rename from test/e2e/yarn-pnp/test/with-styled-components.test.ts rename to test/e2e/yarn-pnp/test/with-styled-components-babel.test.ts index f8ee921afe98..35c778df540b 100644 --- a/test/e2e/yarn-pnp/test/with-styled-components.test.ts +++ b/test/e2e/yarn-pnp/test/with-styled-components-babel.test.ts @@ -1,5 +1,5 @@ import { runTests } from './utils' describe('yarn PnP', () => { - runTests('with-styled-components') + runTests('with-styled-components-babel') })