DEV Community

Cover image for I’m Not an SEO Guru, So I Built a dynamic Content Engine with Gemini-CLI Instead
Marcin Niemira
Marcin Niemira

Posted on

I’m Not an SEO Guru, So I Built a dynamic Content Engine with Gemini-CLI Instead

How I Used Gemini-CLI and Golang to Scale a Tiny Translation Business from 10 to 600+ Impressions

As life happens, I’ve stumbled into helping a tiny business: a new translation service in Australia called insighter.

Initially, I crafted a simple website. The stack was Golang, HTMX, and Tailwind. It was clean, fast, and... invisible. Google Search Console showed around 10 impressions a day and zero clicks.

Disclaimer: I’m not an SEO guru. I’m just a random engineer who accidentally stepped into the world of Programmatic SEO (pSEO). Here is the 6-step engineering log of how I used LLMs to build a content engine.


Step 1: The Low-Hanging Fruit (Metadata)

I started by improving page quality and metadata. I let gemini-cli do the heavy lifting, generating keyword-rich tags and descriptions for the existing static content.

The Workflow:

  1. Run an SEO checker to find missing tags.
  2. Feed the page context to Gemini.
  3. Manual tweaks to ensure it didn't sound like a robot wrote it.

Impact: SEO tools stopped screaming at me. A solid baseline, but not a game-changer yet.


Step 2: Breaking the "Quality" Rule with pSEO

Google traditionally advises focusing on a few high-quality pages rather than many similar ones. However, Australia has over 2,600 postcodes. I decided to ignore the "less is more" advice and went for bulk generation.

I built 26 templates and programmatically generated pages for different locations. To avoid the "duplicate content" penalty, I got creative:

  • Unique Visuals: I generated SVG images with random seeds and predefined colors. Every page got a unique fingerprint.
  • Data Skewing: I built a "fun fact" bank (50 records) and state/territory specific twists (8).

The Math: 2600 pages / 26 templates / 50 fun facts / 8 state-specific twists ~= 0.25.

With a ratio below 1, the risk of an exact duplicate page is nearly zero. Of course this number is skewed as ACT has less postcodes than NWS, but principle stays.

Impact: A visible bump. Impressions jumped by 250–350 per day.


Step 3: Pivoting Keywords (Languages & Countries)

I applied the same logic from Step 2 but shifted focus to Language + Country combinations.

Instead of just "Translation Services," I targeted "NAATI Documents from France" or "NAATI French Translation".

Impact: Another 100 impressions/day added to the tally.


Step 4: Building the "Link Mesh"

Internal linking is SEO gold. Using the distance between latitudes and longitudes, I automated a "Nearby Locations" section.

If you are on the Black Rock 3193 page, the app automatically suggests:

  • Highett 3190
  • Cheltenham 3192
  • Brighton 3187
  • Mentone 3194

I did the same for languages. Since Switzerland has multiple official languages, the page for Switzerland links to Italian, German, and French. The Italian page, in turn, links back to Switzerland, Italy, and San Marino. This irregular, non-1:1 mapping creates a natural-feeling web for crawlers.

Impact: Harder to isolate, but overall site authority began to climb.


Step 5: Template Variators (The "Mad Libs" Approach)

To make the content even more unique, I implemented DocumentPurposeVariations and DocumentNounVariations.

Instead of every page saying "We translate legal documents," the template uses placeholders like {DOC_NOUNS} and {DOC_PURPOSES}. The engine picks from a bank of grammatically compatible strings. The result? Thousands of pages that are technically different but consistently accurate.

Impact: Unsure yet as it's a fresh change, but the uniqueness score is high.


Step 6: JSON-LD and FAQ Injection

Finally, I focused on Schema markup (JSON-LD). For a postcode like 3022 (which covers Ardeer and Deer Park East), I injected specific FAQ schemas:

  • Q: Do you provide service in Ardeer?A: Yes.
  • Q: Do you provide service in Deer Park East?A: Yes.

This tells Google exactly what the page is about in a machine-readable format.


Summary

The effort required to do this manually would never justify the gain for a "tiny business." But by treating SEO as a data engineering problem and using gemini-cli as a specialized intern, I built a pSEO solution for insighter mostly in the background.
Does it solve all the problems? Nah, backlinks or authority are not sorted yet, but it's already a huge improvement.

The takeaway: Don't just build a site. Build a system that generates the site.

Top comments (0)