---
changelog:
  category: Release
  version: blume@1.2.0
date: '2026-07-27T01:38:21Z'
seo:
  description: >-
    Add a top-level integrations array to blume.config.ts for registering Astro
    integrations. Entries are schema-validated as an array (each element is left
    for…
title: blume@1.2.0
type: changelog
---
### Minor Changes

- 217975c: Add a top-level `integrations` array to `blume.config.ts` for registering Astro integrations. Entries are schema-validated as an array (each element is left for Astro to validate) and appended after Blume's built-in integrations in declaration order, with no sorting or deduplication. The generated Astro config loads them through a portable bridge back to `blume.config.ts` rather than serializing the instances, so function-bearing hooks survive across build, `blume dev`, config regeneration, and eject. Install and version each integration in the site itself — Blume neither adds it to the runtime's dependencies nor manages its Astro compatibility.
- 592af35: Add `blume eval`, a test suite for your docs. An AI agent — Claude Code by default, Codex with `--agent codex`, spawned from your own installation with no API keys held by Blume — answers the questions in `evals.yaml` using ONLY the documentation, served over a private MCP stdio bridge to an agent locked out of its file, shell, and web tools; a judge pass then grades each answer against the expected facts you listed. Any question the docs can't answer fails CI (relax with `--threshold`), each failure is anchored to the source page that should answer it, `--json` emits the validate/audit-compatible machine report, `--fix` hands the failing report to the agent to edit the docs interactively, and `blume eval init` drafts a starter evals file from your existing docs. No build or deployment is needed — the docs snapshot is computed from the content tree.
- 2063196: Let a header tab declare its link target with `href`. A tab's `path` scopes its sidebar section and doubles as the link, so a section whose `path` isn't a page of its own falls back to the section's first page rather than linking to a 404. That fallback only sees the content tree, so a tab pointing at a route generated outside it — the automatic `/changelog` index, or a custom page under `pages/` — lands on the section's first entry instead of the page the reader expected. Setting `href` keeps the tab on the declared route; the field is optional and tabs that omit it resolve exactly as before. Declared hrefs are localized and rebased like any other route, so they work under i18n and a `deployment.base`.
- 55e176a: Support external Ask AI endpoints on static sites and per-source OpenAPI search, llms.txt, and crawler indexing controls.

### Patch Changes

- 18e1d8d: Stop Cloudflare server builds from declaring unused `SESSION` KV and `IMAGES` bindings in the generated wrangler config. Without a configured session driver, `@astrojs/cloudflare` force-enables KV-backed sessions — making `wrangler deploy` demand a real KV namespace nothing reads — and defaults images to the runtime Cloudflare Images binding. Blume never reads `Astro.session` and every HTML route prerenders, so the generated Astro config now sets an inert in-memory session driver and `imageService: "compile"`, which pre-optimizes images at build time with sharp.
- 38475cb: `blume init` now adds `node_modules/` to the generated `.gitignore` alongside Blume's runtime and build output directories.
- 0c8f78d: Make the entire sidebar navigation back row clickable. When a drilled-in section has no index page, the chevron and title now form a single full-width back button; when it does have one, the title link and back button each fill their side of the row so there are no dead zones, and both get row hover states.
- 812b09e: Fix nested `<Tree>` folder chevrons, nested `<Accordion>` chevrons, and a nested object schema's "Show properties" toggle reflecting an ancestor's open state instead of their own. All three rotated or flipped on Tailwind's `group-open:` variant, which matches any open ancestor `.group` — the same leak as the nested sidebar chevron — so a collapsed disclosure inside an expanded one showed an open indicator. Each indicator is now scoped to its own `details`.
- 812b09e: Fix a nested sidebar group's chevron pointing down while the group is collapsed. The chevron rotated on Tailwind's `group-open:` variant, which matches any descendant of an open `.group` — and since every collapsible group in the tree is a `.group`, expanding a parent rotated the chevrons of its collapsed children too, so the arrow disagreed with the items it was hiding. The rotation is now scoped to the group's own `details`, leaving each chevron to reflect only its own open state.
- d5d6b7a: Fix the EPUB page action failing in dev with `epub is not a function`. `epub-gen-memory`'s browser bundle is a browserified UMD, and its dynamic import lives inside `node_modules/blume`, which Vite's optimizer scan doesn't crawl — so in dev it was served as raw ESM, where the UMD finds no `exports`/`define`, exposes no `default`, and strands its callable on `window.epubGen`. It now joins mermaid in `optimizeDeps.include`, naming the `/bundle` subpath that is actually imported, since optimizing the package root leaves that entry unoptimized. Production builds already bundled it correctly and are unchanged.
- 55e176a: Pagefind now honors search exclusions: pages with `search.exclude` frontmatter (and hidden pages, unless `search.indexing.includeHiddenPages` opts them in) no longer appear in local search results.
