Next.js x Vercel x GitHubで超簡単デプロイ

# Next.js x Vercel x GitHubで超簡単デプロイ

# はじめに

これは [KWC Advent Calendar 2022](https://qiita.com/advent-calendar/2022/kwc) の記事です。

こんにちは！今年四月にKWCに入社したばかりのひよこエンジニアFeifeiです！

フロントエンジニアを目指してるところ、急に道がフルスタックに変わってバタバタの真最中の状態ですが、ReactとAWS を中心に色々勉強をしています。初めてのテックブログ且つ日本語で文章書くのが久しぶりですが、がんばるます（アーニャ顔）！

今回、個人でよく利用しているNext.js x vercel x GitHubの組み合わせでWebサイトを超簡単にデプロイできる流れを紹介したいと思います。

元々、自分のプロジェクトでNotionのapiを利用してみたく、バックエンドなしでSSRの機能を使ってnotionのapiを呼び出すためにNext.jsを選定しました。

そこで、Nextを使うことになって自然にVercelを使ってデプロイすることが視野に入るようになりました。初めてのVercelなんですが、使い勝手が良くて、UIもとても綺麗でわかりやすかったので、~~前に何もわかってない状態からいきなりAWSのサービスでデプロイするときの苦痛な経歴と比べたらとても親切でシンプルな流れになるので~~、ぜひ皆さんにその利点を紹介したいと思います！

# ながれ

今回、作業する流れは以下になります：

1. リポジトリ作成
2. ローカルでNextのプロジェクトを作成
3. Nextのルーティングの機能も紹介するために軽くページ作成
4. コードをGitHubにプッシュ
5. VercelでGitHubリポジトリの紐付ける設定をつける(GitHubリポジトリの方も**権限付与**が必要なので忘れず！)
6. デプロイされたサイトを確認

## 下準備

**GitHubのアカウントとVercelのアカウントを先に準備して下さい！**

Vercelのアカウントは無料のHobby、Pro、Custom三つのタイプがありますが、今回は**無料のHobby**で十分です（クレジットカードの登録など一切なし）。

ローカル環境：

Node.jsバージョン: 16.13.1

npmバージョン: 8.19.2

# 早速、本番に入ります

## リポジトリ作成

まず、vercel_is_awesomeというリポジトリを作成します。

publicにします。

![%E6%88%AA%E5%B1%8F2022-12-11_14.45.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2988308/226040e2-ab65-1902-3afd-c1d2f6161bb1.png)

## ローカルでNextのプロジェクトを作成

`npx create-next-app@latest --typescript`

でNextプロジェクトを新しく作成します。

![%E6%88%AA%E5%B1%8F2022-12-11_14.52.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2988308/ccb7c72d-21b3-747c-4a09-92c653e40b41.png)

プロジェクト名やESLintに関する選択などを入力します。

![%E6%88%AA%E5%B1%8F2022-12-11_14.55.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2988308/c41a6558-d1be-7033-f93e-80cd7c98b172.png)

生成が終わったら、GitHubのリポジトリに紐付けます。

![%E6%88%AA%E5%B1%8F2022-12-11_14.59.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2988308/452324e1-f90f-cb42-670b-83932e96a23a.png)


内容がリモートリポジトリに入りました！

![%E6%88%AA%E5%B1%8F2022-12-11_15.01.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2988308/4d14fcfc-926e-6005-6fc4-08895e34f012.png)


続いて、Nextのページを追加していきます。

## Nextにページを追加

### Nextのプロジェクトの構成

まずリポジトリーの構成を確認してみます！

**pagesのディレクトリ**

Nextには**pages**というページをまとめて管理するディレクトリが存在します。

ここに入ってるtsx(かjsx)ファイルが一つのルートになります。

例：

- `index.tsx` → `localhost:3000/` になります（indexだけちょっと特殊）
- `test.tsx` →`localhost:3000/test`になります
- `about/feifei.tsx`→`localhost:3000/about/feifei`になります（階層ができる！）

ちなみに`localhost:3000/post/001`みたいなダイナミックなルーティングもできます。

![%E6%88%AA%E5%B1%8F2022-12-11_15.07.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2988308/68e9acfa-b837-76f4-c619-68c4ab03b479.png)


**pages/apiのディレクトリ**

おまけに説明しますが、Next x Vercelでデプロイする際に、このapiディレクトリの配下のファイルがserverless functionになります。apiエンドポイントが簡単にできてしかもVercel無料枠で作れます！今回は詳しい説明を割愛しますがとても使いやすいです。

例：`api/hello.ts` → `localhost:3000/hello`がapiエンドポイントになります。

### ページを作成

まず、

`npm run dev`でアプリを起動します。

`index.tsx`がこうなります！

![%E6%88%AA%E5%B1%8F2022-12-11_15.34.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2988308/c42d1cee-cb28-11ac-b209-27f027fd6d5d.png)


test.tsxというファイルを作成(=ページを作成)

![%E6%88%AA%E5%B1%8F2022-12-11_15.39.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2988308/8bebd00a-22b6-ec0f-1e79-ab46d24490e6.png)


中身はそんなに重要ではないのですが一応こうなります。

```tsx
import Head from 'next/head'
import Image from 'next/image'
import styles from '../styles/Home.module.css'

export default function Test() {
    return (
        <div className={styles.container}>
            <Head>
                <title>Create Next App - test</title>
                <meta name="description" content="Generated by create next app" />
                <link rel="icon" href="/favicon.ico" />
            </Head>

            <main className={styles.main}>
                <h1 className={styles.title}>
                    こちらはテストページの画面です！
                </h1>

                <p className={styles.description}>
                    Get started by editing{' '}
                    <code className={styles.code}>pages/test.tsx</code>
                </p>

            </main>

            <footer className={styles.footer}>
                <a
                    href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
                    target="_blank"
                    rel="noopener noreferrer"
                >
                    Powered by{' '}
                    <span className={styles.logo}>
                        <Image src="/vercel.svg" alt="Vercel Logo" width={72} height={16} />
                    </span>
                </a>
            </footer>
        </div>
    )
}
```

## VercelでGitHubリポジトリの紐付ける設定をつける

さてさて、最新状態をGitHubにプッシュしたら肝心なVercelの設定に入ります！

### Vercelの下準備

Vercelのアカウントを記事を書く前に作ってしまったのでこの部分の説明はできませんが、概ね以下のことになります。

1. アカウント作成
2. Import Git Repositoryの設定　→ Add GitHub Org or Account選択
3. GitHubに連携するためのGitHubリポジトリにVercelアプリをインストールする画面が出ます
4. そこでAll repositoryにインストールするよりも、入れたいリポジトリだけに入れる方が無難なので、**Only select repositories**を選択してvercelに連携したいリポジトリだけにインストールするようにしましょう

**※Import Git Repositoryで、連携したいリポジトリが見つからない時**

もし、先程のVercelアプリとGitHubリポジトリの連携が失敗しても、手動で権限付与できます。

まずは**Adjust GitHub App Permissions**をクリック

![%E6%9C%AA%E5%91%BD%E5%90%8D.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2988308/ea9f4bd0-5d59-7689-53e0-76d6e7d29521.png)


次にGitHubの画面が出ますが、**Select repositories**にデプロイしたいリポジトリを選択すれば大丈夫です！

![%E6%9C%AA%E5%91%BD%E5%90%8D 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2988308/260841b5-f955-d3c8-842e-71d79d763bed.png)

vercel_is_awesomeを追加して、**save**します。

![%E6%88%AA%E5%B1%8F2022-12-11_16.29.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2988308/a82be348-1951-ac69-87fe-01d8153aee9f.png)

Vercelの画面に戻ったら、**vercel_is_awesome**が出るようになったので、**import**します。

![%E6%9C%AA%E5%91%BD%E5%90%8D 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2988308/cdc86279-537e-9d64-34d1-a4e9bf62b949.png)

あと少しです。

Project Nameに自動的にリポジトリ名が入り（ちなみにproject nameもドメイン名になるので、今回の場合だと`vercel-is-awesome.vercel.app`が自動的に付いてくるのです）、Frameworkも自動的にNextであることをわかってくれました！今回特にRoot directoryをいじる必要がないのでそのままdeployして進みます！

![%E6%88%AA%E5%B1%8F2022-12-11_16.33.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2988308/e1a1461b-00cb-ec8f-056d-d7d72b8c674d.png)

デプロイ中…

![%E6%88%AA%E5%B1%8F2022-12-11_16.37.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2988308/6671a4a6-7a56-b932-9972-6344afe1b96b.png)

できました！

![%E6%88%AA%E5%B1%8F2022-12-11_16.38.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2988308/9d70b048-6d97-23a0-3fac-1dd43ae3a7d2.png)

`vercel-is-awesome.vercel.app`にアクセスすると、画面が出ました！

![%E6%88%AA%E5%B1%8F2022-12-11_16.39.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2988308/82fd5348-9842-578f-008c-ccf5af2d3897.png)

`vercel-is-awesome.vercel.app/test`の画面もちゃんとあります！

![%E6%88%AA%E5%B1%8F2022-12-11_16.40.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2988308/8c94d9bc-8e3e-e826-8dfa-2023eb462561.png)


GitHubリポジトリの方もEnvironmentが追加されました！

![%E6%88%AA%E5%B1%8F2022-12-11_17.07.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2988308/3e09ebd6-a92b-5d51-88cf-3c1309ace688.png)

Deployed by vercelです。

![%E6%88%AA%E5%B1%8F2022-12-11_17.07.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2988308/e730eb1c-3e50-832f-0b8a-a81ea151a421.png)


# 結果

Next.js x Vercel x GitHubで、スムーズにデプロイすることができました！

Vercelでデプロイすると、無料枠で自動的にSSL証明書が付いてきて、良さげなドメイン名にもなります。

今回は触れておりませんが、serverless functionも作れますし、environment variablesなども簡単に設定ができる利点があります。（環境ごとapiエンドポイントを変えたい、apiエンドポイントやキー隠したい等）

そして毎回紐付けたブランチにプッシュする際に、previewの画面が出ます。preview画面を確認して問題なければ更新するような形になります。

新しいfeatureブランチを切って、新機能あるいは修正をして、別なところにデプロイして確認ができたら本番環境を更新する手間がなくなります。

個人のプロジェクトにとって最適ではないかと思います！

# おわりに

最後まで読んで頂き、ありがとうございます！
今度チャンスあればNext x Vercelでserverless functionを作る記事も書いてみたいです=v=

また、KWCのアドベントカレンダーはまだまだ続くのでお楽しみに！

# 関係リンク

今回の流れでデプロイされたサイト

[https://vercel-is-awesome.vercel.app/](https://vercel-is-awesome.vercel.app/)

リポジトリ

[https://github.com/f3if3i/vercel_is_awesome](https://github.com/f3if3i/vercel_is_awesome)