前書
この回答は問題の原因がstyled-componentsにあると想定しての内容になります。以下の手順で作業を行ったにもかかわらず問題が解決されない場合は、Next.jsのCSSインポート機能でスタイルシートを読み込んでいないか(例:import styles from '../styles/SomeStyle.module.css'
)確認してください。当該機能を利用している場合、Next.jsのCSSインポート機能はSSRをサポートしていないため、他のアプローチでスタイルを設定する必要があります。styled-componentsを利用している場合はcreateGlobalStyle
がおすすめです。
回答
styled-componentsで正しくSSRを行うためには専用の設定を行う必要があります。
以下に既存のNext.jsアプリに設定を追加する手順を示します:
SSRのセットアップ
.babelrcを準備する
アプリのルートに.babelrc
ファイルが存在しなければ追加します。.babelrc
の必要最低限の内容は次の通りです:
json
1{
2 "presets": ["next/babel"],
3 "plugins": []
4}
next/babel
はnext
パッケージに含まれているため、インストールの必要はありません。
babelプラグインを追加する
まず、次のコマンドのいずれかを使い、styled-components
のbabelプラグインをインストールします:
sh
1# npm
2npm i -D babel-plugin-styled-components
sh
1# yarn
2yarn add -D babel-plugin-styled-components
sh
1# pnpm
2pnpm add -D babel-plugin-styled-components
インストールが完了したら、.babelrc
に追加したプラグインを記載します:
json
1{
2 "presets": ["next/babel"],
3 "plugins": ["styled-components"]
4}
この状態でdev
スクリプトを実行し、次の行が正しく出力されるか確認します:
plain
1info - Using external babel configuration from /.../.babelrc
出力を確認したらdev
スクリプトを一度終了します。
正しく出力されない、あるいはエラーが発生する場合は、ファイルが当手順に従って正しく構成されているか確認してください。
カスタマイズしたDocumentクラスでServerStyleSheetを使用する
pages/_document.[jt]sx?
にファイルを置くことで、カスタマイズしたDocument
クラスを使用することができます。(Next.jsのデフォルトのDocument
クラスはこちらで確認できます。)このクラスのstatic getInitialProps
静的メソッドを次のコードで拡張します:
// 以下の3行の`import`文は必須です
import React from 'react'
import Document, { DocumentContext, DocumentInitialProps } from 'next/document'
import { ServerStyleSheet } from 'styled-components'
export default class MyDocument extends Document {
// 拡張部ここから〜
static async getInitialProps(
ctx: DocumentContext
): Promise<DocumentInitialProps> {
const sheet = new ServerStyleSheet()
const originalRenderPage = ctx.renderPage
ctx.renderPage = (): ReturnType<DocumentContext['renderPage']> =>
originalRenderPage({
enhanceApp: (App) => (props) => sheet.collectStyles(<App {...props} />),
})
const initialProps = await Document.getInitialProps(ctx)
return {
...initialProps,
styles: [
...React.Children.toArray(initialProps.styles),
sheet.getStyleElement()
],
}
}
// 〜拡張部ここまで
}
拡張したDocumentのテスト
再びdev
スクリプトを実行し、ブラウザでJavaScriptをオフにした状態でCSSが正しくレンダリングされているか確認してください。
正しく動作している場合、サーバーのコンソールには次のようなログが出力されます:
plain
1ready - started server on http://...
2info - Using external babel configuration from .../.babelrc
3event - compiled successfully
4event - build page: /
5wait - compiling...
6event - compiled successfully
以上で設定は終了です。
なにかご不明な点等ありましたらコメントでお気軽にご質問ください。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/11/15 07:05 編集
2020/11/15 07:07
2020/11/15 11:32
2020/11/16 01:38
2020/11/17 10:14
2020/11/18 02:54
2020/11/18 02:55
2020/11/18 10:43
2020/11/18 11:14
2020/11/28 21:47 編集
2020/11/19 01:28
2020/11/19 09:08
2020/11/19 11:04