🧪

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> ) }
 
作成したrregistry.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() } } }
 

参考した資料