NextJSで静的ページを公開するまで【Page Router】

# はじめに
Next.jsとは、数あるフロントエンドフレームワークの中で**6年連続**使用率1位を獲得しているほど現在人気を博している、非常に優れたフレームワークです！
引用: https://2023.stateofjs.com/ja-JP/libraries/front-end-frameworks/

今回はそんなNext.jsを使用してサイト作成の基礎を学ぶことを目指します！

さっそく、基礎知識としていくつかの用語を解説していきます！

## ReactとNext.jsの違い
Next.jsの開発をしているとよくReactというライブラリが出てきます。
初めはReactとNext.jsが混同されることが多かったので、ざっくりと何が違うのかをお伝えします！

**React**・・・UIを表示するためのコンポーネントを作成するライブラリ
**Next.js**・・・ルーティングやSEO、レンダリング方式を簡単に扱えるフレームワーク

このように、Reactで作成した部品をNext.jsでアプリやサイトに組み込んでいくという関係です。
はじめはざっくりとこれがわかっていれば大丈夫だと思います！

## Page Router、App Routerとは？
この記事で作成するものは`Page Router`を使用したWebページになります。

具体的に何が違うのかというと、`静的ページ`か`動的ページ`かの違いで、
めっちゃ簡単にいうとただのWebサイトか、アプリかの違いです！

なぜ分ける必要があるのかというと、ユーザーに表示する際のレンダリング方式が異なるためです。

## レンダリング方法とは？
そもそもレンダリングとは、プログラムを画面に表示できる形に変換するプロセスを指します。
`Page Router`と`App Router`のレンダリング方式の違いは以下の通りです。

**Page Router**・・・SSG (Static Site Generation)
**App Router**・・・SSR (Server Side Rendering)

SSGは`事前`にビルドを行います。
ビルドは、ソースコードが完成して公開する前に一度だけ行います。
ユーザーがURLにアクセスした際、事前にビルドしたものを即座に提供します。
そのため、全てのユーザーに同じ内容を見せる`ポートフォリオサイト`や`LPサイト`などに使用されます。

SSRは`ユーザーがアクセスするたび`にビルドを行います。
ユーザーがURLにアクセスした際、毎回ビルドしてからデータを提供します。
そのため、ユーザーごとに異なる内容を見せるアプリケーションに使用されます。

# プロジェクトの作成
それではさっそく開発の準備を進めていきます！

## 環境確認
Next.jsプロジェクトの作成には`npx`、
動作環境として`Node.js`が必要です！
```bash
node -v # バージョンが表示されていればOK
v21.7.3

npm -v # バージョンが表示されていればOK
10.8.2
```

## Next.jsプロジェクトの作成
Next.jsのコードをまとめるディレクトリを作成します！
任意の場所に移動し、特に指定がない場合はデスクトップなどわかりやすい場所に以下のコマンドを実行します。
```bash
npx create-next-app next-site

# 実行後、選択肢が表示されるので以下のように選択してください。
Ok to proceed? (y) y

✔ Would you like to use TypeScript? … No
# TypeScriptを使用しますか？

✔ Would you like to use ESLint? … No
# ESLint (コードチェックツール) を使用しますか？

✔ Would you like to use Tailwind CSS? … No
# Tailwind CSS (CSSフレームワーク) を使用しますか？

✔ Would you like your code inside a `src/` directory? … Yes
# コードを`src/`ディレクトリに格納しますか？

✔ Would you like to use App Router? (recommended) … No
# App Router (ルーティング) を使用しますか？

✔ Would you like to use Turbopack for `next dev`? … No
# Turbopack (ビルドツール) を使用しますか？

✔ Would you like to customize the import alias (`@/*` by default)? … No
# インポートエイリアスをカスタマイズしますか？
```
すると、`next-site`というディレクトリが作成されます！

:::note info
今回は `next-site` というプロジェクト名で作成しましたが、
プロジェクトの命名は自由です！
:::

次に、作成したプロジェクトに移動します。
```
cd next-site
```
インストールが完了した段階ですでにNext.jsのデモページが作成されています。
一度この状態で実行してみましょう！
```bash
npm run dev
```
すると以下のようなログが表示されるので、`Local`のURLにアクセスしてみてください。
```bash
> next-site@0.1.0 dev
> next dev

   ▲ Next.js 15.1.5
   - Local:        http://localhost:3000

 ✓ Starting...
 ✓ Ready in 201ms
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3794632/7db825eb-576d-32d0-6835-bdecdfb3367b.png)
このような画面が表示されていれば成功です！

:::note info
初期状態のNext.jsページレイアウトは将来的に変更される可能性があります。
とりあえずNext.jsのページが何らか表示されていれば成功と言えます！
:::

# ファイルの解説
一度に多くのファイルやディレクトリがインストールされますが、
それぞれに意味があるため、一つ一つ解説していきます！

## public/
このディレクトリにはWebページで使用する画像を格納します！
既に多数存在する `.png`や`.svg`ファイルはNext.jsのデモサイトで使用されている画像です！

## src/
ページに関連するソースコードは基本的にこのディレクトリ内に記述します！

### api/
Next.jsプロジェクト内でAPIを簡単に作成でき、このディレクトリに記述することでルーティングも自動で行われます！
（今回の解説では使用しないため詳細は省略します）

### _app.js
アプリ全体の共通設定やレイアウトを定義するファイルです。

### _document.js
HTMLの全体構造（<html>, <body>, <head>など）のカスタマイズが可能です。

### index.js
ここにメインのコードを記述します。
HTMLで言うところの`index.html`と同じ役割を担います！

# カスタマイズ
それでは新規作成したプロジェクトの中身を変更していきましょう！

## 初期ページソースコードのリセット
まずはNext.jsの標準サイトで使用されていて不要なものを削除します。

- `public/` ディレクトリの中身を削除
- `src/pages/api` ディレクトリとその中身を削除
- `src/styles/globals.css` ファイルの中身を全て削除
- `src/styles/Home.module.css` ファイルの中身を全て削除
- `src/pages/index.js` ファイルの中身を全て削除し、以下のコードに置き換えます。
```jsx:index.js
import Head from "next/head";
import styles from "@/styles/Home.module.css";

export default function Home() {
  return (
    <>
      <Head>
        <title>Create Next App</title>
        <meta name="description" content="Generated by create next app" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <link rel="icon" href="/favicon.ico" />
      </Head>
      <div>
        <h1>Hello World</h1>
      </div>
    </>
  );
}
```

## 主な開発の手順
主に`src/pages/index.js`ファイルと `src/styles` ファイルのコードを書き換えてページを作成していきます！

### 通常と異なる記述
現在`index.js`には `<h1>Hello World</h1>`という記述がありますが、この部分を変更していきます。
変更の方法は基本的に通常のHTMLと変わりませんが、CSSの記述が以下のように変わります。

```jsx
<div>
    <h1 className={styles.headline}>Hello World</h1>
</div>
```
まず、通常`class`で割り当てるクラス名は`className`属性に変わります。
次に、`index.js`の2行目に以下のような記述があります。
```jsx
import styles from "@/styles/Home.module.css";
```
こちらはCSSを「styles」という名前で読み込んでいます。
つまり、h1の記述は`@/styles/Home.module.css`内の`headline`というクラスを割り当てる
という意味になります。

このコードを動作させるには、 `src/styles/Home.module.css`に以下の記述を追加する必要があります。
```css
.headline {
  color: red;
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3794632/100be464-fef8-ca87-08c6-22506fc296d1.png)
これで赤色の`Hello World`が表示されます！

## 画像の読み込み
先ほど `public/`ディレクトリに画像を格納すると説明しましたが、
imgタグで読み込む画像のパスは `public/`から始まるパスでは動作しません！
```jsx
<img src="public/apple.png" alt="どくりんご" />
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3794632/d883f6ab-fdf3-cba4-aa5b-028456229ae6.png)
どくりんごになっちゃいました...

ではどのように読み込めば良いかというと、
単純に `public/` を省略するだけで動作します！

```jsx
<img src="/apple.png" alt="どくりんご" />
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3794632/2438ed5e-f5cd-545e-4bb3-adadebe997a3.png)
正常に表示されました！

imgタグに限り、`public/`ディレクトリのパスの`public`は省略しなければならない特殊なルールがあります。
これで画像の表示も可能になりました！

# 終わりに
今回は全体的にざっくりとした解説しか行っていないため、まだまだ説明しきれていない項目は多くありますが、
今回の目的はNext.jsでサイト作成の基礎を学ぶことなので、ここまでとします！