🚀 How I Built a Local Blogger Theme Simulator (and Finally Made Blogger Development Not Painful)

Sunday, May 10, 2026 0 comments

For more than a decade, my personal portfolio has lived on Blogger.

Not because it’s trendy.
Not because it’s developer‑friendly.
But because it’s home — stable, fast, free, and surprisingly powerful when pushed.

But let’s be honest:
Developing modern, interactive, Tailwind‑powered themes on Blogger is a nightmare.

If you’ve ever tried to:

  • write HTML
  • convert it into Blogger XML
  • sprinkle <b:if> and <b:loop> tags
  • debug inside Blogger’s restrictive editor
  • and repeat this cycle 100 times

…you know exactly what I mean.

This post is about how I finally snapped — and built a local Blogger theme simulator that lets me develop like a normal human again.


⭐ The Problem: Blogger + Modern Frontend = Pain

Blogger’s templating system is powerful but ancient.
It doesn’t support:

  • component includes
  • partials
  • loops
  • conditionals
  • modern CSS frameworks
  • local previewing
  • hot reload
  • or any sane development workflow

Every time I wanted to update my portfolio, I had to:

  1. Write HTML locally
  2. Convert it manually into Blogger XML
  3. Replace logic with <b:if> and <b:loop>
  4. Upload
  5. Pray
  6. Debug inside Blogger’s editor
  7. Repeat

This workflow kills creativity.
It kills iteration.
It kills motivation.

So I built something better.


⭐ The Solution: A Local Blogger Simulator Using Express + Handlebars

I created a local development environment that mimics Blogger’s rendering engine — but with modern tooling.

The stack:

  • Express.js — local server
  • Handlebars — templating engine
  • Tailwind CSS — via CDN or build
  • Node HTML Parser — to transform templates
  • Google Blogger API v3 — to fetch real blog data
  • A custom build script — the magic layer

This lets me:

  • write clean HTML
  • use partials ({{> header}})
  • use loops ({{#each posts}})
  • use conditionals ({{#if view.isPost}})
  • preview everything locally
  • fetch real posts, labels, pages, search results
  • and finally compile everything into valid Blogger XML

No more manual conversion.
No more Blogger editor.
No more pain.


⭐ The Magic: Converting Handlebars → Blogger Tags Automatically

The heart of the system is a build script that:

  1. Reads my theme template
  2. Injects partials
  3. Parses the DOM
  4. Converts data-b="widget" into <b:widget>
  5. Rewrites logic blocks
  6. Rewrites loops
  7. Rewrites variables
  8. Injects Tailwind CSS into <b:skin>
  9. Outputs a fully valid Blogger XML theme

Here’s the core script (simplified for the blog):

import fs from "fs";
import { parse } from "node-html-parser";

const CONFIG = {
  source: "./views/theme.xml",
  css: "./dist/output.css",
  output: "./dist/final-theme.xml",
};

function compile() {
  let sourceHtml = fs.readFileSync(CONFIG.source, "utf8");
  const cssContent = fs.readFileSync(CONFIG.css, "utf8");

  const partials = {
    header: fs.readFileSync("./views/partials/header.xml", "utf8"),
    footer: fs.readFileSync("./views/partials/footer.xml", "utf8"),
    blog: fs.readFileSync("./views/partials/blog.xml", "utf8"),
  };

  Object.keys(partials).forEach((name) => {
    const regex = new RegExp(`{{>\\s*${name}\\s*}}`, "g");
    sourceHtml = sourceHtml.replace(regex, partials[name]);
  });

  const root = parse(sourceHtml, {
    lowerCaseTagName: false,
    comment: true,
  });

  const widgetCounters = {};
  const bloggerElements = root.querySelectorAll("[data-b]");
  bloggerElements.forEach((el) => {
    const type = el.getAttribute("data-b");

    if (type === "widget") {
      const widgetType = el.getAttribute("type") || "HTML";
      if (!el.getAttribute("id")) {
        widgetCounters[widgetType] = (widgetCounters[widgetType] || 0) + 1;
        el.setAttribute("id", `${widgetType}${widgetCounters[widgetType]}`);
      }
    }

    el.tagName = `b:${type}`;
    el.removeAttribute("data-b");
  });

  let template = root.toString();

  const mappings = [
    { from: /\s(href|src|alt)="{{\s*.*?\s*}}"/g, to: "" },
    { from: /{{\s*#if\s+localDev\s*}}/g, to: "<b:if cond='data:localDev'>" },
    { from: /{{\s*#each\s+posts\s*}}/g, to: "<b:loop values='data:posts' var='post'>" },
    { from: /{{\s*post\.title\s*}}/g, to: "<data:post.title/>" },
    { from: /<b:skin><\/b:skin>/g, to: `<b:skin><![CDATA[\n${cssContent}\n]]></b:skin>` },
  ];

  mappings.forEach((m) => {
    template = template.replace(m.from, m.to);
  });

  template = template
    .replace(/<(meta|link|img|br)([^>]*?)\s*\/?>/g, "<$1$2 />")
    .replace(/&(?!(amp|lt|gt|quot|apos);)/g, "&amp;")
    .replace(/{{\s*.*?\s*}}/g, "");

  fs.writeFileSync(CONFIG.output, template);
  console.log("✅ Build Complete: dist/final-theme.xml");
}

compile();

This script is the bridge between:

  • modern development
  • and Blogger’s XML world

It lets me write themes like a frontend engineer — not like an archaeologist digging through 2008‑era markup.


⭐ Fetching Real Blogger Data Locally

To make the simulator feel real, I used:

Google Blogger API v3

This lets me fetch:

  • posts
  • pages
  • labels
  • search results
  • pagination
  • metadata

So my local environment behaves exactly like Blogger.

I can test:

  • homepage
  • post page
  • label page
  • search page
  • pagination
  • widgets

…all without touching Blogger.


⭐ The Result: A Modern, Maintainable Blogger Portfolio

Now I can:

  • build with Tailwind
  • use partials
  • use loops
  • use conditionals
  • preview locally
  • fetch real data
  • compile to XML
  • deploy in seconds

My Blogger portfolio finally feels like a real micro‑SaaS website, not a relic.

And I didn’t have to migrate away from Blogger — the platform that has hosted my work for more than a decade.


⭐ Why I’m Sharing This

Because I know there are other indie devs like me:

  • nostalgic about Blogger
  • frustrated by its limitations
  • wanting modern tooling
  • but not wanting to migrate

If you’re one of them, this approach might save you months of pain.


⭐ Want the full code, architecture, or a starter template?

I can publish:

  • a starter repo
  • a CLI tool
  • a full tutorial series
  • a video walkthrough

Just tell me what direction you want next.

No comments