自サイトを Next.js + Vercel で置き換えようと思った話

# はじめに

自サイトの構成が古く（生PHPによるお手製CMS！）なってきたので、新しい技術で置き換えようと思いました。

いろいろ調べてみると、`Next.js`か`Gatsby`というフレームワークが良さそうだったので、まずはメジャーな`Next.js`のほうを試してみることにしました。

Gatsbyを試してみた記事はこちらです。
https://qiita.com/naga3/items/2063e4eeecbf4e785d4d

## Vercelとは

Next.jsを開発しているVercel社のホスティングサービスで、楽に使えそうなのでやってみます。

Vercelは無料プランと有料プランがありますが、個人が普通に使うぶんには無料プランで十分そうです。
https://vercel.com/pricing

プランによる制限についではこちらが詳しいです。
https://b.lollipop.onl/q2fgpwij4/

# Vercelプロジェクト作成

アカウントがなければサインアップしておきましょう。
https://www.gatsbyjs.com/dashboard/signup/

まず、ダッシュボード https://vercel.com/dashboard から `Import Project` を押します。

既存のリポジトリを使う`Import Git Repository`と、テンプレートから作成する`Import Template`がありますが、今回はゼロから作るので`Import Template`を選びます。

テンプレートは`Next.js`を選びます。

次にリポジトリ名、プロジェクト名を適当に付けます。プロジェクト名は小文字のみの英数字+ハイフンしか使えないようです。

最後に`Deploy`ボタンを押すと、`yarn install`やらいろいろ走るのが見えて、デプロイ完了しました。やったね！

早速Visitボタンを押して完成したサイトに訪れてみましょう。

# ローカルでの開発

ここからはローカルでの開発になります。`node`や`yarn`はインストールしておきます。

上で作成したリポジトリをcloneして、

```sh
yarn install
yarn dev
```

を実行するとサーバーが立ち上がって、`http://localhost:3000/`で確認することができます。

![Screenshot from 2020-11-11 10-24-14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32030/1b71a421-2133-1bf0-62be-00e1df009e72.png)

次に、トップページに書いてあるとおり、`pages/index.js`を編集してみます。

Reactはよく分かりませんが、JavaScriptとHTMLが混在した形式のようですね。とりあえず`h1`を変更してみます。

```html
Welcome to <a href="https://nextjs.org">Next.js!</a>
```

これを以下のように変更します。

```html
こんにちは <a href="https://nextjs.org">Next.js!</a>
```

保存するとLive Reloadされました。

![Screenshot from 2020-11-11 10-29-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32030/91f51e0c-f94e-3677-db3b-adeeff4523b7.png)

いいですね。

## ローカルからのデプロイ

そのままmasterにpushすれば本番に反映されるのではないかと思ったので、やってみると、無事反映されました。簡単ですね。

# ページの追加

ページを増やしてみます。`pages`ディレクトリ下にファイルを作成し、ページ表示用の関数を`export default`するだけでページを追加できるようです。

```jsx:pages/page2.js
export default function Page2() {
  return <h1>page 2</h1>
}
```

`http://localhost:3000/page2`を開きます。

![Screenshot from 2020-11-11 11-24-47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32030/35d381c8-5723-3570-8132-6a0312135f37.png)

できました。

## トップページからリンクを張る

普通に`a`タグで張ってみます。

```jsx:pages/index.js
<a href="/page2">Page 2</a>
```

普通に動きました。

クライアントサイドでルーティングを行う`Link`コンポーネントというものがあるらしいので、そちらも使ってみます。

```jsx:pages/index.js
import Link from 'next/link'
...
<Link href="/page2">Page 2</Link>
```

こちらも普通に動きましたが、`a`よりも`Link`のほうが圧倒的に速いです。通常はこちらを使ったほうが良さそうですね。

Linkコンポーネントの詳細はこちら https://nextjs.org/docs/api-reference/next/link

# アセットを追加する

画像などのアセットは、`/public`配下に置きます。これでルートから参照できます。

適当な画像を`image.png`という名前で`/public`配下に置き、`page2.js`を変更してみます。

```jsx:pages/page2.js
export default function Page2() {
  return (
    <div>
      <h1>ビャンビャン麺</h1>
      <img src="/image.png" />
    </div>
  )
}
```

![Screenshot from 2020-11-11 12-18-16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32030/118276cb-b5cd-bf42-9141-ad037e415592.png)

良さそうですね。

# CSSを適用する

## ページ内に書く

いわゆる`style`タグのようにCSSファイルを分けない場合は、最初から組み込まれている[styled-jsx](https://github.com/vercel/styled-jsx)を使います。

```jsx:pages/page3.js
export default function Page3() {
  return (
    <div>
      <p>赤色</p>
      <style jsx>{`
        p {
          color: red;
        }
      `}</style>
    </div>
  )
}
```

![Screenshot from 2020-11-11 14-03-15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32030/885224a7-239c-b8be-1a47-01dd8408bd84.png)

## CSSファイルを分ける

CSSファイルを独立させるのなら、`styles`ディレクトリにCSSファイルを置いてimportすればOKです。

CSSの構文はそのまま書けますが、ファイル名を`*.module.css`にする必要があります。

```css:styles/page4.module.css
.title {
  color: blue;
}
```

```jsx:pages:page4.js
import styles from '../styles/page4.module.css'

export default function Page4() {
  return (
    <div>
      <p className={styles.title}>青色</p>
    </div>
  )
}
```

![Screenshot from 2020-11-11 14-20-20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32030/1ec7b4f6-cfc4-9cc1-e378-baa499c28047.png)