Was ausgeliefert wurde

Jede Version und die Änderungen darunter, die jemandem auffallen würden. Neueste zuerst; die Versionen sind die Tags im Repository.

September 2026

This page

A changelog, at /changelog and linked from the footer. Every release and, between them, the changes worth naming — read from one typed list and rendered by the converter the product sells.

A page for an address that is not a page

There was none: an unmatched address got the host’s own error page, with nothing to click. There is now a 404 carrying the site’s chrome and three ways out, written once and re-rendered in the reader’s language.

Two soft 404s came out with it. A link to an article that does not exist answered 200, which a crawler indexes as a real page; and /de/history was a plain 404 in four languages, so the screen worked until somebody reloaded it.

The blog in German

Twenty-nine of the fifty-six articles are in German, and the blog can now be translated one article at a time.

The rule throughout is that a language has what it has. Its index lists only its own articles, an article claims an hreflang only for the languages that actually have text, and a language with nothing translated gets no index at all rather than a heading over an empty list. Covers are drawn per language, because the headline is part of the picture.

Email that arrives

A welcome message, sent once when an account is first used, and a notice to somebody a document has been shared with.

Both took three attempts. The notice was wired to an endpoint the app never calls, then fired after the response so the request never left the function, then blocked by a key that was genuinely absent from the first builds. Deliverability needed DMARC, not just SPF and DKIM.

Signing in with an email address

Google was the only way in. There is now a dialogue with sign-in, sign-up, a password reset and a one-time code, and an unconfirmed account is held back: no publishing by link, and ten documents rather than five hundred, until the address is confirmed.

Five languages

The interface, the documentation and the pages of words are in English, German, French, Spanish and Italian, with the words in one typed catalogue and a build step that walks every language against English: same keys, same array lengths, nothing empty, the same placeholders. It found 192 missing keys on its first run.

The language is in the address — /de/docs, /fr/csv-to-markdown — and English keeps the bare paths, because sixty-eight pages were already indexed at them.

An embed, and the frame policy the app never had

/embed is the converter with no chrome, for a page that wants to host it, and it talks to its host with postMessage. Adding it meant writing the rule that was missing: every other route now refuses to be framed at all, which nothing had said before.

The connector has its own dialogue

Adding TransformPipe to an assistant used to open the API keys dialogue — a screen headed "API keys" with a key generator at the top, so a person who chose "MCP connector" had to work out they were in the right place. It is its own dialogue now, with the address, the one-line command and the assistants already connected.

A guard for the failures that only happen on the platform

Two things had taken production down and neither could fail locally: an extensionless import that a bundler hides and Node refuses, and a vercel.json pattern that produces no deployment at all. Both are now checked before the build, and the guard was proved by reintroducing each bug.

Share an article

X, LinkedIn and Reddit, under the prose rather than above it — somebody shares an article they have read.

— 2.0.0

TransformPipe, and four conversions

The rename, at transformpipe.com, and four formats in rather than one: HTML, Word, CSV and TSV, and JSON. Each conversion has an address of its own, because "word to markdown" is a thing people type into a search box.

JSON picks a rendering per shape rather than one rule for everything — an array of flat objects becomes a table, an array of scalars a list, an object a heading per nested key, and anything past three levels a fenced block, because a heading at depth seven is not a heading.

Also: an assistant can act on an account through a connector that needs no API key pasted anywhere; fifty-six articles, up from twenty, each with a cover the build refuses to ship without; and the blog stopped being sent to everybody who opened the converter, which had been 952 kB of Markdown in the main bundle.

— 1.1.0

A blog, and real HTML for every page

Twenty articles at /blog, rendered by the converter they describe. An FAQ under the dropzone and again in the documentation, from one list.

Every page a stranger arrives on is now a real file with its own title, description, canonical link and structured data, plus sitemap.xml and robots.txt. And the downloaded .html became genuinely self-contained — it used to link its typeface from Google Fonts.

— 1.0.0

Markdown in, a document out

The first release. A converter with a preview, an HTML source view and a self-contained download; accounts and history across devices; sharing by link or by address, with a read-only page.

A public API with revocable keys and quotas, a dependency-free CLI, and a GitHub Action that comments rendered links on a pull request. Documentation at /docs, with screenshots captured from the running app.

Nur Änderungen, die im Produkt auffallen. Interner Umbau und Infrastrukturarbeit stehen nicht hier, und die Einträge selbst sind auf Englisch.