Skip to content

01kingmaker01/Spotify

Repository files navigation

twin, next, styled-components

Download this example using degit

npx degit https://github.com/ben-rogerson/twin.examples/next-styled-components folder-name

From within the new folder, run npm install, then npm start to start the dev server.

Table of contents

Getting started

Installation

Install Next.js

npx create-next-app

Install the dependencies

npm install styled-components
npm install -D twin.macro tailwindcss babel-plugin-macros
Install with Yarn
yarn create next-app

Install the dependencies

yarn add styled-components
yarn add twin.macro tailwindcss babel-plugin-macros --dev

Add the global styles

Twin uses the same preflight base styles as Tailwind to smooth over cross-browser inconsistencies.

The GlobalStyles import adds these base styles along with some @keyframes for the animation classes and some global css that makes the ring classes and box-shadows work.

Due to an issue in styled-components, global styles get added in the wrong order when using styled-components. This gives the tailwind base styles an incorrect specificity.
Until the issue is fixed, the workaround is to export the styles from another file.

You can import GlobalStyles within a new file placed in components/GlobalStyles.js:

// components/GlobalStyles.js
import React from "react";
import { createGlobalStyle } from "styled-components";
import tw, { theme, GlobalStyles as BaseStyles } from "twin.macro";

const CustomStyles = createGlobalStyle`
  body {
    WebkitTapHighlightColor?: ${theme`colors.purple.500`};
    ${tw`antialiased`}
  }
`;

const GlobalStyles = () => (
  <>
    <BaseStyles />
    <CustomStyles />
  </>
);

export default GlobalStyles;

Then import the GlobalStyles file in pages/_app.js:

// pages/_app.js
import GlobalStyles from "./../components/GlobalStyles";

const App = ({ Component, pageProps }) => (
  <div>
    <GlobalStyles />
    <Component {...pageProps} />
  </div>
);

export default App;

Add the twin config

Twin’s config can be added in a couple of different files.

a) Either in babel-plugin-macros.config.js:

// babel-plugin-macros.config.js
module.exports = {
  twin: {
    preset: "styled-components",
    autoCssProp: false,
  },
};

b) Or in package.json:

// package.json
"babelMacros": {
  "twin": {
    "preset": "styled-components"
  }
},

Add the babel config

Add this babel configuration in .babelrc.js:

// In .babelrc.js
module.exports = {
  presets: [["next/babel", { "preset-react": { runtime: "automatic" } }]],
  plugins: [
    "babel-plugin-macros",
    ["babel-plugin-styled-components", { ssr: true }],
  ],
};

Add the server stylesheet

To avoid the ugly Flash Of Unstyled Content (FOUC), add a server stylesheet in pages/_document.js that gets read by Next.js:

// pages/_document.js
import Document from "next/document";
import { ServerStyleSheet } from "styled-components";

export default class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const sheet = new ServerStyleSheet();
    const originalRenderPage = ctx.renderPage;
    try {
      ctx.renderPage = () =>
        originalRenderPage({
          enhanceApp: (App) => (props) =>
            sheet.collectStyles(<App {...props} />),
        });
      const initialProps = await Document.getInitialProps(ctx);

      return {
        ...initialProps,
        styles: (
          <>
            {initialProps.styles}
            {sheet.getStyleElement()}
          </>
        ),
      };
    } finally {
      sheet.seal();
    }
  }
}

Customization

Next steps

Learn how to work with twin

Learn more about styled-components