Next13でStyled Componentsを使ってみましょう。(App Router / Pages Router)
Next13 App Router
Next13でStyled Componentsを使ってみましょう。
まず下記のようにインストールします。
タイプスクリプトを使用するため、
@types/styled-components
もインストールしました。npm i styled-components npm i @types/styled-components
インストールが完了したら、
next.config.js
ファイルに以下のようにスタイルコンポーネントコンパイラを作成してくれます。Next13ではSWCコンパイラを使用していますので
.barbelrc
の代わりにnext.config.js
に作成します。/** @type {import('next').NextConfig} */ const nextConfig = { reactStrictMode: true, compiler: { styledComponents: true, }, } module.exports = nextConfig
作成したら
lib/registry.tsx
ファイルを生成し、以下のように作成します。'use client' import React, {useState} from 'react' import {useServerInsertedHTML} from 'next/navigation' import {ServerStyleSheet, StyleSheetManager} from 'styled-components' export default function StyledComponentsRegistry({ children, }: { children: React.ReactNode }) { const [styledComponentsStyleSheet] = useState(() => new ServerStyleSheet()) useServerInsertedHTML(() => { const styles = styledComponentsStyleSheet.getStyleElement() return <>{styles}</> }) if (typeof window !== 'undefined') return <>{children}</> return ( <StyleSheetManager sheet={styledComponentsStyleSheet.instance}> {children} </StyleSheetManager> ) }
作成したr
registry.tsx
ファイルでlayoutを包み込みます。// app/layout.tsx 'use client' import Header from '@/components/Header' import StyledComponentsRegistry from './lib/registry' export default function RootLayout({children}: {children: React.ReactNode}) { return ( <html> <body> <StyledComponentsRegistry> <Header /> {children} </StyledComponentsRegistry> </body> </html> ) }
Styled Componentsが壊れずに動作します。
参考した資料
Next13 Pages Router
next12から13にアップグレードした後、スタイル コンポーネントを適用してみましょう。
リロードときにフォントが壊れるため、next/fontを使用するために13にアップグレードしました。
まず、フォントが壊れないようにnext/fontを使用します。
// pages/_app.js import GlobalStyle from '@/styles/globalStyles' import {Poppins} from 'next/font/google' const poppins = Poppins({ weight: ['400', '600', '800'], variable: '--font-poppins', subsets: ['latin'], display: 'swap', }) export default function App({Component, pageProps}) { return ( <main className={poppins.className}> <GlobalStyle /> <Component {...pageProps} /> </main> ) }
13にアップグレードするとbabelが使用できないため、
.babelrc
を消してnext.config.jsファイルに追加します。(スタイルコンポーネントを使用するため)
module.exports = { reactStrictMode: true, compiler: { styledComponents: true, }, }
問題は、バーベリックを消すとsvgを使用するときに問題が現れます。
元々は
babel-plugin-inline-react-svg
を使って<SvgName/>
のように持ってきて、fillを通じて色を変更して使用したのですが、バーベルが使えないため
<SvgName/>
のように取得できず問題が発生しました。imgを使おうかと思ったのですが、色が変更できなくてもう少し探してみたら
ReactComponents as SvgName
でコンポーネント化して使う方法がありました。<SvgName />
この場合、fillへの色変更も可能です。
それで、あ、これです!と使おうとしましたが、Nextでは使えませんでした。
そこでnextでsvgを使う方法をもう少し調べてみると、@svgr/webpackを見つけました。
Next13でsvgの使い方
babel-plugin-inline-react-svg
を削除してNext13でsvgの使い方 ページに沿って設定します。svg設定まで完了したら戻ってスタイルコンポーネントの設定を終わらせましょう。
_document.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() } } }