0からNext.jsで作成したWebアプリをVercelで公開するまで

# はじめに
Next.jsで作成したWebアプリをネット上に載せる情報があまりなかったので、主に手順を説明する記事を作成しようと思いました。

# 準備
以下のサイトを参考にしてください。
### Node.js
windows
https://magazine.techacademy.jp/magazine/16050
### Git
windows
https://qiita.com/T-H9703EnAc/items/4fbe6593d42f9a844b1c
mac
https://zenn.dev/mesgory/articles/948876ac1b7517
### GitHub
https://qiita.com/Baru_Try/items/e80a765919a35a3c28c7
### VSCode
windows
https://qiita.com/YurimyMiyu/items/5ce7821f1e3e5905c3ee
mac
https://qiita.com/cleyera_f/items/24bf47321fb3af05714f

### Vercel
https://vercel.com/

# 環境
mac OS：14.4.1
VSCode：1.89.0
Node.js：20.12.2
Next.js：14.2.4
Git：2.39.3

# 公開までの手順

### プロジェクト作成
ここからプロジェクトを作成していきます。
まず、プロジェクトフォルダを入れるディレクトリを作成します。私は、next_testというディレクトリを作成しました。
次にターミナルでそのディレクトリへ移動してください。「cd ディレクトリ名」で移動できます。
```terminal
xxxxxxxx:next_test xxxxx$ 
```
ターミナルがこのようになったらOKです。
次に
```
npx create-next-app@latest
```
とターミナルに入力して実行してください。そうすると、
```
? What is your project named? › my-app
```
このように表示されると思います。
my-appの部分に任意のプロジェクト名を記述します。
今回はこのままmy-appでいきます。
プロジェクト名を決めてEnterを押すと、いくつか質問が来ると思います。
![スクリーンショット 2024-07-05 9.17.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3758008/c605176b-699c-3ae4-64bf-0f0fcc0f98f5.png)
このように回答してください。
実行してSuccessと出たら成功です。
next_testフォルダ内を見てみると、my-appフォルダができていることがわかります。
次にmy-appフォルダをVSCodeで開いてください。
![スクリーンショット 2024-07-05 9.23.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3758008/6368982d-bff4-bdf4-5fd9-4a514276f536.png)
このような画面になっているはずです。
ここで一部分だけ変更します。
next.config.mjsがデフォルトで、
```next.config.mjs 
/** @type {import('next').NextConfig} */
const nextConfig = {};

export default nextConfig;
```
このようになっていると思いますが、
```next.config.mjs 
/** @type {import('next').NextConfig} */
const nextConfig = {
    output: 'export'
};

export default nextConfig;
```
このように変更してください。
この設定をすることで、VercelやGitHub Pagesへデプロイできるようになります。

:::note warn
手を加えるファイルはまだこれだけです。
:::


### ローカルで確認
ではローカルでこのプロジェクトを確認してみたいと思います。
⌘+JでVSCode内にてターミナルを開いてください。
そこで
```
yarn dev
```
と入力して実行してください。
すると、
```
yarn run v1.22.22
$ next dev
 ⚠ Port 3000 is in use, trying 3001 instead.
 ⚠ Port 3001 is in use, trying 3002 instead.
  ▲ Next.js 14.2.4
  - Local:        http://localhost:3002

 ✓ Starting...
 ✓ Ready in 2.6s
```
このような出力がされると思います。
私はポート3000と3001使ってしまっているため、localhosy:3002へアクセスする必要がありますが、基本的にはlocalhost:3000になっていると思います。
そしたら、http://localhost:3000
にアクセスしてみてください。
![スクリーンショット 2024-07-05 9.43.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3758008/44ffee73-3527-8a46-744f-5482e5bdcaba.png)
このように開けたら成功です。
これはデフォルトなのでイメージとしては、これを自分なりに編集してwebアプリケーションを作成していきます。

### GitHubにコミット・プッシュ
ではこれをGitHubにコミット・プッシュしていきます。
まずGitHub上でレポジトリーを作成します。
![スクリーンショット 2024-07-05 9.49.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3758008/b1da8040-1ff5-d18d-4b64-ff537ef5efd2.png)
この画面の右上の「New」ボタンを押してレポジトリーを作成していきます。
![スクリーンショット 2024-07-05 9.53.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3758008/df429399-e41d-dd7c-3310-a3f0d19392bc.png)
この画面で任意のレポジトリーの名前を決めていきます。
私はNext_Test_Appにしました。
このレポジトリーの名前がサイトのURLで使用されます。
この他は手を加えなくて大丈夫です。
Create Repositoryボタンを押すと、
![スクリーンショット 2024-07-05 10.04.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3758008/07f4973e-3347-4ea8-c068-a30fe744c854.png)
この画面になります。
上の囲っている部分を一つずつVSCode内のターミナルで実行していきます。
まず、さっきのとは別のターミナルを開きたいので、右側にある「＋」ボタンを押して、ターミナルを開きます。
そこでさっきのを実行します。
実行が終わり、GitHubをリロードして確認すると、フォルダやファイルがたくさんあると思います。これで、最初のコミット・プッシュは成功です。

### GitHub Pagesを設定
次に、GitHub Pagesを設定します。
GitHubサイトで「Settings」->「Pages」を開いてください。
![スクリーンショット 2024-07-05 10.23.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3758008/9e0682e9-912e-dc2b-cfe2-3893ff8e49a0.png)
この画面になるはずです。
このBranchのところのNoneをmainへ変えて、saveボタンを押してください。
これでGitHub Pagesの設定はOKです。

### VSCodeで少し編集
少しサイトを編集します。
まずターミナルで
```
npx shadcn-ui@latest init
```
を実行します。
これも３つほど質問が来るのですが、答え方は、Default、Zinc、yesの順番で答えてください。
次に
```
npm install tailwindcss-animate
```
を実行します。
そしてyarn devを実行したターミナルをもう一度開いて「control+c」で実行を抜けて、もう一度
```
yarn dev
```
を実行してください。
次に以下のように指定のファイルを変更してください。
```page.tsx
export default function Home() {
  return (
    <div>
        <h2 className="font-bold" style={{fontSize: `20px`, margin: `3%`}}>
          ホーム画面
        </h2>
    </div>
  );
}
```
```layout.tsx
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import Link from "next/link";
import { cn } from "@/lib/utils";

const inter = Inter({ subsets: ["latin"] });

export const metadata: Metadata = {
  title: "Create Next App",
  description: "Generated by create next app",
};
const navItems = [
  { label: 'home', href: '/'},
  { label: 'about', href: '/about'},
  { label: 'content', href: '/content'},
]

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="ja">
      <body className={cn(inter.className, 'min-h-dvh')} style={{background: `#F2F2F2`,}}>
      <header className="container h-16 flex items-center border-b justify-between" style={{background: `#FFF`}}>
          <h1 className="font-bold">next-test-app</h1>
          <ul className="flex gap-4">
            {navItems.map(item => <li key={item.label}>
              <button>
                <Link href={item.href}>{item.label}</Link>
              </button>
            </li>)}
          </ul>
        </header>
        {children}
      <footer className="container sticky top-full h-16 flex items-center border-t">
      <p>next-test-app</p>
      </footer>
      </body>
    </html>
  );
}
```
次にappフォルダ下にaboutフォルダとcontentフォルダを作成してください。
そしてどちらのフォルダにもpage.tsxを作成してください。
中身は以下のように。
```./app/about/page.tsx
"use client"
export default function About() {
    return (
      <div>
          <h2 className="font-bold" style={{fontSize: `20px`, margin: `3%`}}>
            about画面
          </h2>
      </div>
    );
}
```
```./app/content/page.tsx
"use client"
export default function Content() {
    return (
      <div>
          <h2 className="font-bold" style={{fontSize: `20px`, margin: `3%`}}>
            content画面
          </h2>
      </div>
    );
}
```
今フォルダは
![スクリーンショット 2024-07-05 11.13.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3758008/a3b403f5-0bfb-d8b6-bcee-276f7e4ecd5c.png)
こんな感じになっています。
これでVSCodeでの編集は以上です。

### コミット・プッシュ
ではコミット・プッシュしていきます。
VSCodeの左のバーから、ソース管理を選択します。
すると、
![スクリーンショット 2024-07-05 11.47.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3758008/62e047b5-0c2e-30f2-c768-8c4484652be5.png)
このような画面になるはずです。
このメッセージのところに「２回目コミット」と入力し、「コミット」ボタンを押してください。
次に「変更の同期」ボタンを押してください。
そうしたら変更部分のコミット・プッシュは完了です。
GitHubで確認してみましょう。
![スクリーンショット 2024-07-05 11.52.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3758008/2573bf0c-9f96-91e0-f199-326533ff46f8.png)
このように、２回目コミットと書かれたファイル・フォルダがたくさんあったら成功です。

### Vercelを設定し、公開
最後にVercelを設定し、公開できるようにします。
https://vercel.com
にアクセスしてください。
GitHubと連携してログインすると、
![スクリーンショット 2024-07-08 10.12.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3758008/81e4d03b-eeeb-44b6-785d-2a06a32a948a.png)

この画面になるはずです。
このデプロイしたいレポジトリのImportボタンを押してください。
![スクリーンショット 2024-07-08 10.14.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3758008/ce433053-8e19-9040-a1e4-6f87e86f417d.png)
そしたらdeployボタンを押してデプロイを開始してください。
デプロイが完了すると、
![スクリーンショット 2024-07-08 10.18.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3758008/ca7ba785-2f6d-1f32-ca95-50ecc52a9506.png)
この画面になります。
Continue to Dashboardボタンを押すと、
![スクリーンショット 2024-07-08 10.19.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3758008/28af0890-46a3-6d19-d1a1-3de4a8a6a5f4.png)
この画面になり、DomainsのURLをクリックすると、自分が公開したwebサイトを閲覧することができます。
これでVercelを使って公開ができました。
![スクリーンショット 2024-07-08 10.47.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3758008/89130056-2c8f-b16b-b330-aeddbcb8133a.png)


# 公開してからの編集方法
ここからは公開してからの編集方法について説明します。
### VSCodeで編集
まずVSCodeで編集します。
VSCodeのターミナル上で
```
npx shadcn-ui@latest add button
```
これを実行してください。
次に以下のようにファイルの内容を変更してください。
```./app/page.tsx
import { Button } from "@/components/ui/button";
import Link from "next/link";

export default function Home() {
  return (
    <div className='flex flex-col items-center'> 
        <div className='flex flex-col items-center' style={{background: `#FFF`, margin:`20%`, marginTop: '5%', marginBottom: '5%', padding: `5%`, paddingBottom: `2%`, paddingTop: `2%`, width: '90%'}}>
          <h2 className="font-bold" style={{fontSize: `25px`}}>
            home
          </h2>
        </div>
        <div className='flex flex-col items-center' style={{background: `#FFF`, margin:`20%`, marginTop: '0%', marginBottom: '5%', padding: `5%`, width: '60%'}}>
          <h3 className="font-bold" style={{fontSize: `20px`, marginTop: '5%'}}>
            about画面はこちらから
          </h3>
          <Button variant="destructive" asChild style={{margin: `5%`}}>
            <Link href="/about">about</Link>        
          </Button>
        </div>
        <div className='flex flex-col items-center' style={{background: `#FFF`, margin:`20%`, marginTop: '5%', marginBottom: '5%', padding: `5%`, width: '60%'}}>
          <h3 className="font-bold" style={{fontSize: `20px`, marginTop: '5%'}}>
            content画面はこちらから
          </h3>
          <Button variant="destructive" asChild style={{margin: `5%`}}>
            <Link href="/content">content</Link>              
          </Button>
        </div>
       
    </div>
  );
}
```
```layout.tsx
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import Link from "next/link";
import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";

const inter = Inter({ subsets: ["latin"] });

export const metadata: Metadata = {
  title: "Create Next App",
  description: "Generated by create next app",
};
const navItems = [
  { label: 'home', href: '/'},
  { label: 'about', href: '/about'},
  { label: 'content', href: '/content'},
]

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="ja">
      <body className={cn(inter.className, 'min-h-dvh')} style={{background: `#F2F2F2`,}}>
      <header className="container h-16 flex items-center border-b justify-between" style={{background: `#FFF`}}>
          <h1 className="font-bold">next-test-app</h1>
          <ul className="flex gap-4">
            {navItems.map(item => <li key={item.label}>
              <Button variant="ghost" asChild>
                <Link href={item.href}>{item.label}</Link>
              </Button>
            </li>)}
          </ul>
        </header>
        {children}
      <footer className="container sticky top-full h-16 flex items-center border-t">
      <p>next-test-app</p>
      </footer>
      </body>
    </html>
  );
}
```

### ローカル上で確認
変更したらlocalhostにアクセスして変更内容を確認してください。
![スクリーンショット 2024-07-08 11.21.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3758008/e7ec8223-973e-8cd7-cdd0-047e492eefbe.png)
このようになったらOKです。
エラーが起きてなくて問題なさそうだったら次に進みます。

### GitHubにコミット・プッシュ
次はGitHubにコミット・プッシュします。
これは最初にGitHubへコミット・プッシュした時と同じです。
左側のバーからソース管理を開いて、コミットメッセージを書き、コミットしてください。
今回は３回目コミットというメッセージにします。
そうしたら変更の同期ボタンを押してプッシュします。
無事にプッシュできたらGitHubのActionsからうまくビルド・デプロイできているか確認してください。


### Vercelで反映されるまで待つ
Vercelを開いてください。
![スクリーンショット 2024-07-08 11.29.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3758008/3b184895-1298-365a-cd24-33f18f5464c4.png)
開いてこの画面になっていたらVercel側でもデプロイ完了です。
エラーがあってデプロイがうまくいかなかった場合、「To update your Production Deployment, push to the "main" branch」のところにデプロイエラーの内容が書いてあるので、そこを確認してください。

### webを確認
先ほどのwebサイトをリロードすると変更内容が反映されると思います。

# 最後に
ぜひ新しくプロジェクトを作成して自分なりのNext.js開発をしてみてください。