Next.jsを学習した

## モダンな環境を学習したい
目にとまったNext.js,Nest.jsを学習しようと思い立った。
まずはNext.jsから。
Nest.jsはバックエンドらしいので、別の記事で。

## Next.js（フロントエンド）構築

基本、ChatGPTさんに従って実行。

⏱️ 学習目安：3〜4時間 by ChatGPT

### GitHubにリポジトリ作成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3916302/70427079-4bc3-4109-9e17-7db937384637.png)

```
C:\Users\idtrm\vscode\scacyba\profiledemo>git clone https://github.com/scacyba/profiledemo.git 
.
Cloning into '.'...
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
Receiving objects: 100% (3/3), done.
```


### 1. Next.js プロジェクトの作成
// ターミナルで以下を実行
// npx create-next-app@latest frontend --js --eslint --tailwind
いろいろ聞かれるがすべてデフォルトで。
```
idtrm@otaskacyba MINGW64 ~/vscode/scacyba/profiledemo (main)
$ ls -a
./  ../  .git/  README.md

idtrm@otaskacyba MINGW64 ~/vscode/scacyba/profiledemo (main)
$ npx create-next-app@latest frontend --js --eslint --tailwind
Need to install the following packages:
create-next-app@15.3.2
Ok to proceed? (y) y

√ Would you like your code inside a `src/` directory? ... No / Yes
√ Would you like to use App Router? (recommended) ... No / Yes
√ Would you like to use Turbopack for `next dev`? ... No / Yes
√ Would you like to customize the import alias (`@/*` by default)? ... No / Yes
Creating a new Next.js app in C:\Users\idtrm\vscode\scacyba\profiledemo\frontend.

Using npm.

Initializing project with template: app-tw


Installing dependencies:
- react
- react-dom
- next

Installing devDependencies:
- @tailwindcss/postcss
- tailwindcss
- eslint
- eslint-config-next
- @eslint/eslintrc

#結構時間かかる

added 384 packages, and audited 385 packages in 6m

138 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
Success! Created frontend at C:\Users\idtrm\vscode\scacyba\profiledemo\frontend
```

### 2. frontend/pages/index.js
```javascript:frontend/pages/index.js
export default function Home({ profile }) {
  return (
    <div className="p-6">
      <h1 className="text-4xl font-bold">{profile.name}</h1>
      <p className="mt-4 text-xl">{profile.title}</p>
      <p className="mt-2">{profile.bio}</p>
    </div>
  );
}

// 3. SSGでAPIからデータ取得
export async function getStaticProps() {
    try {
      const res = await fetch('https://your-nest-api.onrender.com/profile');
      if (!res.ok) {
        throw new Error(`API Error: ${res.status}`);
      }
      const profile = await res.json();
  
      return { props: { profile } };
    } catch (error) {
      console.error('Failed to fetch profile:', error);
      // mock:API未完成時の仮データ
      return {
        props: {
          profile: {
            name: 'オオタスカシバコンサルタント',
            title: 'ITコンサルタント / エンジニア',
            bio: 'Nest.js APIが未起動のため、仮データで表示中です。',
          },
        },
      };
    }
  }
```

### 4. next.config.mjs を静的サイト用に編集
```javascript:next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
    output: 'export',
  };
  
export default nextConfig;
```

>frontend/package.json を開き、"scripts" セクションに以下を追加してください：
⚠ すでに "scripts" がある場合は "export": "next export" の行だけ追加してください。
```frontend/package.json
"scripts": {
  "dev": "next dev",
  "build": "next build",
  "export": "next export", 
  ...
}
```

### 5. ビルドとエクスポート
// npm run build && npm run export
// → out/ フォルダが生成される（静的HTML）
```bash
cd frontend
npm run build && npm run export
・・・
 ⨯ Conflicting app and page file was found, please remove the conflicting files to continue:
 ⨯   "pages/index.js" - "app/page.js"

# インストール時に`App Router`を有効にしてたから競合したらしい
idtrm@otaskacyba MINGW64 ~/vscode/scacyba/profiledemo/frontend (main)
$ ls
app/  eslint.config.mjs  jsconfig.json  next.config.mjs  node_modules/  package.json  package-lock.json  pages/  postcss.config.mjs  public/  README.md

idtrm@otaskacyba MINGW64 ~/vscode/scacyba/profiledemo/frontend (main)
$ mv app app_pagesを使うので未使用

idtrm@otaskacyba MINGW64 ~/vscode/scacyba/profiledemo/frontend (main)
$ npm run build && npm run export

> frontend@0.1.0 build
> next build

   ▲ Next.js 15.3.2

 ✓ Linting and checking validity of types    
   Creating an optimized production build ...
 ✓ Compiled successfully in 1000ms
 ✓ Collecting page data    
Failed to fetch profile: Error: API Error: 404
    at P (C:\Users\idtrm\vscode\scacyba\profiledemo\frontend\.next\server\pages\index.js:1:1861)
 ✓ Generating static pages (3/3)
 ✓ Collecting build traces    
 ✓ Finalizing page optimization    

Route (pages)                                Size  First Load JS
┌ ● / (799 ms)                              362 B        92.3 kB
└ ○ /404                                  2.47 kB        94.4 kB
+ First Load JS shared by all             91.9 kB
  ├ chunks/framework-2f335d22a7318891.js  57.7 kB
  ├ chunks/main-4c23680d4b230a3e.js         32 kB
  └ other shared chunks (total)           2.23 kB

○  (Static)  prerendered as static content
●  (SSG)     prerendered as static HTML (uses getStaticProps)


> frontend@0.1.0 export
> next export

 ⨯ 
    `next export` has been removed in favor of 'output: export' in next.config.js.
Learn more: https://nextjs.org/docs/app/building-your-application/deploying/static-exports
```
エラー出るけどいいらしい。
v15以降は output: 'export' 指定でビルドに含まれる。とのこと。by ChatGPT
どういうこと？ともう一回尋ねると
>npm run build を実行すると…
静的HTML（out/ フォルダ）が自動で生成されるようになります。
つまり npm run export はもう不要 です。

→不要なんかい！←ChatGPTはv13のつもりだったらしいけど。

ブラウザで動作確認OK。mockデータが表示される。
/frontend/out/index.html


### 6. GitHubにPushしてRenderで "Static Site" として無料公開
RenderにGithub連携でアカウント作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3916302/7e9331d4-f7f4-436e-a9d0-478338a4e3f7.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3916302/7560dc5c-cf4a-4592-a5ea-4dcd2520887c.png)

静的サイト
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3916302/33ed7581-e6bf-4831-aa7f-edbcb946b016.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3916302/24a0b7cc-7e4b-4816-8743-8e0541de705d.png)

リポジトリを指定して`Install`：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3916302/f0cf49b7-7c55-4972-b641-c6584bbb4f2d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3916302/2fb7935f-5e79-4af2-a66e-828b5a7586e4.png)
>✅ 次にやること（この画面で）
リポジトリを選択
　→ 表示されている scacyba / profiledemo をクリックしてください。
>
設定画面が表示されたら以下を入力：
>
項目	入力内容
Name	profile-site（自由でOK）
Root Directory	frontend（←ここ重要！）
Build Command	npm run build
Publish Directory	out

設定して、`Deploy static site`
※その前にgithubにpush忘れずに。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3916302/8d179bd6-08c7-45e0-8df5-b23f1d04055e.png)

デプロイのコンソールログ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3916302/09b84483-280d-447c-91e8-f5cb622120c5.png)
```
==> Cloning from https://github.com/scacyba/profiledemo
==> Checking out commit 9af93197577d02a3381ed9f317863a4e28d73ac7 in branch main
==> Installing dependencies with npm...
==> Using Node.js version 22.14.0 (default)
==> Docs on specifying a Node.js version: https://render.com/docs/node-version
==> Using Bun version 1.1.0 (default)
==> Docs on specifying a bun version: https://render.com/docs/bun-version
added 391 packages, and audited 392 packages in 18s
142 packages are looking for funding
  run `npm fund` for details
found 0 vulnerabilities
up to date, audited 392 packages in 1s
142 packages are looking for funding
  run `npm fund` for details
found 0 vulnerabilities
==> Running build command 'npm run build'...
> frontend@0.1.0 build
> next build
⚠ No build cache found. Please configure build caching for faster rebuilds. Read more: https://nextjs.org/docs/messages/no-cache
   ▲ Next.js 15.3.2
   Linting and checking validity of types ...
   Creating an optimized production build ...
 ✓ Compiled successfully in 3.0s
   Collecting page data ...
   Generating static pages (0/3) ...
Failed to fetch profile: Error: API Error: 404
    at P (.next/server/pages/index.js:1:1861)
 ✓ Generating static pages (3/3)
   Finalizing page optimization ...
   Collecting build traces ...
   Exporting (0/3) ...
Route (pages)                                Size  First Load JS
┌ ● / (378 ms)                              362 B        92.9 kB
└ ○ /404                                    190 B        92.8 kB
+ First Load JS shared by all             92.6 kB
  ├ chunks/framework-2f335d22a7318891.js  57.7 kB
  ├ chunks/main-ef7adcb06c400f9e.js       33.9 kB
  └ other shared chunks (total)             950 B
○  (Static)  prerendered as static content
●  (SSG)     prerendered as static HTML (uses getStaticProps)
==> Uploading build...
==> Your site is live 🎉
```

動作確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3916302/4a73872e-9cdf-4f39-92ec-72bfbdc685e2.png)

### ここまでの所要時間
休憩込み2H

### 次は
Nest.jsでバックエンドだ！