Translating your whole blog without breaking it on the way back
Machine translation got good. That part is solved. What stays hard is everything wrapped around the words — the tags, the slug, the feature image, the internal links, the frontmatter — surviving the trip from your source language into another one and back into Ghost without quietly losing a piece. Most people who try to do this on Ghost end up with a Make scenario that fires on publish, ships the body to DeepL, and tries to reassemble a second post on the far side. It works until it doesn’t, and when it doesn’t you find out from a reader who hit a slug collision or a callout that came back as flat prose.
There’s a calmer way to do this, and it starts by getting your blog out of the web editor and onto disk.
Pull the blog down first
Specter is a native macOS app that does two-way sync between a Ghost blog and a folder of plain markdown files. You connect it with your Admin API key, pick a folder, and it pulls every post down as a .md file with its frontmatter intact — title, tags, status, feature image URL, and excerpt all sitting at the top of the file where you can read them. The body becomes markdown underneath.
That single step changes the problem. Instead of translation being a thing that happens inside an automation you half-remember configuring, it becomes a thing you do to a folder of files you can see. Your source-language posts are right there. Whatever you translate them into will sit next to them. And for the first time you have one place where you can look at the original and its translation side by side and confirm they actually match.
Run the translation pass
Now hand the folder to whatever translation you already trust. This is where bring-your-own-AI matters: Specter bundles no model and charges for no tokens, so you’re free to point Claude, ChatGPT, or Gemini at the folder and ask it to translate every body, or run your own DeepL script across the files, or anything in between. The folder is just text, so any tool that can read and write files can do the work.
The instruction you give the AI is the important part. You don’t want it translating blindly — you want it translating the prose while leaving the scaffolding alone. Tell it to translate the body and the human-readable frontmatter fields like the title and excerpt, but to preserve the tags, keep the slug stable so it doesn’t collide with the original, leave image URLs untouched, and rewrite internal links thoughtfully rather than dropping them. Frontmatter is structured, so a careful pass keeps it structured. Because everything lives in one folder, this is a single sweep across the whole archive instead of one webhook firing per post, and there’s no stitching step where a tag or a feature image gets lost in transit.
If you’re translating a section rather than the whole blog, the same thing applies at smaller scale — point the tool at the files you care about and leave the rest.
Preview the diff before anything ships
This is the part the brittle automation never had. Before a single byte reaches Ghost, Specter shows you a dry-run preview: exactly which posts would be created, which would be updated, and which it would flag as a conflict. You read the scope of the whole translation pass as a list of concrete changes, not as a leap of faith. After translating two hundred posts, that preview is the difference between a clean publish and a quiet mess you discover weeks later.
It matters here more than almost anywhere else, because translation is exactly where fidelity gets tested. Ghost posts are not really markdown — they’re Lexical documents, and the markdown Specter hands you is a faithful projection of that, not the underlying truth. For ordinary prose the round-trip is clean. For posts built heavily out of Koenig cards — galleries, embeds, toggles, bookmarks — a projection can lose detail on the way back, and the dry-run is where you catch that before it lands on a published page. Read how Specter handles Ghost cards before you translate a card-heavy archive, because it tells you honestly where the edges are. The point of the preview is to let you confirm a callout is still a callout before you ship the German version, rather than finding out afterward.
When the diff looks right, you sync back. The translated posts go up to Ghost, the metadata you preserved stays preserved, and the internal links you rewrote point where you meant them to.
Same blog, or a folder per language
Where the translations land is your call, and it depends on how your site is built. If you publish all your languages within one Ghost instance, the translated posts sync back into that same blog alongside the originals. If your setup runs one Ghost instance per language — a common and clean pattern — then each instance is simply its own synced folder. You connect each one with its own Admin API key and end up with a folder per language, each a local mirror you can translate, review, and push back independently.
It’s worth being precise about the boundary, though. Specter works on the content layer: the posts, their text, their metadata. It does not configure multilingual routing for you. The theme work, the URL structure between languages, the hreflang tags and canonical setup that tell search engines which version is which — all of that lives in your Ghost theme and infrastructure, and it’s a separate job from anything Specter touches. What you get from Specter is the part the pipelines kept getting wrong: the actual content of each language, correct and in sync, with a preview standing between your translation pass and your live site.
If you want the broader picture of running a multilingual publication this way, the companion piece is Specter for multilingual sites. And once your archive is local, the same folder-as-control-plane idea covers more than translation — it’s also how you’d bulk-edit Ghost SEO across every post at once.