Full-Stack & Next.js• 10 min read•Updated: October 2026
How to Build a High-Performance IPO Dashboard with Next.js & Tailwind CSS
Building consumer-facing financial dashboards requires optimal Core Web Vitals (LCP < 2.5s) and automated background cache invalidation. In this tutorial, you will construct a responsive Indian IPO market terminal in Next.js utilizing React Server Components (RSC) and Incremental Static Regeneration (ISR).
React Server Component Implementation
By executing the data fetch directly on the Next.js server side, your API keys remain 100% hidden from client-side bundles. Enabling revalidate = 60 ensures high performance with near-instantaneous page delivery cached on edge CDNs.
app/ipo-dashboard/page.tsx
typescript
// app/ipo-dashboard/page.tsx (React Server Component)
import React from 'react';
interface IpoRecord {
ipoId: number;
companyName: string;
type: string;
startDate: string;
endDate: string;
lotSize: number;
minimumPrice: number;
maximumPrice: number;
}
// Enable Incremental Static Regeneration (ISR) every 60 seconds
export const revalidate = 60;
async function getLiveIpos(): Promise<IpoRecord[]> {
const res = await fetch('https://api.ipoapipro.in/api/ipo/all?pageNumber=1&perPageRow=20', {
headers: {
'ApiKey': process.env.IPO_API_KEY!,
'ApiSecret': process.env.IPO_API_SECRET!,
},
next: { revalidate: 60 }
});
if (!res.ok) {
throw new Error('Failed to fetch Indian IPO stream');
}
const payload = await res.json();
return payload.data || [];
}
export default async function IpoDashboard() {
const ipos = await getLiveIpos();
return (
<div className="max-w-6xl mx-auto p-6 space-y-6">
<div className="flex items-center justify-between">
<h1 className="text-2xl font-bold text-white">Live Indian IPO Market Watch</h1>
<span className="text-xs font-mono text-emerald-400 bg-emerald-500/10 px-2.5 py-1 rounded-full border border-emerald-500/20">
● Auto-synced every 60s
</span>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
{ipos.map((ipo) => (
<div key={ipo.ipoId} className="p-5 rounded-2xl bg-slate-900 border border-slate-800 space-y-3">
<div className="flex justify-between items-start">
<span className="text-xs font-mono px-2 py-0.5 rounded bg-slate-800 text-slate-300 font-bold">
{ipo.type}
</span>
<span className="text-xs text-slate-400 font-mono">
{ipo.startDate} to {ipo.endDate}
</span>
</div>
<h2 className="text-base font-bold text-white truncate">{ipo.companyName}</h2>
<div className="pt-2 border-t border-slate-800/80 flex justify-between text-xs font-mono">
<span className="text-slate-400">Price Band:</span>
<span className="text-emerald-400 font-semibold">₹{ipo.minimumPrice} - ₹{ipo.maximumPrice}</span>
</div>
<div className="flex justify-between text-xs font-mono">
<span className="text-slate-400">Min. Lot:</span>
<span className="text-cyan-400 font-semibold">{ipo.lotSize} Shares</span>
</div>
</div>
))}
</div>
</div>
);
}