Companion to the GTM Audit. Ordered by leverage-per-effort. Each item lists the concrete files to touch in this repo where applicable. Referenced finding codes (T1–T9) are defined in the audit's §3 technical findings.
src/components/SEO.jsx:
addressCountry "US" → "IN".sameAs URLs with real, claimed profiles only (currently https://twitter.com/InvestWise48732; add others as they're claimed).Organization (or WebSite with Organization publisher), not FinancialService on every page — FinancialService implies a regulated advisory, which invites YMLY scrutiny the site can't back up.noAds → <meta name="robots" content="noads"> branch (invalid token, emits duplicate robots meta).useEffect out of SEO.jsx into a route-level tracker (e.g. a usePageTracking hook mounted once in App.jsx).src/lib/schema.js):
BreadcrumbList for stocks (Home › Stocks › {name}), heatmaps, calculators, blog.FAQPage for calculator + heatmap pages (content in §2/§3).Corporation (name, tickerSymbol, exchange: NSE, ISIN) on stock pages.WebApplication (applicationCategory: FinanceApplication) on calculators.src/pages/stocks/StockPage.jsx:500:
`${stock.fullName || stock.name} Share Price (NSE: ${symbol}) — Live Chart & Analysis | Wise Invest`Nifty 50 Heatmap — Live NSE Stock Market Heatmap Today | Wise Invest (per index).SWP Calculator — Systematic Withdrawal Plan Calculator India | Wise Invest etc.{Post title} | Wise Invest (drop the Wise Invest | Blog | prefix).scripts/generate-sitemap.mjs:
Date.now() on every build, and set changefreq=weekly.sip, swp, cagr, lumpsum, retirement, gratuity, term-insurance, home-loan, fixed-deposit, interest-rate), heatmap index pages (/heatmap/index/nifty50, nifty100, nifty200, nifty500, nifty-bank, nifty-it, nifty-auto, nifty-midcap-100, nifty-smallcap-100, sector pages), /dividend-calendar, /ipo-listings, /stocks-list./services.sitemap-core.xml, sitemap-stocks.xml, sitemap-blog.xml (keeps GSC diagnostics per-section).public/robots.txt: keep as is (it's fine), confirm sitemap-index URL.src/App.jsx / StockPage.jsx: when a symbol doesn't exist in the dump, render a real not-found component with <SEO noIndex> and prerender-status-code meta; longer-term the prerender layer (Phase 1) returns real 404s.noIndex to /stocks/data-health, /test-wealth-upload, /wealth-dashboard-demo, /wealth/* (per-user pages), /blog/editor, /blog/update/*.amplify.yml): 301 legacy blog slugs (URL-encoded (,:,. variants) → clean slugs. 301 /heatmap/index/nifty_smallcap_100 → /heatmap/index/nifty-smallcap-100./heatmap?index=…§or=…): set canonical to the path-based equivalent in the Heatmap component.amplify.yml: Referrer-Policy → strict-origin-when-cross-origin.index.html: drop maximum-scale=1.0; add display=swap-style loading for Material Symbols (media="print" onload pattern or self-host subset); consider loading Google Charts loader only on routes that use it.Exit criteria: Rich Results Test passes for Breadcrumb + FAQ on one stock page, one calculator, one heatmap page; GSC URL Inspection shows correct canonical/meta on the top-20 impression pages.
The single highest-leverage engineering investment. Options, in order of pragmatism:
Option A (recommended): build-time static HTML generation on the existing stack.
generate-sitemap.mjs already downloads the full market dump at build time. Extend the same pipeline:
scripts/prerender.mjs post-build step: for each priority route, copy dist/index.html and inject (a) correct <title>/meta/canonical/JSON-LD, (b) a server-rendered content block (company name, price snapshot as of dump date, sector, market cap, ISIN, 2–3 paragraph company description, FAQ) inside #root or a <noscript>-adjacent SEO block that React replaces on hydration.dist/stocks/{symbol}/index.html etc.; Amplify serves static files before the SPA rewrite, so no infra change is needed.BlogPosting schema and Article rich results actually visible to the crawler.Option B: Migrate to a framework with SSG/SSR (Astro or Next.js) — cleaner long-term but a multi-week rewrite of a large app; defer until Option A's ceiling is reached.
Option C: Bot-only dynamic rendering (Rendertron/prerender.io via CloudFront) — Google discourages it and it adds infra; not recommended.
Exit criteria: curl https://wiseinvest.in/stocks/reliance returns full HTML with title, meta, JSON-LD and content without JS execution. GSC "Crawled — currently not indexed" count begins falling.
The audit shows pages 2–5 today; goal is page 1 for the index-heatmap family.
/heatmap/index/:index pages):
FAQPage schema): "What is the Nifty 50 heatmap?", "How often is it updated?", "What do the colors mean?"/stocks/*)./features/stock-heatmaps (389 impressions, 0.51% CTR): rewrite as the pillar page "Stock Market Heatmap — India (NSE) Live", link out to every index page.nifty 50 heatmap, nifty 100 heatmap, nifty 200 heatmap, nifty 500 heatmap, nifty midcap 100 heatmap, nifty smallcap 100 heatmap, nifty bank heatmap, nifty it heatmap, f&o heatmap, sector heatmap, stock market heatmap live, nse heatmap.Exit criteria: ≥3 heatmap queries in top 10; heatmap cluster becomes the #1 non-brand click source.
/products/calculators) rebuilt as a directory with descriptions (it already gets clicks at pos 73 with zero optimization).alternateName in Organization schema; correct social links.SEO.jsx (Phase 0.1); add events: heatmap_interaction, calculator_used, stock_page_engaged (30s+), newsletter_signup. (Superseded by the full event catalog in the GA4 Tracking Plan.)| Week | Workstream |
|---|---|
| 1 | Phase 0 (schema, titles, sitemap, canonicals, noindex, redirects) |
| 2–4 | Phase 1 prerendering pipeline; daily rebuild cron |
| 3–6 | Phase 2 heatmap landing pages + pillar + blog upgrade |
| 6–10 | Phase 3 calculators + SWP/credit-score hubs |
| 8+ | Phase 4 distribution loops, ongoing content cadence |
This acquisition sequencing is merged with the conversion/funnel workstream in the Combined Growth Plan's Part 4 roadmap.