---
changelog:
  category: Release
  version: blume@1.6.1
date: '2026-09-05T23:20:35Z'
seo:
  description: >-
    Every copy affordance (Copy as Markdown, code blocks, MCP commands, prompts,
    color swatches, API panels) now falls back to the legacy copy command when
    the…
title: blume@1.6.1
type: changelog
---
### Patch Changes

- e6fc45f: Every copy affordance (Copy as Markdown, code blocks, MCP commands, prompts, color swatches, API panels) now falls back to the legacy `copy` command when the Clipboard API is unavailable or denied — in-app browsers, WebViews, insecure origins, and after a denied permission prompt — instead of doing nothing. When nothing lands on the clipboard even then, the Copy as Markdown and MCP actions flash a localized **Copy failed** label (new `actions.copyFailed` UI string, translated in every shipped pack) rather than showing no feedback at all; the other copy buttons still show no confirmation.
- 743b36b: Copy as Markdown now works in Safari and Firefox. The action fetches the page's Markdown on click, and the clipboard write used to be issued only after that fetch resolved — outside the click's user activation, which those browsers require for a clipboard write — so it failed on every click. The write is now issued inside the click with the Markdown still loading (a promised `ClipboardItem`), and browsers without that API keep the previous fetch-then-write path.
- 316df45: The default 404 page now has a Markdown twin at `/404.md` — the not-found message plus the same recovery links as the HTML page (every top-level section, the sitemap, and `llms.txt`), absolute once `deployment.site` is set. On a Vercel server build, a request for a missing page that sends `Accept: text/markdown`, or asks for a `.md`/`.mdx` URL no page backs, gets that Markdown body with the `404` status instead of the HTML shell, so agents recover from a stale URL without parsing page chrome. Both variants are skipped together when a project owns `/404` with its own `pages/404.astro` or a `404.md` content page.
- ccc3ac1: Scan an `examples.source` directory that lives outside the project root for Tailwind utilities in `<Component />` preview frames, and resolve relative `@source` paths in `theme.css` and `examples.css` from the file that declares them. A monorepo can now point Blume at sibling workspace packages without knowing the generated runtime's directory layout.
- 1df9208: Generated OG cards now show the page's own description as the subtitle (its `seo.description`, else `description`), matching the page's `og:description`, and fall back to the site-wide `seo.og.description` only for pages without one. `seo.og.description: false` still hides the subtitle on every card.
- db10b26: Keep Astro's and Vite's caches inside the hidden `.blume` runtime instead of under its `node_modules`, which is a junction into Blume's package directory. Two projects that resolve the same Blume install (a monorepo building docs and a sandbox in parallel) previously shared one content data store, so pages of whichever build lost the race rendered as 404s.
- 872caf4: Add a per-source `seoDescriptionSuffix` option to the `openapi`, `asyncapi`, and `graphql` reference blocks. Generated operation pages derive their meta description from the operation's own prose followed by a generated English sentence ("Reference for the `GET /pets` endpoint in the Petstore API."), which kept every page distinct but left non-English sites with half-translated metadata that no amount of authored prose could fix. Set `seoDescriptionSuffix: false` on a source to describe its pages with the spec's `description` (or `summary`) alone; an operation with neither falls back to its language-neutral title (`GET /pets`, the channel and action, or the GraphQL field or type name), so no page ships an empty description. The default is unchanged.
- 7869217: Serve the runtime's data snapshots from memory instead of `.blume/src/generated/*.json`. The page data behind `blume:data`, the parsed API specs, the static search index, the raw-Markdown and content-asset maps, the MCP and Ask corpora, and the rendered RSS feeds are now published into an in-process registry by the generator and served to Vite as virtual modules, so a content edit in `blume dev` invalidates exactly the modules whose data changed and reloads the browser — no JSON write, no file-watcher round trip, and nothing half-written for the dev server to observe. `blume eject` is unchanged: the ejected project keeps the JSON files and aliases each module to them.
- ac4e501: Update dependencies: Astro 7.3, `@astrojs/mdx` 8 with `@astrojs/markdown-satteri` 0.4 (MDX now compiles through the Sätteri processor Blume already configures), takumi 2.13, citty 0.2, zod 4.5, and the latest patch releases of the remaining runtime dependencies. A bare `--host` before another flag (`blume dev --host --open`) still binds all interfaces under citty's new argument parser.
- 743b36b: `blume version <id>` now preserves the line endings of a CRLF `blume.config.ts` when it inserts the new entry into `versions.archived`, instead of introducing a lone LF ahead of the entry.
