As case study
SEO: 0 to 39.9K
How I grew Royal Subz from zero search presence to 39,900 monthly impressions — no agency, no ad budget.
At a glance
The constraint
Running a SaaS reseller means your product catalogue is ChatGPT, Claude, Grammarly, Cursor — products backed by companies with world-class SEO teams and years of domain authority. Competing on “ChatGPT subscription” or “Claude AI pricing” is a dead end before it starts. OpenAI, Anthropic, and every major review site already own those keywords. Difficulty scores in the 80s. No route in.
The real question was different: what are people searching for that the official channels don’t answer?
The answer was in the friction I’d already built the product to solve. People in Bangladesh and South Asia weren’t searching “what is Claude AI” — they were searching “can I get Claude without an international card”, “how do I buy ChatGPT Plus cheap”, “does Claude have a student discount”. The official sites don’t address those questions. That gap was the opening.
The foundation
Before writing a single word of content, I audited the site — SEMrush and Ahrefs both. Four issues would have quietly blocked progress:
Static sitemap
Every new product and blog post required a manual sitemap edit to get indexed.
Fix
Built a Supabase edge function that generates the sitemap in real time from the live database. No manual edits ever again.
robots.txt blocking
Essential pages — products, blog posts — were blocked from Googlebot crawl entirely.
Fix
Unblocked all public-facing pages. Restricted only admin and auth routes.
Duplicate H1
One page had two H1 tags. Google picks one and ignores the rest of the structure.
Fix
Fixed the markup. One H1 per page, across the entire site.
2.4 MB JS bundle
Every page visit shipped the full JavaScript bundle — including code for all 40+ products — to the browser upfront.
Fix
Refactored to route-based code splitting. Unvisited sections never load. Faster first paint, better Core Web Vitals.
The most involved fix was performance. SEMrush flagged that every page visit was shipping 2.4MB of JavaScript to the browser upfront — the entire product catalog, all 40+ products, regardless of where the user landed. I refactored the build to split the bundle by route. Unvisited sections stay unloaded. Faster first paint, better Core Web Vitals score, and Google’s crawl budget goes further.
The sitemap fix got its own edge function. The original was static — every new product or blog post
required a manual edit. I built a Supabase edge function that generates the sitemap in real time
from the live database. /sitemap.xml now fetches current products, blogs, and pages on every
request. No manual maintenance.
The keywords
The research phase used three tools and produced one insight. SEMrush and Ahrefs for volume and difficulty data. Keyword Tool IO for surfacing question-pattern variants — the “how do I”, “can I”, “is it worth it” long-tail variations that tools like Ahrefs often undercount.
The insight: a reseller can’t win on branded head terms, but it can win on the questions that friction creates. I filtered for keywords with real search volume and low-to-medium difficulty — the overlap a new domain can actually compete in. Then I looked at intent: not “what is X” but “how do I get X without Y” or “is X worth it for [my situation]”.
The top-performing post came directly from this logic: “Claude Student Discount 2026” had real search volume, Anthropic’s site doesn’t answer it, and anyone searching it is close to buying. That post now drives more impressions than anything else on the site.
The content engine
I built the blog publishing dashboard into the Royal Subz admin panel before writing the first post. The intent was simple: make the right structure unavoidable. Every blog has to clear every field before it goes live — not as a rule imposed after launch, but as a constraint baked into the interface.
Discoverability
Social & Open Graph
Content structure
Media
Taxonomy
Internal linking
The format matters as much as the keyword. Google doesn’t just index words — it reads structure. Summary box with at least five bullet points at the top. Meta title distinct from the H1. Canonical URL set. OG image with alt text. Two internal links to related posts, one link to the product being discussed. Sidebar CTA. Every post ships with all of it, or it doesn’t ship.
First blog published: March 27. Submitted to Google Search Console the same day via manual index request. Three weeks of silence. Then impressions started climbing — exponentially, not gradually.
Outcomes
From 50 impressions at end of month one. Zero paid acquisition, zero ad budget.
Started at position 43 in month one. Now averaging 9.4 across all GSC queries.
Up from 12 clicks in month one — most of which were me searching for my own site.
No agency, no link building, no sponsored placements. Keyword tools were the only cost.
What the numbers mean
The gap between month one and today is the gap between a domain Google doesn't trust and one it's starting to. Fifty impressions means Google had barely seen the site. 39,900 impressions means it's serving the pages regularly — for queries that were never assumed, just found.
The CTR is 0.3%. That's the honest number, and it's low. Impressions measure visibility — clicks measure whether the title and description are worth clicking. That's the current problem. The last 5 scheduled posts target transactional keywords with higher purchase intent, and each one is a test of whether a different angle on the meta title converts impressions into visits. The goal is 3%.
What I’d do differently
Start the content engine before launch
The site launched February 16. The first blog went live March 27 — 39 days later. I waited until the storefront felt "done." That was a mistake I'd already described in the Royal Subz case study and then repeated anyway. SEO compounds from day one. Those 39 days are indexing time I can't recover. Next time the content calendar starts the same week as the first commit.
Impressions are easier than clicks
Getting to 39.9K impressions felt like proof the strategy worked. It is — but impressions measure visibility, not intent. A 0.3% CTR means 99.7% of people who see the listing scroll past it. The meta title and description are the product at that stage, and I underinvested in them early. I'm testing variants now, but I should have been running tests from post one.
Mix in transactional keywords from the start
The first 8 posts were informational — "does X have a student discount", "is Y worth it." Good for impressions, weak for conversions. Transactional long-tail ("buy Cursor AI with bKash", "get ChatGPT Plus in Bangladesh") sits closer to purchase intent. I front-loaded the informational phase without realising I was building an audience that wasn't ready to buy. Next time: transactional keywords in the mix from week one.