Next.js Pages Router やってみた
はじめに
今回、Next.jsのPages Routerについて学ぶことにした。
私はもともとAngular使いで、転職を機にReact+Next.jsの学習に取り組んでいる。
学習ではApp Routerから詳しく学んだ。
一方で転職先のアプリケーションはまだPages Routerであるという。(これから移行予定とのこと)
そのため、遅ればせながらPages Routerの学習に取り組む。
目標としては
- Page Routerそのものの理解
- Page RouterからApp Routerへの移行手段の理解
を達成したい
学習
学習に使うサイトはこれ
Udemyでセールしていたので購入。
今は基本App Routerベースの教材しかないので、Pages Routerベースの教材を見つけるのに苦労した。
公式チュートリアルも見ていない方向けということで、復習にもなると良いな。
Next.jsの基礎
あとでかく
Next.js フォルダ構成
あまり知らなかったところだけ
-
.next
- Next.jsのフレームワーク自体を構築するとき必要なモジュール群、ファイル群
-
public
- 静的なファイル群が格納される
- 例えば画像とか、言語ファイルとかも入るのかも
-
styles
- スタイルファイル置き場、ページのレイアウトとかに必要なスタイルファイル
ホットリロード
コードを変更した際に、アプリケーション全体を再起動することなく、リアルタイムで特定箇所だけ変更を反映する機能。
Next.jsが必要な部分だけ再コンパイルしてくれる。
これにより、開発スピードの向上が見込まれる。
Pages Router
App Routerではフォルダ名がそのままパスになる。
しかしPages Routerでは、ファイル名がパスになる。
例えば以下のツリー構造だと、localhost:3000/posts/firstPost
にアクセスすると、firstPost.jsに書かれたDOMに辿り着く。
my-next-app/
├── node_modules/
├── public/
├── pages/
│ ├── api/
│ │ └── hello.js
│ ├── index.js
│ ├── _app.js
│ ├── _document.js
│ └── posts/
│ └── firstPost.js // localhost:3000/posts/firstPost
<a>
と<Link>
の違い
aタグだとリロードが入る。
Linkコンポーネントだとリロードが入らない。
すなわち、Linkコンポーネントの方がページ遷移が早い。
リロードが入ることでページが再レンダリングされる。
しかしSEOを気にする場合はaタグも使える。
その場合はLinkタグの中にaタグを入れると良いとのこと。
<Link href='/hoge'>
<a> 次へ </a>
</Link>
メタデータについて
Pages RouterではHeadコンポーネントを利用してページにメタデータを埋め込める。
export default function FirstPost() {
return (
<div>
<Head>
<title> 最初の投稿 </title>
</Head>
<h1> 最初の投稿 </h1>
<Link href='/'> ホームへ戻る </Link>
</div>
);
}
一方でApp RouterではHeadコンポーネントを利用できないとのこと。
動的なコンポーネントには以下の方法でメタデータを埋め込めるとのこと。
layout.tsx, page.tsxのどちらかに書いておけば反映されるよう。
注意点としては、Server Componentsでのみ利用可能だということ。
_app.jsについて
_app.js
にはglobal.cssが書かれている
これによりwebアプリケーション全体で共通のスタイルを適用することができる
import '../styles/globals.css'
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />
}
export default MyApp
プリレンダリングについて
Reactの場合、初回のロード時は画面は真っ白になる。
HTMLとJavaScriptをまだ読み込めていないため。
JavaScriptが読み込まれて初めてレンダリングされる。
しかし、Next.jsではSSGであればビルド時に、SSRであればリクエスト時にHTMLが生成される。
そのため、HTMLが動くのでユーザ離脱率を抑えられる。
〜 プリレンダリングされているかどうか確認する方法 〜
開発者ツールを開いた状態でCommand+Shift+P
を押す。
"JavaScriptを無効にする"をクリックする
動的ルーティングについて
getStaticPathsの仕組みを使うことで動的ルーティングができる。
getStaticPaths
は任意の[id].jsのようなファイル内で定義する。
ここで定義されたルートは動的ルーティング対象になる。
// [id].js
export async function getStaticPaths() {
return {
{
params: {
id: hoge, // idという命名は[id].jsに合わせる必要がある
},
params: {
id: fuga,
},
},
fallback: false, // falseだと存在しないURLにアクセスされたときに404に遷移させる
};
}
またgetStaticPaths
を使う場合、getStaticProps
も同時に使う必要がある。
でなければ以下のように怒られてしまう。
Error: getStaticPaths was added without a getStaticProps in /posts/[id]. Without getStaticProps, getStaticPaths does nothing
getStaticProps
はSSGでプリレンダリングするものを返す関数。
getStaticProps
の引数はparamsにする必要があり、そうすることでパスの[id]に当たる文字列を引っ張ってくることができる。
export async function getStaticProps({ params }) {
const postData = await getPostData(params.id); // posts/hogeにアクセスしたとき、params.idはhoge
return {
props: {
postData,
},
};
}
export default function Post({ postData }) { // getStaticPropsで返したpostDataが使える
return <Layout>{postData.title}</Layout>;
}
なお、開発環境ではSSGで記述しても少し遅延があるような挙動になる。
これは開発環境ではSSRでレンダリングされていることが原因だそう。
本番環境、すなわちビルドをすればSSGでレンダリングされることを確認できるとのこと。
なお、開発環境ではSSGで記述しても少し遅延があるような挙動になる。
これは開発環境ではSSRでレンダリングされていることが原因だそう。
本番環境、すなわちビルドをすればSSGでレンダリングされることを確認できるとのこと。
これはnpm run dev
した時の話であり、npm run build && npm run start
した時はプリレンダリングされた状態のアプリケーションを見れる。