Open-source Astro docs framework, agent-ready with an MCP server for search. Free to deploy
▲ 37 r/astrojs

Open-source Astro docs framework, agent-ready with an MCP server for search. Free to deploy

Built and open-sourced (MIT) a documentation framework on Astro: write Markdown, get a static site with search, an API reference generated from an OpenAPI document, and dark mode. Free to run, no per-seat pricing, no watermark, deploys to Cloudflare Workers or any static host.

The part that took the most work: every deployment also ships an MCP server, so AI agents can search and fetch the docs directly instead of guessing from training data (easily RAG-based if using Cloudflare to host - it's all guided).

The bytes served at a page's Markdown URL, the bytes the MCP fetch tool returns, and the bytes the search index embeds all come from one function, and a test asserts the MCP and HTTP responses are byte-identical.

A couple of Astro-specific choices, if useful to anyone building something similar: both Shiki themes ship as CSS variables (defaultColor: false), so switching themes costs no re-render, and Mermaid, KaTeX and cytoscape are lazy chunks loaded only on pages that use them, so the base UI bundle stays around 11 KB gzipped regardless of how much of that a given docs site uses.

Repo: github.com/DuvInc/duvlify - Docs (built with itself): duvlify.dev

u/duv_guillaume — 1 day ago

Is Antigravity running the new Gemini Flash model? It feels 10x faster than before today!

Tried Gemini Flash in Antigravity and it's so incredibly fast, is that the new Flash 3.2 or 3.5 model?

I've measured over 1300 tps

Anyone else has this ?

reddit.com
u/duv_guillaume — 3 months ago

Is Antigravity running the new Gemini Flash model? It feels 10x faster than before today!!

Tried Gemini Flash in Antigravity and it's so incredibly fast, is that the new Flash 3.2 or 3.5 model??

I've measured over 1300 tps

Anyone else has this?

reddit.com
u/duv_guillaume — 3 months ago

How to check if AI bots requests say they accept text/markdown?

I see some companies making their website return markdown when the request comes from an AI agent and one way to do it is to serve markdown instead of HTML when the request says it accepts text/markdown.

Now my website is managed by Cloudflare Pages and I'd like to see if any requests actually are in that setup so see if it's worth investigating.

Anyone knows how to check that in Cloudflare?

reddit.com
u/duv_guillaume — 3 months ago
▲ 10 r/astrojs

How I translated my Markdown-based Astro blog to 6 languages at scale (scaling via CSVs)

Hey guys,

I just finished setting up i18n for my site. Astro's routing makes the folder structure super easy, but translating the actual content in src/content/blog is a different story.

At first, I tried to just let an AI coding agent (using Gemini Flash 3 for speed, in Antigravity) do the translation for me directly on the .md files in my editor. It was a disaster.

Not only was it painfully slow (I could only get through about 3-5 articles per run before it would stall out), but worse, the LLM started getting "lazy". Instead of giving me a 1:1 detailed translation, it started outputting summarized, truncated versions of my articles to save effort. On top of that, it kept hallucinating yaml frontmatter and breaking my custom Astro components.

I realized agentic translation just wasn't scalable for a whole CMS. And since that website is actually the marketing website of my app that's dedicated to batch CSV translations (check AI Glot if interested), I figured I should just use my own tool. I just needed to bridge the gap between Markdown and CSV, because I initially built it 2 years ago for Weglot translations which handles everything via CSV.

So, I put together two simple Node scripts: one to extract the text to a CSV, and one to import it back.

Here is what the workflow looks like and some concrete gotchas if you want to set it up:

  1. the extraction script I wrote a Node script that crawls my src/content/blog/en folder. It parses the frontmatter (catching title, metaDescription, and even custom arrays like faqs) and splits the body text by \n\n+ to isolate paragraphs.

It spits all of this out into a simple CSV with columns: path, English string, and my target locales (fr, es, etc).

Two important details for this script:

  • It explicitly skips over lines starting with ``` so code blocks never get sent to the translator.
  • It has pre-fill logic: if a localized .md file already exists, it maps the existing translations back into the CSV. This means when I add a new paragraph to an old post, I don't have to re-translate the entire file.
  1. the translation Once I had a clean CSV with just the english strings, I could translate it in bulk. You could just write a quick python script to loop through the rows and hit the OpenAI API. I just threw it into AI Glot to handle the batches and apply glossaries (so it doesn't try to translate technical words like "Astro" or "Frontmatter" into French or Spanish).
  2. putting it back together (the tricky part) Then I have an assembly Node script that takes the translated CSV and rebuilds the markdown files. This was trickier than it sounds.

the workflow:

[ /src/content/blog/en/*.md ] 
            │
            ▼ (extract-translations.mjs)
[ multilang-translation.csv ]  <-- Clean text only, no formatting/code blocks
            │
            ▼ (Batch AI Translation via AI Glot / Python script)
[ translated_fr.csv, translated_es.csv, etc ]
            │
            ▼ (assemble-blog-translations.mjs)
[ /src/content/blog/fr/*.md ]  <-- Reassembled with perfect frontmatter & formatting

If you build this yourself, here are the concrete gotchas my assembly script handles:

  • String replacement bugs: You must sort your CSV translation chunks by length (descending) before doing the string replacement in the markdown file. Otherwise, if the script replaces "Astro" before it replaces the longer phrase "Astro i18n API", it will corrupt the string.
  • Image path depths: Astro localized content usually sits one directory deeper (e.g., src/content/blog/fr/live/ instead of src/content/blog/live/). The script runs a quick .replace('../../../assets/', '../../../../assets/') to automatically fix relative image references.
  • Internal link localization: It runs a regex (/\]\(\/([\w\-\/]+)\)/g) to automatically prepend the locale to any internal markdown links (so [Read more](/blog/slug) becomes [Read more](/fr/blog/slug)).
  • Frontmatter injection: It automatically updates the yaml frontmatter to flip isDraft: false and injects locale: "fr".

The best part about doing it this way is that you never break your formatting, and you don't end up with lazy, summarized translations.

Thought I'd share this since markdown translation seems to be a common pain point when scaling a markdown based Astro CMS. If anyone wants the actual extract-translations.mjs and assemble-blog-translations.mjs code, let me know and I'll drop the gists in the comments!

reddit.com
u/duv_guillaume — 3 months ago