From < 100 to 200 K+ Daily Google Impressions
Note: We've mirrored this post from Substack to provide easy access alongside other content. While we strive for accuracy, the original Substack post may offer richer formatting or embedded media. For the definitive reading experience, please visit the original article.
Read on Substack →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.txt
No 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.