- 前回の記事: Docker で Next.js 開発環境を用意する
- 今回の概要
- Next.js チュートリアルのページ
- ソースコード
- 新しいページを追加する
- ページ遷移(リンク)
- 画像などのアセットの配置方法
- title などのメタデータの設定方法
- CSSの書き方
- Layout
- グローバルにCSSを適用させる
- ページをさらに作りこんでいく
- CSSに関するTips
- 次回: Pre-rendering
前回の記事: Docker で Next.js 開発環境を用意する
前回は
- Next.js の Server-side Rendering と Static Generation についての説明
- Docker で Next.js の開発環境を用意
までやりました。まだ読んでいない人はこちら。
今回の概要
今回は適当なページを追加して、Next.js の基本的な文法や、使い方を学びます。
React と違う部分も結構あるので、そこを中心にやっていきます。
Next.js チュートリアルのページ
今回も、Next.js のチュートリアルのページをベースにすすめていきます。
今回はここからやっていきます。
ソースコード
作ったものは以下で公開しています
新しいページを追加する
Next.js のプロジェクトを作成すると、 pages/index.js
というファイルが存在していますが、ここに、pages/posts/first-post.js
を追加することで、ページを追加します。
https://127.0.0.1:3000/posts/first-post
にアクセスすると、このページを表示するようにしたいです。
posts ディレクトリを作成して、first-post.js を作成します。
export default function FirstPost() { return <h1>First Post</h1> }
ファイルを作るだけで、 /posts/first-post にアクセスできるようになっているはずです。
http://127.0.0.1:3000/posts/first-post
ページ遷移(リンク)
index.js から first-post.js へのリンクを貼ります。
index.js にて
# import を追加して import Link from 'next/link' # 適当なところにリンクを貼る <h1 className="title"> Read{' '} <Link href="/posts/first-post"> <a>this page</a> </Link> </h1>
最初 Read{' '}
ってなにかと思ったんだけど、これは Read
と {' '}
に分かれます。
「Read this page」と表示したいんだけど、 Read と this の間にスペース開けるために {' '}
が必要らしい。
{' '}
が無いと Readthis page
となってしまいます。
さらに、 /posts/first-post から index.js に戻れるようにします。
import Link from 'next/link' export default function FirstPost() { return ( <> <h1>First Post</h1> <h2> <Link href="/"> <a>Back to home</a> </Link> </h2> </> ) }
ちなみに、これは Client-Side Navigation というものになります。
- 実際にはページ移動をしているわけではない
- JSでページ遷移している
また、Code splitting and prefetching という仕組みが動いていて、
- ページに必要な情報だけ読まれる。ページにアクセスした時にすべてのページからサーバーから渡されるわけではない。
- 本番用のビルドだと、Link は自動的にプリフェッチされる
画像などのアセットの配置方法
画像とかは public ディレクトリに置きます。
index.js のフッターにある通り、<img>
タグで参照できます。
<img src="/vercel.svg" alt="Vercel Logo" className="logo" />
title などのメタデータの設定方法
<title>
タグなどは <Head>
の中に書きます。
index.jsにある通りです。
<Head> <title>Create Next App</title> <link rel="icon" href="/favicon.ico" /> </Head>
FirstPost にも Head を追加してみます。
import Head from 'next/head' import Link from 'next/link' export default function FirstPost() { return ( <> <Head> <title>First Post</title> </Head> <h1>First Post</h1> <h2> <Link href="/"> <a>Back to home</a> </Link> </h2> </> ) }
CSSの書き方
index.js にはすでに CSS があたっています。
<style jsx>{` … `}</style>
これは styled-jsx ってやつで、CSS in JS というやつです。 他にも styled-components とか emotion みたいな有名な CSS in JS ライブラリに対応しています。
他にも、Build-in CSS というのもあるし、 Tailwind CSS みたいなメジャーな CSS ライブラリには対応しています。
Layout
レイアウトというのを設定できます。すべてのページにヘッダを表示するみたいな、よくあるレイアウト機能です。
components
というディレクトリを作成し、その中に layout.js
を作成します。
export default function Layout({ children }) { return <div>{children}</div> }
first-post からこのレイアウトを使ってみる。全体を <Layout>
で囲う。
import Head from 'next/head' import Link from 'next/link' import Layout from '../../components/layout' export default function FirstPost() { return ( <Layout> ... <h1>First Post</h1> <h2> <Link href="/"> <a>Back to home</a> </Link> </h2> </Layout> ) }
さらに、 components/layout.module.css
を作成します。
.container { max-width: 36rem; padding: 0 1rem; margin: 3rem auto 6rem; }
で、components/layout.js
を編集します。
import styles from './layout.module.css' export default function Layout({ children }) { return <div className={styles.container}>{children}</div> }
これでCSSが適用されたはずです。
ここまでの変更内容: https://github.com/yoshikyoto/nextjs-blog/commit/9890a498fd3b411f0206e5196657bef0585f248d
グローバルにCSSを適用させる
CSSは基本コンポーネントごとになっちゃうので、グローバルに適用させるためには、まず、pages/_app.js
を作成します。
export default function App({ Component, pageProps }) { return <Component {...pageProps} /> }
作成したらアプリの再起動が必要なので、dockerを再起動させます。
docker-compose down
docker-compose up -d
styles/global.css
を作成します。
html, body { padding: 0; margin: 0; font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; line-height: 1.6; font-size: 18px; } * { box-sizing: border-box; } a { color: #0070f3; text-decoration: none; } a:hover { text-decoration: underline; } img { max-width: 100%; display: block; }
pages/_app.js
で、↑のCSSを読み込ませます。以下を追記するだけです。
import '../styles/global.css'
分かりづらいので、適当に a タグの color とか変えてみて、色が変わることを確認すると良いでしょう。
ここまでの差分: https://github.com/yoshikyoto/nextjs-blog/commit/cf46f8457b5b5fc9561412b8e0be10ffd3530934
ページをさらに作りこんでいく
Next.js だと以下のページに該当する。
https://nextjs.org/learn/basics/assets-metadata-css/polishing-layout
レイアウトの洗練、いらなくない?と思ったけど、後で出てくる Pre-rendering の部分でこのコード使うので、やっておいたほうがいい。
適当に.jpg
のプロフィール画像を用意しておきます。400x400くらいが推奨らしいです。
public/images
ディレクトリを作って、その中に入れます。
この章は変更が大きいので、私の GitHub を見ると良い
https://github.com/yoshikyoto/nextjs-blog/commit/5e2085f3648bebbeacd6cfd7630f5c8a85bf43bd
変更部分
layout.module.css
styles/utils.module.css
- ちなみに、
styles
の中にはglobal.css
が今は入っている
- ちなみに、
components/layout.js
utils.module.css
を新たに import するようにする- const siteTitle をここに定義するのかー
pages/index.js
んで、こうなる。read this page をクリックしても、ヘッダには常に Utakata があるようなレイアウトに。
CSSに関するTips
- classnames ライブラリとかが使える
- PostCSS も使える
- チュートリアルに具体例は出てこないので、気になるなら、他の記事を読んでみて実装するのがよさそう。
- Sassも使える
.css
の代わりに.scss
や.sass
を使えば Sass になるっぽい?
Styling について、どれがベストかは、色々使ってみて試すしかない。
次回: Pre-rendering
次回はついに Pre-rendering (SSR, Static Generation)をやります。