Skip to content
DashboardNode.js

Next.js Analytics Dashboard

App Router + Tailwind dashboard with KPI cards and a Recharts line chart.

Open in builder →

7 steps

Shell

Shown with defaults: npm, pip, Node LTS, Python 3.12 and the template's default add-ons.

  1. 1. Install and select Node.js with nvm

    runtime

    nvm lets you install several Node.js versions side by side and switch per project. `nvm use` activates it for this shell.

    bash
    nvm install --ltsnvm use --lts
    Expected result
    `node -v` prints the selected version.
    Verify
    node -v && npm -v
    OS notes
    macOS/Linux/WSL: install nvm with `curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.8/install.sh | bash`, then reopen the terminal. Windows: use nvm-windows (github.com/coreybutler/nvm-windows) from an elevated terminal, or fnm.
  2. 2. Scaffold a Next.js app

    template

    create-next-app generates an App Router project. Flags make it non-interactive and reflect your add-on choices (TypeScript, Tailwind, ESLint).

    bash
    npx create-next-app@latest nvx-dashboard --ts --tailwind --eslint --app --src-dir --import-alias "@/*" --use-npm --yes
    Expected result
    A ./nvx-dashboard folder with src/app, package.json and installed dependencies.
    Verify
    ls nvx-dashboard/src/app
    OS notes
    Requires Node.js 20.9 or newer. On Windows, run in PowerShell or Windows Terminal.
  3. 3. Enter the project folder

    template

    The scaffolder created ./nvx-dashboard. Move into it before installing anything else.

    bash
    cd nvx-dashboard
    Expected result
    You are inside ./nvx-dashboard
    Verify
    ls package.json
  4. 4. Add the charting library

    template

    Recharts renders responsive SVG charts from plain arrays.

    bash
    npm install recharts
    Expected result
    recharts appears in package.json dependencies.
    Verify
    npm ls recharts
  5. 5. Write the dashboard page

    template

    Replace the default home page with a client component that shows KPI cards and a chart.

    Files written by this step: src/app/page.tsx
    src/app/page.tsx
    "use client";
    
    import { useMemo, useState } from "react";
    import { CartesianGrid, Line, LineChart, ResponsiveContainer, Tooltip, XAxis, YAxis } from "recharts";
    
    const DAYS = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
    
    export default function Dashboard() {
      const [range, setRange] = useState(7);
      const data = useMemo(
        () => DAYS.slice(0, range).map((day, i) => ({ day, users: 120 + i * 35 + (i % 2) * 40, revenue: 900 + i * 210 })),
        [range]
      );
      const revenue = data.reduce((sum, row) => sum + row.revenue, 0);
      const users = data.reduce((sum, row) => sum + row.users, 0);
    
      return (
        <main className="mx-auto max-w-5xl space-y-6 p-8">
          <header className="flex flex-wrap items-center justify-between gap-4">
            <h1 className="text-3xl font-bold">nvx-dashboard dashboard</h1>
            <label className="text-sm">
              Range{" "}
              <select className="rounded border px-2 py-1" value={range} onChange={(e) => setRange(Number(e.target.value))}>
                <option value={3}>3 days</option>
                <option value={5}>5 days</option>
                <option value={7}>7 days</option>
              </select>
            </label>
          </header>
          <section className="grid gap-4 sm:grid-cols-3">
            <div className="rounded-xl border p-4"><p className="text-sm opacity-70">Revenue</p><p className="text-2xl font-semibold">${revenue.toLocaleString()}</p></div>
            <div className="rounded-xl border p-4"><p className="text-sm opacity-70">Active users</p><p className="text-2xl font-semibold">{users}</p></div>
            <div className="rounded-xl border p-4"><p className="text-sm opacity-70">Days</p><p className="text-2xl font-semibold">{range}</p></div>
          </section>
          <section className="h-72 rounded-xl border p-4" aria-label="Users chart">
            <ResponsiveContainer width="100%" height="100%">
              <LineChart data={data}>
                <CartesianGrid strokeDasharray="3 3" />
                <XAxis dataKey="day" />
                <YAxis />
                <Tooltip />
                <Line type="monotone" dataKey="users" stroke="#6366f1" strokeWidth={2} />
              </LineChart>
            </ResponsiveContainer>
          </section>
        </main>
      );
    }
    
    Expected result
    src/app/page contains the dashboard.
  6. 6. Start the dev server

    templaterun manually · dev server

    Runs Next.js with hot reload. Keep it running and open the URL.

    bash
    npm run dev
    Expected result
    http://localhost:3000 shows the dashboard.
    Verify
    curl -I http://localhost:3000
  7. 7. Create a production build

    template

    Type-checks and compiles the optimized production bundle.

    bash
    npm run build
    Expected result
    Build finishes without errors and creates .next/.
    Verify
    ls .next