A modern, SEO-first financial dashboard that tracks 100+ global assets — stocks, cryptocurrencies, precious metals, and commodities — with real-time data, candlestick charts, and institutional-grade analytics.
Live Demo: https://finnio.vercel.app/
| Layer | Technology |
|---|---|
| Framework | Next.js 15 (App Router, React Server Components) |
| Language | TypeScript (strict mode, zero any) |
| Styling | Tailwind CSS with custom dark design system |
| State | Zustand (watchlist, portfolio) |
| Data Fetching | SWR (client), Server Components (SSR) |
| Charts | Lightweight Charts (TradingView), Recharts |
| Auth | Supabase (optional) |
| Icons | Lucide React |
| Deployment | Vercel with ISR (60s revalidation) |
This project uses React Server Components (RSC) — Next.js 15's modern SSR approach — instead of legacy getServerSideProps. Key architectural decisions:
generateMetadata()— Dynamic per-page meta titles, descriptions, OG/Twitter cards, and canonical URLsgenerateStaticParams()— Pre-renders all asset pages at build time for instant TTFBrevalidate = 60— ISR with 60-second windows balances freshness with edge-cached performance- Server → Client split — Server Components fetch data and inject SEO; Client Components handle interactivity (charts, filters, search)
Every page delivers fully rendered HTML on the first response, ensuring searchbot crawlability.
Every route exports metadata or generateMetadata with:
- Title (templated via
%s | FinnSays) - Description (keyword-optimized)
- OpenGraph (title, description, type, images)
- Twitter Cards (summary_large_image or summary)
- Canonical URL (
alternates.canonical)
- Organization schema on every page (via root layout)
- FinancialProduct schema on asset detail pages (stocks, crypto)
- Currency schema on cryptocurrency pages
- AboutPage schema on the
/aboutpage
sitemap.xml— Auto-generated covering all static + dynamic routesrobots.txt— Allows all, disallows private routes- Semantic HTML — Proper
<main>,<article>,<section>, heading hierarchy - Skip-to-content link for accessibility
- Self-referencing canonicals on all pages
See KEYWORD-RESEARCH.md for the full keyword research document covering transactional, informational, and long-tail keyword pillars.
| Page | Route | SSR | Features |
|---|---|---|---|
| Dashboard | / |
✅ ISR | Hero, search bar, market overview, sparklines |
| Markets | /markets |
✅ ISR | Full asset table, sorting, pagination, filters |
| Asset Detail | /stocks/[symbol] |
✅ SSG+ISR | Candlestick chart, price data, JSON-LD schema |
| Crypto | /crypto/[coin] |
✅ ISR | Live crypto price, chart, Currency JSON-LD |
| Commodities | /commodities/[comp] |
✅ ISR | Gold, silver, oil, natural gas tracking |
| Screener | /screener |
✅ ISR | Multi-column sort, filters, real-time table |
| Watchlist | /watchlist |
✅ ISR | Persistent favorites with localStorage |
| Portfolio | /portfolio |
✅ ISR | Wealth tracking across asset classes |
| News | /news |
✅ CSR+API | Live financial news from Yahoo Finance |
| Blog | /blog |
✅ SSR | Financial education and market insights |
| About | /about |
✅ SSR | Tech stack, data sources, architecture, SEO strategy |
| Contact | /contact |
✅ SSR | Contact form |
| Technology | /technology |
✅ SSR | Infrastructure and performance overview |
| SEO Dashboard | /seo |
✅ SSR | Internal SEO metrics (noindex) |
Client (SWR) ──► API Routes ──► DataAggregator ──► Yahoo Finance
│
▼
In-Memory Cache
+ File Cache
(TTL: 30s quotes, 5m candles)
The DataAggregator singleton provides a unified API across all asset types with caching, rate limiting, and request deduplication.
git clone https://github.com/alteretzy/finnsays-.git
cd finnsays
npm installcp .env.example .env.localFill in your API keys (see .env.example for documentation):
NEXT_PUBLIC_FINNHUB_API_KEY— Get free from FinnhubALPHA_VANTAGE_API_KEY— Optional, from Alpha Vantage
npm run devOpen http://localhost:3000.
npm run build # Production build (zero warnings)
npm run lint # ESLint check
npm run test # Jest unit tests- Push code to GitHub
- Import into Vercel
- Set environment variables from
.env.example - Deploy — ISR and edge caching are automatic
npm i -g vercel
vercel login
vercel # Follow prompts
vercel --prod # Production deploy- TypeScript strict mode — Zero
anytypes in production code - ESLint —
next/core-web-vitals+next/typescriptrules - Prettier — Consistent formatting (
.prettierrc) - Zero console.log — Only
console.error/warnin error boundaries - Security headers —
X-Content-Type-Options,X-Frame-Options,X-XSS-Protection,Referrer-Policyviavercel.json
MIT