Markdown blogging is doable (but not the way I initially thought)

I’ve always liked writing in plain Markdown. It’s fast, distraction-free, and doesn’t force me into any framework-specific workflow... Khm-khm .mdx... For a while, I used Docsify.js to turn Markdown into a clean, interactive blog with almost zero setup and honestly, it worked great.

It really worked great. Until the audience wasn't agents.

The problem with client-side rendering

Docsify is purely client-side. It relies on the global window object and renders everything in the browser. That used to be fine.

But things changed.

So effectively, the audience might never see your content. Not to mention how bad this is for those lovely SEO bots.

At the time I worked around this by pre-rendering Markdown into HTML using Cloudflare Browser Workers. On every update, I’d spin up a headless browser, render the page, and cache the result. (Obviously, this was a DB trigger on Xano..)

Rethinking the approach

I wanted something simpler:

My initial idea was:

Before building it, I sanity-checked the idea with Perplexity and got mixed feelings. I was directed towards Markdoc which already exists and is exactly what I was thinking...

Enter Markdoc

Stripe’s Markdoc does exactly this.

It basically solved every requirement I had.

Implementation setup

I wired Markdoc into my stack:

Basic flow:

TypeScript
import Markdoc from '@markdoc/markdoc';

const ast = Markdoc.parse(markdownSource);
const content = Markdoc.transform(ast, config);
const html = Markdoc.renderers.html(content);

Custom tags

You can define your own components:

TypeScript
const config = {
  tags: {
    alert: {
      attributes: {
        type: { type: String, default: 'note' }
      }
    }
  }
};

Then use it in Markdown:

Markdown
{% alert type="tip" %}
This is a tip.
{% /alert %}

Dealing with edge cases

A few things needed extra care, because I work with Xano and a bit of a niche tech stack:

The result

I ended up with:

Most importantly, writing feels predictable again. I don’t have to wonder whether the final output will match what I had in mind or whether it’ll even render for all the audience (even if there's actually no traffic here LOL).


@calycode, we build open, reliable, and automated workflows for Xano that empower teams with clarity, transparency, and control. Our mission: make backend development safe, collaborative, and future-ready, so every team can ship confidently and trust the process.


We have a Chrome Browser Extension for Xano to get you rolling much faster and more reliable Xano systems. If you're curious how @calycode/cli works with Xano features, check out our repo, docs or drop us a message on Discord!


You can also get started with Xano right now, here.