Next.js + TypeScript + Rechartsで株価チャートを表示するところまでやってみた【App Router構成】

最近、株式投資を効率化するツールを個人開発しようと思い立って、まずは**フロントエンドで株価チャートを表示できるところまで**進めてみました。

せっかくなので、**Next.js + TypeScript + Tailwind CSS + Recharts** を使って、**MSFT（Microsoft）の株価チャート**を描画するまでのセットアップの流れをメモしておきます。

---
## 前提
Webアプリ初心者です。Pythonは業務で少し使っているので、今回WebAppの勉強がてら、Pythonでバックエンド処理を作って表示だけフロントエンドのお手軽サービスを使えば、完全にゼロからではないので勉強しやすく、かつ役立つものを作れるのではないかとトライしてみた素人のメモです。

## 環境
OS : Windows11
Platform : VScode on WSL2 Ubuntu24

## トライ内容

### 1. WSL2 + Ubuntu で Next.js プロジェクトを作成（TypeScript + App Router構成）

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

* ESLint / Tailwind CSS → どちらも `Yes`
* `App Router`（`src/app/`）構成で生成される（これに最初戸惑った）
* `pages/` ディレクトリがないので、最初「アレ？」ってなるけど、`src/app/` の中に `page.tsx` や `layout.tsx` があるのが今のやり方らしい

### ⚠️ 躓いたポイント（メモ）

* `useEffect`, `useState` を使おうとしたら `use client` を冒頭に書かないとエラーになる（App Router構成では必須）
* `PriceData` 型に `data` プロパティがあると型エラーになる（正しくは `date: string`）
* `npm audit` で脆弱性が出るが、開発用なら無視でOK（Recharts経由の依存ライブラリ）

---

### 2. `/dashboard` ページを作成して Recharts のチャートを表示

```bash
npm install recharts
```

作ったファイル：`src/app/dashboard/page.tsx`

```tsx
'use client'

import { useEffect, useState } from 'react'
import {
  LineChart, Line, XAxis, YAxis, Tooltip, CartesianGrid, ResponsiveContainer,
} from 'recharts'

interface PriceData {
  date: string
  price: number
}

const API_KEY = 'YOUR_API_KEY' // Alpha Vantage で取得したキーに変更

export default function DashboardPage() {
  const [data, setData] = useState<PriceData[]>([])

  useEffect(() => {
    async function fetchData() {
      const res = await fetch(
        `https://www.alphavantage.co/query?function=TIME_SERIES_DAILY_ADJUSTED&symbol=MSFT&apikey=${API_KEY}`
      )
      const json = await res.json()
      const timeSeries = json['Time Series (Daily)']

      if (timeSeries) {
        const parsed: PriceData[] = Object.entries(timeSeries)
          .slice(0, 30)
          .map(([date, info]: any) => ({
            date,
            price: parseFloat(info['4. close']),
          }))
          .reverse()

        setData(parsed)
      }
    }

    fetchData()
  }, [])

  return (
    <main>
      <h1 className="text-2xl font-bold mb-4">MSFT 株価チャート</h1>
      <div className="h-[300px] w-full">
        <ResponsiveContainer width="100%" height="100%">
          <LineChart data={data}>
            <CartesianGrid strokeDasharray="3 3" />
            <XAxis dataKey="date" />
            <YAxis />
            <Tooltip />
            <Line type="monotone" dataKey="price" stroke="#00bcd4" strokeWidth={2} />
          </LineChart>
        </ResponsiveContainer>
      </div>
    </main>
  )
}
```

---

### 3. ナビゲーションを追加（`layout.tsx`）

```tsx
import './globals.css'
import Link from 'next/link'
import { ReactNode } from 'react'

export default function RootLayout({
  children,
}: {
  children: ReactNode
}) {
  return (
    <html lang="en">
      <body className="min-h-screen font-sans bg-white text-black dark:bg-black dark:text-white">
        <nav className="p-4 bg-gray-100 dark:bg-gray-800 text-sm flex gap-4">
          <Link href="/" className="hover:underline">Home</Link>
          <Link href="/dashboard" className="hover:underline">Dashboard</Link>
        </nav>
        <main className="p-4">{children}</main>
      </body>
    </html>
  )
}
```
## 結果画面

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2510530/88dabdb7-306d-4bbe-b0f8-6dc95cd17c3b.png)
画像はAAPLとMSTFの間違いだが、一応ちゃんと表示された。
マウスオーバーでポイントも出来るので、ちゃんとそれっぽいグラフに見える。

Pythonになれているせいか、Streamlitの方が簡単で高機能に作れるが、Streamlitはインタラクティブな波形の描画に限界があるので、今後のアップデートで差分を把握していきたい。

---

## ✅ 今後やる予定

* FastAPI（Python）でバックエンドAPIを立てる
* フロントからFastAPI経由で株価取得・保存
* テクニカル分析（RSI, MACD, VWAPなど）の自動計算
* AWSにホストして定期通知 or アラート出す

---

## 📍 所感メモ

* App Router構成は最初ちょっと混乱するけど、慣れるとレイアウトやAPIの扱いがかなり綺麗
* Recharts はシンプルで使いやすい。分析ツールを作るなら第一選択肢になりそう
* Alpha Vantage の制限（1分5回）はあるけど、学習＆個人開発レベルなら十分

---

以上、Next.js のフロントで株価を表示するところまでのセットアップでした。
続きは FastAPI 編に進む予定です☕️