TL;DR
Start (Feb 17 2020): < 100 Google impressions/day on a thin client-side SPA.
Today: > 200 000 impressions/day, Core Web Vitals all green, Lighthouse 80-95.
Stack: Next.js, AWS, PM2.
Team: 1 developer – me 🤓
1. Day-Zero Reality Check
When I joined KukuFM the website looked like a one-page mock-up.
Everything shipped inside a single 450 KB JS bundle, so Googlebot mostly saw this:
<div id="root"></div>
No
robots.txtNo sitemap
No structured data
Daily search impressions: < 100
2. Choosing the Right Hammer (Why Next.js)
2020 had a buffet of SSR options custom Node/Webpack, Nuxt, even Gatsby hacks.
I picked Next.js v9.2:
Why Next.js won, SSR without boilerplate File-based routing + getServerSideProps Fast learning curve Great docs & community (even in 2020) Future-proof Betting on Vercel’s momentum paid off
Yes, I boarded the hype-train but it was the right train.
3. Two-Week Rewrite Sprint 🚀
Bootstrap repo – Monorepo, ESLint, Prettier, Pre commit hooks
Migrate views – each SPA screen →
/pages/**.Data fetching –
getServerSideProps.Deployment – PM2, AWS ec2.
Perf – code-split, lazy-load images, js bundle on CDN.
Result: First deploy hit 80 + Lighthouse on every key page.
That quick Slack high-five captured the moment we knew the new SSR stack was working in production.
4. Behind-the-scenes plumbing: structured data, sitemaps, and a crash-course in SSR
Once the pages were rendering on the server, I turned my attention to the invisible scaffolding that makes a site understandable to both crawlers and users. I began by sprinkling Schema.org JSON-LD across every template so that Google could instantly recognise a Podcast, an Episode, or a breadcrumb trail without having to guess. Next came the maps: a nightly Python job now combs the database for every live show and episode, compresses the list into a fresh sitemap.xml
That all sounds neat in hindsight, but the learning curve was real. I had to figure out how to pass user context locale, theme, even auth tokens into getServerSideProps so that logged-in listeners saw their “Continue Listening” shelf the moment HTML hit the browser. I wrestled with getStaticProps versus SSR trade-offs, and I bumped into more than one quirky Next.js convention that felt upside-down coming from a SPA mindset. Plenty of late nights, but the payoff was a site that speaks Google’s language, stays perfectly mapped, and delivers personalised content on first paint.
5. The Hockey-Stick Moment
Six months in, Google finally had enough crawlable, well-structured content.
Impressions exploded:
This is our latest impression click chart at the time of writing blog
Month 0-1: Flat (< 500/day)
Month 2-4: Steady climb (2 k → 15 k)
Month 6: Spike to 200 k+ / day
6. Key Lessons for Solo Devs
SSR ≠ SEO by default – still need sitemaps, schema, CWV.
Ship → Iterate – two-week MVP rewrite unlocked everything else.
Own the pipeline – when the same engineer controls build → deploy → monitoring things become 10x faster
Track a single metric – for us it was Google Search impressions and clicks.
7. Ask Me Anything
Have questions about the stack, roadmap, or the gritty bits I skipped?
👇 Drop a comment or reach me on LinkedIn / GitHub.
Thanks for reading! If you enjoyed this deep-dive, consider subscribing or sharing the post with a fellow dev who’s battling SEO.



