blume 2.0.1 → 2.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +147 -0
- package/dist/cli/{chunk-qwsrynx5.js → chunk-1d7ve1dm.js} +38 -19
- package/dist/cli/{chunk-qwsrynx5.js.map → chunk-1d7ve1dm.js.map} +4 -4
- package/dist/cli/{chunk-s6jhgk0q.js → chunk-2eytanqx.js} +2 -2
- package/dist/cli/{chunk-kdp5q7ke.js → chunk-2hsdwb9n.js} +18 -19
- package/dist/cli/{chunk-kdp5q7ke.js.map → chunk-2hsdwb9n.js.map} +2 -2
- package/dist/cli/{chunk-hdpx1tax.js → chunk-2z928egk.js} +5 -5
- package/dist/cli/{chunk-jwyddg7y.js → chunk-35d4wj9f.js} +30 -24
- package/dist/cli/chunk-35d4wj9f.js.map +15 -0
- package/dist/cli/{chunk-ah61y8py.js → chunk-364znk6q.js} +2 -2
- package/dist/cli/{chunk-jts8mvcz.js → chunk-3em5wd2y.js} +25 -6
- package/dist/cli/{chunk-jts8mvcz.js.map → chunk-3em5wd2y.js.map} +3 -3
- package/dist/cli/{chunk-s1p84fyh.js → chunk-5f86nr5m.js} +63 -22
- package/dist/cli/chunk-5f86nr5m.js.map +11 -0
- package/dist/cli/{chunk-2hn4b8z7.js → chunk-5m5nmvyq.js} +170 -76
- package/dist/cli/chunk-5m5nmvyq.js.map +13 -0
- package/dist/cli/{chunk-epjnccmv.js → chunk-5xvm6tfj.js} +18 -15
- package/dist/cli/chunk-5xvm6tfj.js.map +10 -0
- package/dist/cli/{chunk-fz5wtpmh.js → chunk-6dsbexzp.js} +18 -15
- package/dist/cli/chunk-6dsbexzp.js.map +10 -0
- package/dist/cli/{chunk-vtk4a6dg.js → chunk-8ktnccpt.js} +1 -1
- package/dist/cli/{chunk-6hsn950k.js → chunk-9t7a85s3.js} +178 -48
- package/dist/cli/chunk-9t7a85s3.js.map +10 -0
- package/dist/cli/{chunk-fxypxtvm.js → chunk-a58773jm.js} +2 -2
- package/dist/cli/{chunk-mb2919y2.js → chunk-acanzt5p.js} +17 -6
- package/dist/cli/chunk-acanzt5p.js.map +10 -0
- package/dist/cli/{chunk-27g6wdth.js → chunk-akbpwfxc.js} +90 -26
- package/dist/cli/chunk-akbpwfxc.js.map +10 -0
- package/dist/cli/{chunk-wm7js3j9.js → chunk-b07cmahc.js} +2 -2
- package/dist/cli/{chunk-wgm7m9qk.js → chunk-c8chx29p.js} +179 -51
- package/dist/cli/chunk-c8chx29p.js.map +36 -0
- package/dist/cli/{chunk-qs4q5p4e.js → chunk-crgn1q09.js} +32 -14
- package/dist/cli/chunk-crgn1q09.js.map +10 -0
- package/dist/cli/chunk-e04dxsz1.js +39 -0
- package/dist/cli/chunk-e04dxsz1.js.map +10 -0
- package/dist/cli/{chunk-yt5n7ppj.js → chunk-ey84smr6.js} +17 -7
- package/dist/cli/chunk-ey84smr6.js.map +10 -0
- package/dist/cli/{chunk-f2z5v128.js → chunk-g4hq16wv.js} +14 -15
- package/dist/cli/{chunk-f2z5v128.js.map → chunk-g4hq16wv.js.map} +2 -2
- package/dist/cli/{chunk-fa25z98p.js → chunk-ga0pf4aj.js} +9 -8
- package/dist/cli/chunk-ga0pf4aj.js.map +11 -0
- package/dist/cli/{chunk-kpf8rrjc.js → chunk-hm3vjy5s.js} +109 -58
- package/dist/cli/chunk-hm3vjy5s.js.map +19 -0
- package/dist/cli/{chunk-fs23ddbb.js → chunk-j85vccga.js} +625 -750
- package/dist/cli/chunk-j85vccga.js.map +36 -0
- package/dist/cli/{chunk-ch6g3ar0.js → chunk-p3v96n38.js} +6 -6
- package/dist/cli/{chunk-ch6g3ar0.js.map → chunk-p3v96n38.js.map} +3 -3
- package/dist/cli/{chunk-q5163e60.js → chunk-p73c0m7w.js} +21 -19
- package/dist/cli/chunk-p73c0m7w.js.map +11 -0
- package/dist/cli/{chunk-dh8cwk36.js → chunk-pehfxfta.js} +24 -9
- package/dist/cli/chunk-pehfxfta.js.map +10 -0
- package/dist/cli/{chunk-qkqwkpte.js → chunk-pv29h0wf.js} +3688 -1313
- package/dist/cli/chunk-pv29h0wf.js.map +190 -0
- package/dist/cli/{chunk-6vm74dry.js → chunk-q58y5e6a.js} +10 -10
- package/dist/cli/{chunk-6vm74dry.js.map → chunk-q58y5e6a.js.map} +3 -3
- package/dist/cli/{chunk-zxcczpyx.js → chunk-r20tn01b.js} +1 -1
- package/dist/cli/{chunk-m3vmjgmq.js → chunk-r9rcc4w7.js} +16 -8
- package/dist/cli/chunk-r9rcc4w7.js.map +10 -0
- package/dist/cli/{chunk-5shv93fd.js → chunk-tkacnehg.js} +2 -2
- package/dist/cli/{chunk-zxh4d9vy.js → chunk-tzmab476.js} +4 -4
- package/dist/cli/{chunk-yw7dm696.js → chunk-vg9r4eb9.js} +24 -11
- package/dist/cli/chunk-vg9r4eb9.js.map +14 -0
- package/dist/cli/{chunk-79jhk4py.js → chunk-wrr3j9w9.js} +260 -132
- package/dist/cli/chunk-wrr3j9w9.js.map +35 -0
- package/dist/cli/{chunk-6crbhc3x.js → chunk-yfyb25rh.js} +54 -27
- package/dist/cli/chunk-yfyb25rh.js.map +14 -0
- package/dist/cli/index.js +162 -35
- package/dist/cli/index.js.map +4 -4
- package/dist/types/ai/agent-surface.d.ts +32 -0
- package/dist/types/ai/api-catalog.d.ts +7 -1
- package/dist/types/ai/ask-context.d.ts +7 -0
- package/dist/types/ai/component-markdown.d.ts +4 -4
- package/dist/types/ai/link-headers.d.ts +8 -1
- package/dist/types/ai/openapi-components.d.ts +5 -2
- package/dist/types/ai/relative-links.d.ts +11 -4
- package/dist/types/ai/skills.d.ts +4 -1
- package/dist/types/ai/static-expression.d.ts +28 -0
- package/dist/types/ai/tar.d.ts +1 -3
- package/dist/types/analytics/databuddy.d.ts +43 -0
- package/dist/types/analytics/index.d.ts +4 -0
- package/dist/types/analytics/one-dollar-stats.d.ts +48 -0
- package/dist/types/analytics/schema.d.ts +28 -0
- package/dist/types/astro/integration.d.ts +3 -2
- package/dist/types/cli/env.d.ts +5 -0
- package/dist/types/cli/init/scaffold.d.ts +19 -3
- package/dist/types/cli/init/starter-spec.d.ts +11 -0
- package/dist/types/core/base-path.d.ts +24 -1
- package/dist/types/core/config-input.d.ts +13 -11
- package/dist/types/core/config.d.ts +2 -2
- package/dist/types/core/directive-diagnostics.d.ts +12 -0
- package/dist/types/core/graph.d.ts +2 -0
- package/dist/types/core/heading-markers.d.ts +5 -7
- package/dist/types/core/i18n-ui.d.ts +31 -0
- package/dist/types/core/i18n.d.ts +9 -1
- package/dist/types/core/last-modified.d.ts +10 -0
- package/dist/types/core/links.d.ts +3 -1
- package/dist/types/core/load-module.d.ts +10 -0
- package/dist/types/core/locale-links.d.ts +12 -2
- package/dist/types/core/meta.d.ts +13 -1
- package/dist/types/core/nav-diagnostics.d.ts +10 -0
- package/dist/types/core/navigation.d.ts +38 -0
- package/dist/types/core/ordering-prefix.d.ts +4 -0
- package/dist/types/core/safe-links.d.ts +3 -1
- package/dist/types/core/schema.d.ts +59 -13
- package/dist/types/core/sources/github-releases.d.ts +5 -0
- package/dist/types/core/sources/lower.d.ts +38 -13
- package/dist/types/core/sources/normalize.d.ts +23 -2
- package/dist/types/core/sources/remote.d.ts +11 -1
- package/dist/types/core/sources/resolve.d.ts +12 -0
- package/dist/types/core/sources/types.d.ts +31 -0
- package/dist/types/core/sources/watch.d.ts +12 -5
- package/dist/types/core/standard-schema.d.ts +5 -0
- package/dist/types/core/types.d.ts +9 -0
- package/dist/types/deploy/adapters/node.d.ts +5 -2
- package/dist/types/deploy/adapters/types.d.ts +7 -0
- package/dist/types/deploy/artifacts.d.ts +6 -4
- package/dist/types/deploy/cloudflare-negotiation.d.ts +3 -2
- package/dist/types/deploy/headers.d.ts +36 -7
- package/dist/types/deploy/node-headers.d.ts +43 -8
- package/dist/types/deploy/platforms/netlify.d.ts +27 -2
- package/dist/types/deploy/platforms/node.d.ts +6 -5
- package/dist/types/deploy/platforms/types.d.ts +15 -0
- package/dist/types/deploy/platforms/vercel.d.ts +3 -2
- package/dist/types/deploy/redirects.d.ts +31 -15
- package/dist/types/deploy/vercel-negotiation.d.ts +3 -2
- package/dist/types/markdown/directives.d.ts +62 -0
- package/dist/types/markdown/features.d.ts +21 -0
- package/dist/types/markdown/mdast.d.ts +63 -0
- package/dist/types/openapi/asyncapi.d.ts +4 -2
- package/dist/types/openapi/model.d.ts +20 -6
- package/dist/types/search/sync/algolia.d.ts +3 -1
- package/docs/01-quickstart.mdx +3 -2
- package/docs/02-deployment.mdx +20 -9
- package/docs/08-faq.mdx +10 -3
- package/docs/advanced/changelog.mdx +1 -1
- package/docs/advanced/custom-pages.mdx +7 -5
- package/docs/cli/audit.mdx +19 -3
- package/docs/cli/doctor.mdx +2 -2
- package/docs/cli/evals.mdx +4 -4
- package/docs/cli/index.mdx +4 -1
- package/docs/cli/translate.mdx +4 -4
- package/docs/cli/version.mdx +1 -1
- package/docs/configuration/analytics.mdx +42 -2
- package/docs/configuration/assistant.mdx +1 -1
- package/docs/configuration/customization.mdx +6 -3
- package/docs/configuration/index.mdx +5 -3
- package/docs/configuration/search.mdx +2 -2
- package/docs/content/components.mdx +2 -2
- package/docs/content/frontmatter.mdx +5 -1
- package/docs/content/i18n.mdx +3 -1
- package/docs/content/index.mdx +8 -4
- package/docs/content/islands.mdx +1 -1
- package/docs/content/meta.mdx +7 -3
- package/docs/content/navigation.mdx +29 -4
- package/docs/content/sources.mdx +18 -16
- package/docs/content/syntax.mdx +14 -0
- package/docs/content/versioning.mdx +2 -1
- package/docs/discoverability/agent-discovery.mdx +22 -8
- package/docs/discoverability/index.mdx +4 -3
- package/docs/discoverability/llms-txt.mdx +2 -5
- package/docs/discoverability/markdown.mdx +6 -4
- package/docs/discoverability/mcp.mdx +4 -0
- package/docs/discoverability/metadata.mdx +3 -2
- package/docs/discoverability/open-graph.mdx +8 -4
- package/docs/discoverability/rss.mdx +4 -2
- package/docs/references/asyncapi.mdx +2 -2
- package/docs/references/graphql.mdx +2 -2
- package/docs/references/openapi.mdx +6 -4
- package/package.json +1 -1
- package/skills/blume-migrate/SKILL.md +6 -6
- package/skills/blume-migrate/references/docusaurus.md +6 -6
- package/skills/blume-migrate/references/fumadocs.md +1 -1
- package/skills/blume-migrate/references/mintlify.md +3 -3
- package/skills/blume-migrate/references/monorepo.md +1 -1
- package/skills/blume-migrate/references/nextra.md +2 -2
- package/skills/blume-migrate/references/starlight.md +5 -5
- package/skills/blume-migrate/scripts/mintlify-codemod.mjs +9 -4
- package/skills/blume-update-docs/references/audit-checklist.md +1 -1
- package/src/ai/agent-readability.ts +2 -2
- package/src/ai/agent-surface.ts +56 -0
- package/src/ai/ai-catalog.ts +6 -2
- package/src/ai/api/handlers.ts +2 -2
- package/src/ai/api/spec.ts +17 -4
- package/src/ai/api-catalog.ts +13 -3
- package/src/ai/ask-context.ts +14 -2
- package/src/ai/ask-data.ts +26 -12
- package/src/ai/changelog-markdown.ts +2 -2
- package/src/ai/component-markdown.ts +43 -37
- package/src/ai/link-headers.ts +22 -8
- package/src/ai/llms.ts +22 -10
- package/src/ai/markdown.ts +23 -11
- package/src/ai/mcp/discovery.ts +2 -2
- package/src/ai/mcp/query.ts +2 -2
- package/src/ai/mcp/server.ts +80 -9
- package/src/ai/openapi-components.ts +22 -6
- package/src/ai/relative-links.ts +99 -15
- package/src/ai/serializers.ts +2 -1
- package/src/ai/skills.ts +14 -1
- package/src/ai/static-expression.ts +416 -0
- package/src/ai/tar.ts +139 -12
- package/src/ai/visibility.ts +45 -14
- package/src/analytics/databuddy.ts +67 -0
- package/src/analytics/head.ts +8 -0
- package/src/analytics/index.ts +7 -0
- package/src/analytics/one-dollar-stats.ts +86 -0
- package/src/analytics/posthog.ts +21 -3
- package/src/analytics/schema.ts +4 -0
- package/src/astro/generate.ts +72 -28
- package/src/astro/include-hmr.ts +31 -12
- package/src/astro/include-refresh.ts +19 -8
- package/src/astro/integration.ts +108 -14
- package/src/astro/runtime-modules.ts +28 -13
- package/src/astro/templates.ts +139 -57
- package/src/audit/catalog.ts +2 -2
- package/src/audit/checks/assets.ts +25 -5
- package/src/audit/checks/content.ts +20 -2
- package/src/audit/checks/i18n.ts +46 -8
- package/src/audit/checks/indexability.ts +39 -19
- package/src/audit/checks/links.ts +22 -1
- package/src/audit/checks/llms.ts +6 -3
- package/src/audit/checks/network.ts +3 -1
- package/src/audit/checks/og-image.ts +10 -0
- package/src/audit/checks/robots.ts +6 -1
- package/src/audit/checks/sitemap.ts +56 -31
- package/src/audit/checks/social.ts +21 -2
- package/src/audit/crawl.ts +88 -15
- package/src/audit/graph.ts +3 -1
- package/src/audit/report.ts +54 -17
- package/src/audit/run.ts +13 -9
- package/src/audit/snapshot.ts +5 -0
- package/src/audit/types.ts +18 -0
- package/src/audit/url.ts +37 -6
- package/src/cli/args.ts +32 -0
- package/src/cli/build-failure.ts +50 -0
- package/src/cli/commands/audit.ts +11 -1
- package/src/cli/commands/build.ts +19 -5
- package/src/cli/commands/check.ts +2 -0
- package/src/cli/commands/doctor.ts +3 -1
- package/src/cli/commands/eval.ts +20 -18
- package/src/cli/commands/init.ts +15 -5
- package/src/cli/commands/preview.ts +15 -0
- package/src/cli/commands/sync.ts +2 -0
- package/src/cli/commands/translate.ts +18 -18
- package/src/cli/commands/upgrade.ts +11 -0
- package/src/cli/commands/validate.ts +3 -1
- package/src/cli/dev-lock.ts +157 -37
- package/src/cli/eject-scripts.ts +32 -7
- package/src/cli/env.ts +12 -1
- package/src/cli/init/scaffold.ts +117 -11
- package/src/cli/init/starter-spec.ts +235 -0
- package/src/cli/report-format.ts +11 -6
- package/src/components/colors.ts +19 -0
- package/src/components/content/AccordionItem.astro +26 -22
- package/src/components/content/Badge.astro +7 -12
- package/src/components/content/Card.astro +2 -2
- package/src/components/content/Component.astro +11 -5
- package/src/components/content/Expandable.astro +5 -1
- package/src/components/content/Frame.astro +2 -7
- package/src/components/content/GithubInfo.astro +12 -2
- package/src/components/content/Prompt.astro +2 -7
- package/src/components/content/Tab.astro +0 -1
- package/src/components/content/Tabs.astro +58 -5
- package/src/components/content/Tile.astro +1 -1
- package/src/components/content/Tooltip.astro +69 -7
- package/src/components/content/Tree.astro +7 -2
- package/src/components/content/TypeTable.astro +10 -5
- package/src/components/content/Update.astro +8 -2
- package/src/components/content/auto-type-table.ts +4 -1
- package/src/components/content/badge-color.ts +20 -0
- package/src/components/content/base-href.ts +14 -22
- package/src/components/content/inline-markdown.ts +27 -7
- package/src/components/copy-feedback.ts +35 -8
- package/src/components/islands/assistant.tsx +37 -6
- package/src/components/islands/base-path.ts +47 -10
- package/src/components/islands/hooks.ts +42 -21
- package/src/components/islands/webmcp.ts +16 -10
- package/src/components/layout/Banner.astro +23 -4
- package/src/components/layout/Breadcrumbs.astro +5 -2
- package/src/components/layout/DiscoveryLinks.astro +9 -5
- package/src/components/layout/Header.astro +23 -10
- package/src/components/layout/LanguageSwitcher.astro +2 -2
- package/src/components/layout/Logo.astro +5 -0
- package/src/components/layout/NavSelector.astro +8 -3
- package/src/components/layout/NavTabMenu.astro +133 -0
- package/src/components/layout/NavTree.astro +31 -12
- package/src/components/layout/NavTreeCache.astro +5 -2
- package/src/components/layout/NavTreeScript.astro +45 -5
- package/src/components/layout/PageActions.astro +4 -3
- package/src/components/layout/PageLayout.astro +28 -13
- package/src/components/layout/Pagination.astro +3 -3
- package/src/components/layout/ReferenceLayout.astro +4 -1
- package/src/components/layout/RootLayout.astro +25 -12
- package/src/components/layout/Search.astro +38 -14
- package/src/components/layout/VersionBanner.astro +2 -2
- package/src/components/layout/analytics-client.ts +14 -0
- package/src/components/layout/toc-active.ts +41 -0
- package/src/components/layout/toc-element.ts +8 -14
- package/src/components/openapi/ApiTagOperations.astro +2 -2
- package/src/components/openapi/AsyncApiOperation.astro +7 -4
- package/src/components/openapi/GraphqlChip.astro +2 -2
- package/src/components/openapi/GraphqlType.astro +11 -3
- package/src/components/openapi/MessageComposer.astro +1 -1
- package/src/components/openapi/Operation.astro +23 -5
- package/src/components/openapi/PanelTabs.astro +4 -1
- package/src/components/openapi/Playground.astro +8 -2
- package/src/components/openapi/RequestPanel.astro +13 -6
- package/src/components/openapi/SchemaProperty.astro +11 -33
- package/src/components/openapi/SchemaTable.astro +34 -52
- package/src/components/openapi/async.ts +38 -6
- package/src/components/openapi/helpers.ts +100 -12
- package/src/components/openapi/message-composer.ts +14 -1
- package/src/components/openapi/message-model.ts +12 -2
- package/src/components/openapi/message.ts +21 -3
- package/src/components/openapi/operation-model.ts +119 -17
- package/src/components/openapi/panel.ts +31 -5
- package/src/components/openapi/param-style.ts +181 -0
- package/src/components/openapi/playground-client.ts +110 -23
- package/src/components/openapi/playground-schema.ts +25 -6
- package/src/components/openapi/request.ts +192 -26
- package/src/components/openapi/schema-tree.ts +209 -0
- package/src/components/openapi/snippets.ts +113 -19
- package/src/components/openapi/validate-json.ts +1 -1
- package/src/components/openapi/ws-client.ts +18 -2
- package/src/core/base-path.ts +69 -8
- package/src/core/config-input.ts +13 -11
- package/src/core/config.ts +18 -4
- package/src/core/diagnostics.ts +219 -30
- package/src/core/directive-diagnostics.ts +99 -0
- package/src/core/frontmatter.ts +21 -18
- package/src/core/graph.ts +120 -11
- package/src/core/heading-markers.ts +5 -18
- package/src/core/i18n-ui.ts +39 -2
- package/src/core/i18n.ts +44 -5
- package/src/core/last-modified.ts +25 -3
- package/src/core/links.ts +7 -4
- package/src/core/load-module.ts +20 -0
- package/src/core/locale-links.ts +22 -18
- package/src/core/manifest.ts +3 -2
- package/src/core/meta.ts +89 -12
- package/src/core/nav-diagnostics.ts +56 -1
- package/src/core/navigation.ts +272 -83
- package/src/core/ordering-prefix.ts +27 -0
- package/src/core/project-graph.ts +50 -6
- package/src/core/safe-href.ts +53 -1
- package/src/core/safe-links.ts +11 -2
- package/src/core/schema.ts +94 -18
- package/src/core/sources/assets.ts +83 -41
- package/src/core/sources/contentful-rich-text.ts +28 -20
- package/src/core/sources/contentful.ts +25 -12
- package/src/core/sources/filesystem.ts +25 -3
- package/src/core/sources/github-releases.ts +131 -11
- package/src/core/sources/lexical.ts +30 -20
- package/src/core/sources/lower.ts +276 -56
- package/src/core/sources/mdx-remote.ts +52 -16
- package/src/core/sources/normalize.ts +456 -119
- package/src/core/sources/notion.ts +77 -34
- package/src/core/sources/obsidian.ts +40 -9
- package/src/core/sources/payload.ts +1 -0
- package/src/core/sources/portable-text.ts +85 -49
- package/src/core/sources/remote.ts +18 -2
- package/src/core/sources/resolve.ts +52 -33
- package/src/core/sources/sanity.ts +1 -0
- package/src/core/sources/strapi-blocks.ts +28 -19
- package/src/core/sources/strapi.ts +1 -0
- package/src/core/sources/types.ts +31 -0
- package/src/core/sources/watch.ts +20 -7
- package/src/core/standard-schema.ts +10 -6
- package/src/core/types.ts +9 -0
- package/src/core/ui-packs/ar.ts +13 -0
- package/src/core/ui-packs/bg.ts +13 -0
- package/src/core/ui-packs/bn.ts +13 -0
- package/src/core/ui-packs/ca.ts +13 -0
- package/src/core/ui-packs/cs.ts +13 -0
- package/src/core/ui-packs/da.ts +13 -0
- package/src/core/ui-packs/de.ts +13 -0
- package/src/core/ui-packs/el.ts +13 -0
- package/src/core/ui-packs/es.ts +13 -0
- package/src/core/ui-packs/fa.ts +13 -0
- package/src/core/ui-packs/fi.ts +13 -0
- package/src/core/ui-packs/fr.ts +13 -0
- package/src/core/ui-packs/he.ts +13 -0
- package/src/core/ui-packs/hi.ts +13 -0
- package/src/core/ui-packs/hr.ts +13 -0
- package/src/core/ui-packs/hu.ts +13 -0
- package/src/core/ui-packs/id.ts +13 -0
- package/src/core/ui-packs/it.ts +13 -0
- package/src/core/ui-packs/ja.ts +13 -0
- package/src/core/ui-packs/ko.ts +13 -0
- package/src/core/ui-packs/nl.ts +13 -0
- package/src/core/ui-packs/no.ts +13 -0
- package/src/core/ui-packs/pl.ts +13 -0
- package/src/core/ui-packs/pt-br.ts +13 -0
- package/src/core/ui-packs/pt.ts +13 -0
- package/src/core/ui-packs/ro.ts +13 -0
- package/src/core/ui-packs/ru.ts +13 -0
- package/src/core/ui-packs/sk.ts +13 -0
- package/src/core/ui-packs/sr.ts +13 -0
- package/src/core/ui-packs/sv.ts +13 -0
- package/src/core/ui-packs/th.ts +13 -0
- package/src/core/ui-packs/tr.ts +13 -0
- package/src/core/ui-packs/uk.ts +13 -0
- package/src/core/ui-packs/vi.ts +13 -0
- package/src/core/ui-packs/zh-tw.ts +13 -0
- package/src/core/ui-packs/zh.ts +13 -0
- package/src/core/version-cut.ts +69 -17
- package/src/core/versions.ts +4 -1
- package/src/deploy/adapters/node.ts +5 -2
- package/src/deploy/adapters/registry.ts +2 -1
- package/src/deploy/adapters/types.ts +13 -1
- package/src/deploy/artifacts.ts +52 -11
- package/src/deploy/cloudflare-negotiation.ts +27 -16
- package/src/deploy/headers.ts +75 -55
- package/src/deploy/node-headers.ts +148 -27
- package/src/deploy/platforms/cloudflare.ts +13 -3
- package/src/deploy/platforms/netlify.ts +83 -5
- package/src/deploy/platforms/node.ts +8 -5
- package/src/deploy/platforms/static.ts +2 -0
- package/src/deploy/platforms/types.ts +15 -0
- package/src/deploy/platforms/vercel.ts +10 -3
- package/src/deploy/redirects.ts +68 -21
- package/src/deploy/robots.ts +2 -2
- package/src/deploy/rss.ts +4 -3
- package/src/deploy/sitemap.ts +7 -5
- package/src/deploy/vercel-negotiation.ts +35 -3
- package/src/eval/agents.ts +10 -2
- package/src/eval/run.ts +25 -0
- package/src/markdown/base-links.ts +74 -29
- package/src/markdown/directives.ts +242 -36
- package/src/markdown/features.ts +17 -0
- package/src/markdown/index.ts +13 -9
- package/src/markdown/mdast.ts +5 -2
- package/src/markdown/relative-links.ts +15 -27
- package/src/markdown/route-snapshot.ts +37 -0
- package/src/og/card.ts +149 -9
- package/src/og/derive.ts +156 -5
- package/src/og/index.ts +1 -0
- package/src/openapi/asyncapi.ts +4 -2
- package/src/openapi/graphql-build.ts +28 -2
- package/src/openapi/model.ts +99 -27
- package/src/openapi/proxy.ts +63 -10
- package/src/openapi/render-mdx.ts +51 -3
- package/src/registry/eject.ts +297 -43
- package/src/search/adapters/version-scope.ts +30 -0
- package/src/search/documents.ts +89 -27
- package/src/search/popular.ts +2 -1
- package/src/search/sync/algolia.ts +36 -2
- package/src/seo/jsonld.ts +7 -3
- package/src/sources/registry.ts +5 -0
- package/src/theme/entry.ts +11 -4
- package/src/translate/agents.ts +6 -1
- package/src/translate/ledger.ts +26 -3
- package/src/translate/meta.ts +76 -24
- package/src/translate/run.ts +14 -8
- package/src/translate/validate.ts +14 -2
- package/src/translate/work-list.ts +91 -19
- package/src/upgrade/upgrade.ts +36 -4
- package/dist/cli/chunk-27g6wdth.js.map +0 -10
- package/dist/cli/chunk-2hn4b8z7.js.map +0 -12
- package/dist/cli/chunk-6crbhc3x.js.map +0 -14
- package/dist/cli/chunk-6hsn950k.js.map +0 -10
- package/dist/cli/chunk-79jhk4py.js.map +0 -35
- package/dist/cli/chunk-82bbrxdn.js +0 -51
- package/dist/cli/chunk-82bbrxdn.js.map +0 -10
- package/dist/cli/chunk-abh8yjkn.js +0 -31
- package/dist/cli/chunk-abh8yjkn.js.map +0 -10
- package/dist/cli/chunk-ce574jw2.js +0 -23
- package/dist/cli/chunk-ce574jw2.js.map +0 -10
- package/dist/cli/chunk-dh8cwk36.js.map +0 -10
- package/dist/cli/chunk-epjnccmv.js.map +0 -10
- package/dist/cli/chunk-fa25z98p.js.map +0 -11
- package/dist/cli/chunk-fs23ddbb.js.map +0 -35
- package/dist/cli/chunk-fz5wtpmh.js.map +0 -10
- package/dist/cli/chunk-jwyddg7y.js.map +0 -15
- package/dist/cli/chunk-kpf8rrjc.js.map +0 -19
- package/dist/cli/chunk-m3vmjgmq.js.map +0 -10
- package/dist/cli/chunk-mb2919y2.js.map +0 -10
- package/dist/cli/chunk-q5163e60.js.map +0 -11
- package/dist/cli/chunk-qkqwkpte.js.map +0 -182
- package/dist/cli/chunk-qs4q5p4e.js.map +0 -10
- package/dist/cli/chunk-s1p84fyh.js.map +0 -10
- package/dist/cli/chunk-wgm7m9qk.js.map +0 -36
- package/dist/cli/chunk-yt5n7ppj.js.map +0 -10
- package/dist/cli/chunk-yw7dm696.js.map +0 -14
- /package/dist/cli/{chunk-s6jhgk0q.js.map → chunk-2eytanqx.js.map} +0 -0
- /package/dist/cli/{chunk-hdpx1tax.js.map → chunk-2z928egk.js.map} +0 -0
- /package/dist/cli/{chunk-ah61y8py.js.map → chunk-364znk6q.js.map} +0 -0
- /package/dist/cli/{chunk-vtk4a6dg.js.map → chunk-8ktnccpt.js.map} +0 -0
- /package/dist/cli/{chunk-fxypxtvm.js.map → chunk-a58773jm.js.map} +0 -0
- /package/dist/cli/{chunk-wm7js3j9.js.map → chunk-b07cmahc.js.map} +0 -0
- /package/dist/cli/{chunk-zxcczpyx.js.map → chunk-r20tn01b.js.map} +0 -0
- /package/dist/cli/{chunk-5shv93fd.js.map → chunk-tkacnehg.js.map} +0 -0
- /package/dist/cli/{chunk-zxh4d9vy.js.map → chunk-tzmab476.js.map} +0 -0
package/docs/cli/evals.mdx
CHANGED
|
@@ -74,7 +74,7 @@ Write questions your users actually ask — the ones from support threads, GitHu
|
|
|
74
74
|
|
|
75
75
|
## Failing CI
|
|
76
76
|
|
|
77
|
-
The exit code is the contract: any failed question exits non-zero
|
|
77
|
+
The exit code is the contract: any failed question exits non-zero, except a `severity: warning` one — its miss is reported as a warning and never counts against the gate or `--threshold`. When the agent run itself fails — the reader or judge errors out rather than grading an answer — the report says `run failed:` and points at the question in your evals file instead of naming a docs page to fix, since the docs weren't graded. `--threshold` relaxes the gate to a passing fraction when you're digging out of a backlog:
|
|
78
78
|
|
|
79
79
|
```bash
|
|
80
80
|
blume eval # every question must pass
|
|
@@ -99,9 +99,9 @@ This writes the full JSON report to a file and opens the agent interactively wit
|
|
|
99
99
|
## Flags
|
|
100
100
|
|
|
101
101
|
- `--agent codex|claude` — which agent CLI runs the reader and judge. Defaults to `codex`.
|
|
102
|
-
- `--file <path>` — the evals file. Defaults to `evals.yaml`.
|
|
103
|
-
- `--threshold <0..1>` — minimum passing fraction before the run exits non-zero. Defaults to `1`.
|
|
104
|
-
- `--timeout <seconds>` — reader time limit per question. Defaults to `180
|
|
102
|
+
- `--file <path>` — the evals file, relative to the project root or absolute. Defaults to `evals.yaml`.
|
|
103
|
+
- `--threshold <0..1>` — minimum passing fraction before the run exits non-zero, with `severity: warning` misses counted as passing. Defaults to `1`. An empty value is an error, so `--threshold "$EVAL_THRESHOLD"` with the variable unset can't switch the gate off.
|
|
104
|
+
- `--timeout <seconds>` — reader time limit per question. Defaults to `180`, and can be at most `2147483` (about 24 days), the longest a timer can wait.
|
|
105
105
|
- `--json` — emit the report as JSON on stdout.
|
|
106
106
|
- `--fix` — after a failing run, hand the report to the agent to fix the docs interactively.
|
|
107
107
|
- `--verbose` — include the reader's full answer under each failure.
|
package/docs/cli/index.mdx
CHANGED
|
@@ -15,7 +15,7 @@ blume <command> [options]
|
|
|
15
15
|
| `blume dev` | Start the dev server with hot reload. |
|
|
16
16
|
| `blume build` | Build the static (or server) site. |
|
|
17
17
|
| `blume preview` | Preview the last build. |
|
|
18
|
-
| `blume add
|
|
18
|
+
| `blume add [item]` | Install a source component from the registry (no item lists what's available). |
|
|
19
19
|
| `blume sync` | Re-fetch remote content sources and regenerate. |
|
|
20
20
|
| `blume eject` | Promote the runtime into a standalone Astro app. |
|
|
21
21
|
| `blume check` | Type-check the site with `astro check`. |
|
|
@@ -47,11 +47,14 @@ blume <command> [options]
|
|
|
47
47
|
- `blume build --isolated` — build into a throwaway `.blume-verify/` runtime (and its own `dist/`) instead of `.blume/`, so a running `blume dev` server and your real `dist/` are left untouched. See [Verifying while the dev server runs](#verifying-while-the-dev-server-runs).
|
|
48
48
|
- `blume preview --host --port <n>` — bind the preview server.
|
|
49
49
|
- `blume sync --force` — re-fetch remote sources, dropping the cached snapshot first.
|
|
50
|
+
- `blume sync --preview` — include drafts and unpublished CMS content.
|
|
51
|
+
- `blume sync --strict` — fail on diagnostics.
|
|
50
52
|
- `blume add <item> --force` — overwrite files that already exist.
|
|
51
53
|
- `blume check --preview` — include drafts and unpublished CMS content when checking.
|
|
52
54
|
- `blume check --strict` — fail on content diagnostics as well as type errors.
|
|
53
55
|
- `blume check --isolated` — type-check in a throwaway `.blume-verify/` runtime so a running `blume dev` server is left untouched. See [Verifying while the dev server runs](#verifying-while-the-dev-server-runs).
|
|
54
56
|
- `blume eject --yes` — skip the confirmation prompt.
|
|
57
|
+
- `blume eject --force` — eject again over an already-ejected app, overwriting its `astro.config.mjs` and `src/`.
|
|
55
58
|
|
|
56
59
|
The commands with a page of their own list every flag there: [`blume doctor`](/docs/cli/doctor), [`blume validate`](/docs/cli/validate), [`blume audit`](/docs/cli/audit), [`blume eval`](/docs/cli/evals), [`blume translate`](/docs/cli/translate), and [`blume version`](/docs/cli/version). `blume validate`, `blume doctor`, `blume audit`, `blume eval`, and `blume translate` take `--json` to print machine-readable results on stdout for CI and editor integrations (see [Validate](/docs/cli/validate#json-output) for the diagnostics shape); `build`, `check`, and `dev` report to the terminal only. Every command rejects a flag it doesn't take, suggesting the closest match and listing the flags it accepts, so a typo like `--isolatd` fails instead of being ignored.
|
|
57
60
|
|
package/docs/cli/translate.mdx
CHANGED
|
@@ -33,8 +33,8 @@ A first translation has no precedent to match, so pin the choice up front with [
|
|
|
33
33
|
|
|
34
34
|
## What gets translated
|
|
35
35
|
|
|
36
|
-
- **Pages** — `.md`/`.mdx` files in the default locale. The agent translates the prose and only the human-visible frontmatter values (`title`, `description`, `sidebar.label`, `sidebar.badge`, `seo.title`, `seo.description`). Targets follow your parser: `fr/guides/install.mdx` under `dir`, `guides/install.fr.mdx` under `dot`.
|
|
37
|
-
- **Folder navigation titles** — under the `dir` parser, each locale's needed [`meta.ts`](/docs/content/meta) titles are translated in one batched call, and the generated per-locale `meta.ts` copies every other key (`order`, `pages`, `icon`, `collapsed`) verbatim so the locale's sidebar keeps its ordering.
|
|
36
|
+
- **Pages** — `.md`/`.mdx` files in the default locale. The agent translates the prose and only the human-visible frontmatter values (`title`, `description`, `sidebar.label`, `sidebar.badge`, `seo.title`, `seo.description`). Targets follow your parser: `fr/guides/install.mdx` under `dir`, `guides/install.fr.mdx` under `dot`. A translation that already exists is rewritten where it lives, even under another name (a hand-written `fr/guides/install.md`), so a retranslation never adds a second copy of the page.
|
|
37
|
+
- **Folder navigation titles** — under the `dir` parser, each locale's needed [`meta.ts`](/docs/content/meta) titles are translated in one batched call, and the generated per-locale `meta.ts` copies every other key (`order`, `pages`, `icon`, `collapsed`) verbatim so the locale's sidebar keeps its ordering. It goes in the locale's folder as it exists on disk (`pt-br/` for a configured `pt-BR`), and a `meta.js` or `meta.mjs` already there is rewritten instead of gaining a `meta.ts` beside it.
|
|
38
38
|
|
|
39
39
|
Translations you wrote by hand are **adopted, never overwritten**: a translation that exists but has no ledger entry is stamped as current and left alone. Only `--force` retranslates it.
|
|
40
40
|
|
|
@@ -72,10 +72,10 @@ The JSON report carries the same `diagnostics` + `summary` shape as `blume valid
|
|
|
72
72
|
|
|
73
73
|
## Flags
|
|
74
74
|
|
|
75
|
-
- `--codex` / `--claude` — which agent CLI translates. Exactly one is required
|
|
75
|
+
- `--codex` / `--claude` — which agent CLI translates. Exactly one is required, except with `--check`, which runs no agent and takes neither.
|
|
76
76
|
- `--check` — report drift and exit non-zero, without writing anything.
|
|
77
77
|
- `--concurrency <n>` — parallel agent sessions. Defaults to `4`, max `16`.
|
|
78
78
|
- `--locale <codes>` — comma-separated target locales (defaults to every non-default locale).
|
|
79
79
|
- `--force` — retranslate everything, up-to-date and hand-authored files included.
|
|
80
|
-
- `--timeout <seconds>` — agent time limit per file. Defaults to `600`; the ceiling exists to catch hung agents, so large pages have room to finish.
|
|
80
|
+
- `--timeout <seconds>` — agent time limit per file. Defaults to `600`; the ceiling exists to catch hung agents, so large pages have room to finish. At most `2147483` (about 24 days), the longest a timer can wait.
|
|
81
81
|
- `--json` — emit the report as JSON on stdout, in both modes.
|
package/docs/cli/version.mdx
CHANGED
|
@@ -12,7 +12,7 @@ blume version v1.0
|
|
|
12
12
|
That does four things:
|
|
13
13
|
|
|
14
14
|
1. **Copies the content tree** into a folder named after the id (`docs/v1.0/`), leaving existing snapshots out of the copy.
|
|
15
|
-
2. **Rewrites root-absolute links inside the copy** so they stay within the snapshot: `/guides/x` becomes `/v1.0/guides/x`. Fenced and inline code are left untouched, and links to pages the snapshot has no copy of — generated API references, remote sources like a changelog — keep pointing at the live pages.
|
|
15
|
+
2. **Rewrites root-absolute links inside the copy** so they stay within the snapshot: `/guides/x` becomes `/v1.0/guides/x`. That covers inline links and images, reference-style definitions (`[x]: /guides/x`), and HTML `href` and `src` attributes in either quote style, and a link that spells out your [`basePath`](/docs/deployment#mount-the-docs-under-a-path) keeps it (`/docs/guides/x` becomes `/docs/v1.0/guides/x`). Fenced and inline code are left untouched, and links to pages the snapshot has no copy of — generated API references, remote sources like a changelog — keep pointing at the live pages.
|
|
16
16
|
3. **Registers the id** in `versions.archived` in `blume.config.ts`. The first cut turns versioning on, adding a `versions` block with the id archived and the live docs labeled "Latest". When the config is shaped in a way it won't edit, it warns and prints the entry to paste instead.
|
|
17
17
|
4. **Reports what it did**: the files copied, the pages whose links were rewritten, and a reminder that archived versions are frozen and that `blume dev` needs a restart to pick the snapshot up.
|
|
18
18
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Analytics
|
|
3
|
-
description: First-party web analytics — PostHog, Google Analytics, Plausible, Mixpanel, Segment, and
|
|
3
|
+
description: First-party web analytics — PostHog, Google Analytics, Plausible, Mixpanel, Segment, and more — as adapters in blume.config.ts.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
Blume injects analytics for you from an `analytics` list in `blume.config.ts`. Each entry is an adapter imported from `blume/analytics`: one per provider, plus `script()` for anything without one.
|
|
@@ -38,6 +38,7 @@ Every identifier below — a project key, a measurement ID, a site token — is
|
|
|
38
38
|
| `clarity()` | [Microsoft Clarity](#microsoft-clarity) | `id` |
|
|
39
39
|
| `clearbit()` | [Clearbit](#clearbit) | `key` |
|
|
40
40
|
| `cloudflare()` | [Cloudflare Web Analytics](#cloudflare-web-analytics) | `token` |
|
|
41
|
+
| `databuddy()` | [Databuddy](#databuddy) | `clientId` |
|
|
41
42
|
| `fathom()` | [Fathom](#fathom) | `site` |
|
|
42
43
|
| `googleAnalytics()` | [Google Analytics 4](#google-analytics-4) | `id` |
|
|
43
44
|
| `googleTagManager()` | [Google Tag Manager](#google-tag-manager) | `id` |
|
|
@@ -46,6 +47,7 @@ Every identifier below — a project key, a measurement ID, a site token — is
|
|
|
46
47
|
| `hotjar()` | [Hotjar](#hotjar) | `id` |
|
|
47
48
|
| `logrocket()` | [LogRocket](#logrocket) | `id` |
|
|
48
49
|
| `mixpanel()` | [Mixpanel](#mixpanel) | `token` |
|
|
50
|
+
| `oneDollarStats()` | [OneDollarStats](#onedollarstats) | — |
|
|
49
51
|
| `pirsch()` | [Pirsch](#pirsch) | `code` |
|
|
50
52
|
| `plausible()` | [Plausible](#plausible) | `domain` |
|
|
51
53
|
| `posthog()` | [PostHog](#posthog) | `key` |
|
|
@@ -70,6 +72,8 @@ analytics: [
|
|
|
70
72
|
|
|
71
73
|
`key` and `host` are the two options Blume maps (`host` becomes `api_host`). Anything else you pass — `persistence`, `capture_pageview`, `autocapture`, `disable_session_recording`, and every other `posthog.init` option — is forwarded to `posthog.init` verbatim.
|
|
72
74
|
|
|
75
|
+
Blume sends a `$pageview` for each client-router navigation only while PostHog captures page loads alone, which is its behavior when you set neither `capture_pageview` nor `defaults`. With `capture_pageview: "history_change"`, or a `defaults` date such as `"2025-05-24"` from PostHog's current snippet, PostHog captures navigations itself, so Blume sends nothing extra. With `capture_pageview: false`, no pageviews are sent at all.
|
|
76
|
+
|
|
73
77
|
## Vercel Web Analytics
|
|
74
78
|
|
|
75
79
|
Add `vercel()` to include [Vercel Web Analytics](https://vercel.com/docs/analytics). Blume renders Vercel's official Astro component, which injects the first-party script served from your own domain once Web Analytics is enabled for the project in the Vercel dashboard.
|
|
@@ -172,6 +176,38 @@ analytics: [
|
|
|
172
176
|
|
|
173
177
|
`code` becomes `data-code`, and Blume gives the tag the `pianjs` id Pirsch's script finds itself by. Any other option becomes its own `data-` attribute (`dev`, `exclude`, `include`, `domain`, `endpoint`, …).
|
|
174
178
|
|
|
179
|
+
## Databuddy
|
|
180
|
+
|
|
181
|
+
Pass your **client ID** (from the website's settings in [Databuddy](https://databuddy.cc)) to `databuddy()`.
|
|
182
|
+
|
|
183
|
+
```ts blume.config.ts lineNumbers
|
|
184
|
+
analytics: [
|
|
185
|
+
databuddy({
|
|
186
|
+
clientId: "xxxxxxxxxxxxxxxxxxxxx",
|
|
187
|
+
"track-web-vitals": "true", // optional: any other `data-` setting
|
|
188
|
+
"skip-patterns": '["/admin/*"]',
|
|
189
|
+
}),
|
|
190
|
+
],
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
`clientId` becomes `data-client-id`. Any other option becomes its own `data-` attribute on the tag, so name it the way the attribute reads, in kebab-case (`track-web-vitals`, `track-errors`, `track-outgoing-links`, `api-url`, …). Databuddy ignores a camelCase name like `trackWebVitals`. Values are strings: `"true"` or `"false"` for a switch, and a JSON array for `skip-patterns` and `mask-patterns`. Databuddy reads any other list value as empty.
|
|
194
|
+
|
|
195
|
+
## OneDollarStats
|
|
196
|
+
|
|
197
|
+
Add the site's domain in [OneDollarStats](https://onedollarstats.com), then list `oneDollarStats()`. It needs no key, because OneDollarStats matches events to a site by the domain they come from.
|
|
198
|
+
|
|
199
|
+
```ts blume.config.ts lineNumbers
|
|
200
|
+
analytics: [oneDollarStats()],
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Each option becomes its own `data-` attribute on the tag, and values are strings:
|
|
204
|
+
|
|
205
|
+
- `hostname` reports every event under that host name (`docs.example.com`, with no `https://` or path) on every host, not just `localhost`, so preview deploys and staging count as that site's traffic. Leave it unset unless every build should report under that name.
|
|
206
|
+
- `devmode: "true"` together with `hostname` lets a local `blume preview` send events. On `localhost` the tracker sends nothing without both, so keep them out of the committed config.
|
|
207
|
+
- `url` is the collector endpoint events are posted to (`https://collector.onedollarstats.com/events` by default), not the site's URL.
|
|
208
|
+
- `autocollect: "false"` turns off automatic page views.
|
|
209
|
+
- `"hash-routing": "true"` sends a page view on every navigation, even when only the `#fragment` changes, like a table-of-contents click. Blume leaves the attribute off for `"false"`, because the tracker turns hash routing on whenever it's present.
|
|
210
|
+
|
|
175
211
|
## Mixpanel
|
|
176
212
|
|
|
177
213
|
Pass your **project token** (project settings → Access Keys in [Mixpanel](https://mixpanel.com)) to `mixpanel()`. If the project uses EU or India data residency, set `region` to match, or Mixpanel drops the events.
|
|
@@ -351,6 +387,8 @@ analytics: [
|
|
|
351
387
|
| `clearbit()` | `key` | — | Clearbit publishable API key. Required. |
|
|
352
388
|
| `cloudflare()` | `token` | — | Cloudflare Web Analytics site token (manual setup). Required. |
|
|
353
389
|
| `cloudflare()` | anything else | — | Forwarded in the beacon's `data-cf-beacon` JSON verbatim. |
|
|
390
|
+
| `databuddy()` | `clientId` | — | Databuddy client ID. Required. |
|
|
391
|
+
| `databuddy()` | anything else | — | Rendered as a `data-` attribute on the tag. |
|
|
354
392
|
| `fathom()` | `site` | — | Fathom site ID. Required. |
|
|
355
393
|
| `fathom()` | `spa` | `"auto"` | Fathom's history-change tracking (`data-spa`). |
|
|
356
394
|
| `fathom()` | anything else | — | Rendered as a `data-` attribute on the tag. |
|
|
@@ -370,6 +408,8 @@ analytics: [
|
|
|
370
408
|
| `mixpanel()` | `token` | — | Mixpanel project token. Required. |
|
|
371
409
|
| `mixpanel()` | `region` | `us` | Data residency region: `us`, `eu`, or `in`. |
|
|
372
410
|
| `mixpanel()` | anything else | `track_pageview: "url-with-path-and-query-string"` | Merged into the `mixpanel.init` options verbatim. |
|
|
411
|
+
| `oneDollarStats()` | `hostname` | — | Bare host name every event is reported under, on every host. |
|
|
412
|
+
| `oneDollarStats()` | anything else | — | Rendered as a `data-` attribute on the tag (`"hash-routing": "false"` is left off). |
|
|
373
413
|
| `pirsch()` | `code` | — | Pirsch identification code. Required. |
|
|
374
414
|
| `pirsch()` | anything else | — | Rendered as a `data-` attribute on the tag. |
|
|
375
415
|
| `plausible()` | `domain` | — | The site's domain in Plausible. Required. |
|
|
@@ -389,4 +429,4 @@ analytics: [
|
|
|
389
429
|
|
|
390
430
|
## Custom events
|
|
391
431
|
|
|
392
|
-
Blume's page feedback sends a custom event through every configured adapter that has a client API — PostHog, Mixpanel, Heap, Segment, Hightouch, Amplitude, LogRocket, Adobe, Google Analytics, Google Tag Manager (as a `{ event }` push on `window.dataLayer`), Plausible, Fathom, Pirsch, Clarity, Hotjar, and Vercel. Cloudflare and Clearbit have no event API. Every event also fires as a `blume:track` CustomEvent on `window` with `{ event, props }` in `detail`, so a `script()` adapter can forward it anywhere else. For deploying your built site, see [Deployment](/docs/deployment).
|
|
432
|
+
Blume's page feedback sends a custom event through every configured adapter that has a client API — PostHog, Mixpanel, Heap, Segment, Hightouch, Amplitude, LogRocket, Adobe, Google Analytics, Google Tag Manager (as a `{ event }` push on `window.dataLayer`), Plausible, Databuddy, Fathom, OneDollarStats (with each property value as a string), Pirsch, Clarity, Hotjar, and Vercel. Cloudflare and Clearbit have no event API. Every event also fires as a `blume:track` CustomEvent on `window` with `{ event, props }` in `detail`, so a `script()` adapter can forward it anywhere else. For deploying your built site, see [Deployment](/docs/deployment).
|
|
@@ -54,7 +54,7 @@ Your text is **appended to** the built-in instructions rather than replacing the
|
|
|
54
54
|
|
|
55
55
|
The assistant is **grounded in your docs**. For each question it retrieves the most relevant pages — using the same lexical [Orama](/docs/configuration/search) index that powers on-page search — and injects them into the model's system prompt, so answers come from your content instead of the model's own knowledge. The assistant is told to answer only from the retrieved pages, to say when something isn't covered, and to cite the pages it drew from.
|
|
56
56
|
|
|
57
|
-
The page the reader is currently on is added to the context first and used to scope retrieval to that page's language, so answers stay relevant to where they are in the docs. Retrieval runs at request time from a snapshot baked into the build, so it works regardless of your [search](/docs/configuration/search) provider — even with `search: false` — and needs no configuration.
|
|
57
|
+
The page the reader is currently on is added to the context first and used to scope retrieval to that page's language — and, on a [versioned](/docs/content/versioning) site, to its docs version — so answers stay relevant to where they are in the docs. Retrieval runs at request time from a snapshot baked into the build, so it works regardless of your [search](/docs/configuration/search) provider — even with `search: false` — and needs no configuration.
|
|
58
58
|
|
|
59
59
|
Grounding is on for every adapter except **[Inkeep](#inkeep)**, which runs its own retrieval over the content you've indexed in its dashboard.
|
|
60
60
|
|
|
@@ -97,6 +97,7 @@ Wired slots:
|
|
|
97
97
|
| `Breadcrumbs` | The breadcrumb trail | `crumbs` |
|
|
98
98
|
| `TableOfContents` | The on-this-page outline | `headings`, `title`, `variant` |
|
|
99
99
|
| `Pagination` | The prev/next footer links | `prev`, `next`, `strings` |
|
|
100
|
+
| `Feedback` | The "Was this page helpful?" rating below the article (rendered only when [`feedback`](/docs/configuration#page-feedback) is on) | `strings` |
|
|
100
101
|
| `PageHeader` | An injection point above the article (no built-in) | `page`, `headings`, `route` |
|
|
101
102
|
| `PageFooter` | An injection point below the article (no built-in) | `page`, `headings`, `route` |
|
|
102
103
|
| `Footer` | A site-wide footer after the content grid (no built-in) | `site`, `navigation`, `ui` |
|
|
@@ -184,10 +185,12 @@ npx blume eject --yes
|
|
|
184
185
|
|
|
185
186
|
Eject is a one-way step: the hidden `.blume/` runtime becomes a normal Astro app you own and can modify directly. The `blume` package stays importable, so you keep its components, theme, and Markdown processors.
|
|
186
187
|
|
|
187
|
-
Eject points your `package.json` scripts at `astro dev` and `astro build`, and adds the packages the Astro app imports by name — `astro`, `@tailwindcss/vite`, the search client, integrations, and adapter the config wires in, React when an island, example, or the assistant uses it, `ai` for the assistant route, and `epub-gen-memory` for EPUB export — at the ranges Blume itself uses. Run an install before `dev` or `build`; eject lists what it added. Every path in the ejected app is relative, so it builds from any checkout, CI included.
|
|
188
|
+
Eject points your `package.json` scripts at `astro dev` and `astro build`, and adds the packages the Astro app imports by name — `astro`, `@tailwindcss/vite`, `tailwindcss` and `@tailwindcss/typography` for the generated stylesheets, the search client, integrations, and adapter the config wires in, React when an island, example, or the assistant uses it, `ai` for the assistant route, and `epub-gen-memory` for EPUB export — at the ranges Blume itself uses. Run an install before `dev` or `build`; eject lists what it added. Every path in the ejected app is relative, so it builds from any checkout, CI included.
|
|
188
189
|
|
|
189
|
-
From then on, run the app through its own scripts (`npm run dev`, `npm run build`): `blume dev` and `blume
|
|
190
|
+
From then on, run the app through its own scripts (`npm run dev`, `npm run build`): `blume dev`, `blume build`, `blume check`, `blume sync`, and `blume preview` stop in an ejected project and point you there. Running `blume eject` again refuses too, since it would overwrite your edits; pass `--force` to regenerate the app anyway.
|
|
190
191
|
|
|
191
192
|
### What eject keeps
|
|
192
193
|
|
|
193
|
-
The
|
|
194
|
+
The routes the hidden runtime serves as pages are written into the app's `src/pages`, so it answers the same URLs: each page's Markdown twin, the [404 page](/docs/advanced/custom-pages#404-page) with its `/404.md` and `/404.json` twins, the hosted MCP server, and the [JSON docs API](/docs/discoverability/json-api) at `/api/docs/…` and `/openapi.json` that `llms.txt` and the not-found page point agents to.
|
|
195
|
+
|
|
196
|
+
The ejected app's `build` script runs plain `astro build`, and the artifacts `blume build` layers on top — the search index (and a hosted provider's index sync), `llms.txt` and `llms-full.txt`, `sitemap.xml`, `robots.txt`, `agent-readability.json`, the `.well-known` discovery files, Agent Skills, and the platform `_redirects`/`_headers` files — are still produced: the Blume integration in the ejected `astro.config.mjs` writes them from Astro's `astro:build:done` hook, scanning the project (your `blume.config.ts` and content) the way the CLI did. What the ejected build does not do is the CLI's adapter post-processing: the Vercel and Cloudflare `Accept: text/markdown` routing splices, the Vercel function-bundle audit, the `node()` server-entry wrapper (the `.well-known` discovery files' media types and CORS headers, the sandbox on downloaded SVGs, and each redirect's exact status), the header rules a `netlify()` server build writes into `.netlify/v1/config.json`, Cloudflare's Worker naming (after your project) and its `.wrangler/deploy` redirect for running `wrangler deploy` from the project root, and the `--analyze`/`--budget-*` gate.
|
|
@@ -125,7 +125,7 @@ logo: {
|
|
|
125
125
|
`text` controls the wordmark independently of the mark:
|
|
126
126
|
|
|
127
127
|
- **Omit `text`** and the brand uses your site `title` (the default).
|
|
128
|
-
- **Set `text: ""`** to show the mark alone — handy when the logo image already includes the wordmark.
|
|
128
|
+
- **Set `text: ""`** to show the mark alone — handy when the logo image already includes the wordmark. Screen readers then announce the brand link by the image's `alt`, or by your site `title` when it has none.
|
|
129
129
|
- **Set `text` with no `image`** for a text-only logo.
|
|
130
130
|
|
|
131
131
|
### Favicon
|
|
@@ -272,7 +272,7 @@ A key can be declared site-wide or per-type, not both. See [Per-type keys](/docs
|
|
|
272
272
|
|
|
273
273
|
## GitHub
|
|
274
274
|
|
|
275
|
-
Point Blume at your repository with `github`. It powers the header [repository link](/docs/content/navigation#repository-link) and the **Edit on GitHub**
|
|
275
|
+
Point Blume at your repository with `github`. It powers the header [repository link](/docs/content/navigation#repository-link) and the **Edit on GitHub** [page action](/docs/content/navigation#page-actions):
|
|
276
276
|
|
|
277
277
|
```ts blume.config.ts lineNumbers
|
|
278
278
|
github: {
|
|
@@ -364,6 +364,8 @@ dateFormat: { year: "numeric", month: "2-digit", day: "2-digit" },
|
|
|
364
364
|
| `timeZone` | IANA time zone. Defaults to `UTC`, so a date reads the same regardless of where the site builds. |
|
|
365
365
|
| `calendar`, `numberingSystem` | Calendar system (e.g. `"japanese"`) and numbering system (e.g. `"arab"`). |
|
|
366
366
|
|
|
367
|
+
`timeZone`, `calendar`, and `numberingSystem` don't change the shape: a `dateFormat` that sets only those keeps the long form.
|
|
368
|
+
|
|
367
369
|
## SEO and agents
|
|
368
370
|
|
|
369
371
|
Metadata, Open Graph images, RSS feeds, JSON-LD, the sitemap, and `robots.txt` live under `seo`; `llms.txt`, raw Markdown, the JSON API, the MCP server, and the discovery manifests live under `agents`. Both are covered page by page in the [Discoverability](/docs/discoverability) section, which treats search engines and AI agents as two audiences for the same machine-readable layer. The reader-facing model features — the assistant and the Open in chat action — live under `ai`.
|
|
@@ -381,7 +383,7 @@ seo: {
|
|
|
381
383
|
| Option | Default | Description |
|
|
382
384
|
| --- | --- | --- |
|
|
383
385
|
| `og.enabled` | auto | Per-page Open Graph images — on when a site URL is set. |
|
|
384
|
-
| `rss.enabled` | `true` | Build feeds for blog and changelog content. |
|
|
386
|
+
| `rss.enabled` | `true` | Build feeds for blog and changelog content (needs deployment.site). |
|
|
385
387
|
| `rss.types` | `["blog", "changelog"]` | Content types that each get a feed. |
|
|
386
388
|
| `rss.limit` | `50` | Maximum items per feed. |
|
|
387
389
|
| `sitemap` | `true` | Generate sitemap.xml (needs deployment.site). |
|
|
@@ -79,7 +79,7 @@ search: {
|
|
|
79
79
|
|
|
80
80
|
Each fence's body and title (`blume.config.ts` above) become searchable; the language and fence markers don't. On `.mdx` pages the index reads components as the text they show — a Card's title, a Tab's label, a TypeTable's descriptions — using the same serializers as the [agent surfaces](/docs/discoverability/markdown), so an `agents.markdownComponents` entry covers your own components too. The option has no effect on Pagefind or Mixedbread. Expect the index to grow with your fenced content — the client index ships to every reader, hosted adapters cap record size (Algolia rejects the sync batch when one page's record exceeds its plan's limit, leaving the previous index live), and a hit inside a fence shows flattened code in the result excerpt.
|
|
81
81
|
|
|
82
|
-
On a [versioned](/docs/content/versioning) site, results default to the version being viewed, with an "All versions" toggle in the dialog footer (remembered per reader). Cross-version hits name their version on the row. Orama, FlexSearch, Algolia, and Typesense honor the scoping — hosted records carry a `version` facet, with the current docs uploaded as `"current"
|
|
82
|
+
On a [versioned](/docs/content/versioning) site, results default to the version being viewed, with an "All versions" toggle in the dialog footer (remembered per reader). Cross-version hits name their version on the row. Orama, FlexSearch, Algolia, and Typesense honor the scoping — hosted records carry a `version` facet, with the current docs uploaded as `"current"`. Pagefind, Orama Cloud, and Mixedbread don't scope by version: their results span every version, and the dialog leaves out the toggle.
|
|
83
83
|
|
|
84
84
|
## Tags
|
|
85
85
|
|
|
@@ -145,7 +145,7 @@ Pagefind only runs during `blume build`, so search isn't available in `blume dev
|
|
|
145
145
|
|
|
146
146
|
### Algolia
|
|
147
147
|
|
|
148
|
-
The browser queries [Algolia](https://www.algolia.com) directly with your search-only key. Each `blume build` replaces the index using the admin key from `ALGOLIA_ADMIN_API_KEY` (the build warns and skips the upload if it's unset). The whole index is replaced on every sync, so pages you delete or rename don't linger as stale results.
|
|
148
|
+
The browser queries [Algolia](https://www.algolia.com) directly with your search-only key. Each `blume build` replaces the index using the admin key from `ALGOLIA_ADMIN_API_KEY` (the build warns and skips the upload if it's unset). The whole index is replaced on every sync, so pages you delete or rename don't linger as stale results. The sync also adds `filterOnly(locale)` and `filterOnly(version)` to the index's `attributesForFaceting`, keeping any facets you declared yourself, because the dialog scopes results by language and docs version, and in Algolia a filter on an attribute that isn't declared for faceting matches nothing.
|
|
149
149
|
|
|
150
150
|
```ts blume.config.ts lineNumbers
|
|
151
151
|
import { algolia } from "blume/search";
|
|
@@ -3,7 +3,7 @@ title: Components
|
|
|
3
3
|
description: Cards, steps, tabs, accordions, badges, code groups, frames, trees, type tables, live previews, and diffs — the built-in components, usable in any MDX page.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
Blume ships an accessible, themeable component set available in any `.mdx` page with **no imports**. Each one is shown below with a live preview and its source. Components are vanilla and React-free; React
|
|
6
|
+
Blume ships an accessible, themeable component set available in any `.mdx` page with **no imports**. Each one is shown below with a live preview and its source. Components are vanilla and React-free; React switches on only when your project uses it — any `.tsx` or `.jsx` file in the project, a React [island](/docs/content/islands), [`<Component>`](#component) example, or [component override](/docs/configuration/customization) — or when the [assistant](/docs/configuration/assistant) is enabled.
|
|
7
7
|
|
|
8
8
|
## Card and CardGroup
|
|
9
9
|
|
|
@@ -560,7 +560,7 @@ export interface ButtonProps {
|
|
|
560
560
|
|
|
561
561
|
## GitHub info
|
|
562
562
|
|
|
563
|
-
A card linking to a GitHub repository with its
|
|
563
|
+
A card linking to a GitHub repository with its star and fork counts. The counts are fetched at build time — no client JavaScript — so they show the numbers as of your last build, not live ones; the card still renders without them if the API is unreachable. Pass `owner` and `repo`, or omit them to use the repository from your `blume.config`. Set a `GITHUB_TOKEN` environment variable to lift the API rate limit; a `token` prop overrides it for one card, but the environment variable keeps the token out of your content.
|
|
564
564
|
|
|
565
565
|
The card reads the instance from [`github.host`](/docs/configuration#github-enterprise), so on an Enterprise-hosted site explicit `owner`/`repo` address that instance too. Pass `host` to point one card somewhere else — a public project from an Enterprise site, say; the REST base is derived from it the same way it is from `github.host`.
|
|
566
566
|
|
|
@@ -23,7 +23,11 @@ Every page accepts the following frontmatter. All fields are optional.
|
|
|
23
23
|
description:
|
|
24
24
|
"Post author(s) for blog/changelog content — a name, or objects with a name plus optional avatar/url and any extra fields. Preserved as-is.",
|
|
25
25
|
},
|
|
26
|
-
slug: {
|
|
26
|
+
slug: {
|
|
27
|
+
type: "string",
|
|
28
|
+
description:
|
|
29
|
+
"Set the page's full route from the content root (guides/setup). It replaces the whole path the file's location gives the page, not just the last segment. A . or .. segment is an error: browsers resolve it away, so no link could reach the page.",
|
|
30
|
+
},
|
|
27
31
|
draft: {
|
|
28
32
|
type: "boolean",
|
|
29
33
|
default: "false",
|
package/docs/content/i18n.mdx
CHANGED
|
@@ -43,6 +43,8 @@ docs/
|
|
|
43
43
|
| `docs/guides/quickstart.mdx` | `/guides/quickstart` |
|
|
44
44
|
| `docs/fr/guides/quickstart.mdx` | `/fr/guides/quickstart` |
|
|
45
45
|
|
|
46
|
+
Don't give the default locale a folder of its own: only the other codes are locale folders, so `docs/en/` with an `en` default is ordinary content that publishes at `/en/…` (and at `/fr/en/…` as a French fallback). Blume warns when it finds one.
|
|
47
|
+
|
|
46
48
|
You only translate the files you want — everything else falls back automatically (see [Fallbacks](#fallbacks)).
|
|
47
49
|
|
|
48
50
|
### Filename suffixes
|
|
@@ -81,7 +83,7 @@ i18n: {
|
|
|
81
83
|
|
|
82
84
|
## Per-locale navigation
|
|
83
85
|
|
|
84
|
-
Each language gets its own sidebar, built from that locale's files — so translations can diverge in structure, ordering, or labels. Folder [`meta.ts`](/docs/content/meta) files resolve per locale, too: under the default `dir` parser, put a `meta.ts` under `fr/guides/` to order the French group independently. Under the `dot` parser translations sit next to the originals, so a folder's `meta.ts` applies to every locale. Everything else about [navigation](/docs/content/navigation) works the same, per language.
|
|
86
|
+
Each language gets its own sidebar, built from that locale's files — so translations can diverge in structure, ordering, or labels. Folder [`meta.ts`](/docs/content/meta) files resolve per locale, too: under the default `dir` parser, put a `meta.ts` under `fr/guides/` to order the French group independently. Until a locale has one (or a shared `meta.$.ts`), its group mirrors the [fallback](#fallbacks) locale's — that folder's `meta.ts` and the `sidebar.display` its index page sets — so pages that fall back keep the same titles, order, and collapsible groups. Under the `dot` parser translations sit next to the originals, so a folder's `meta.ts` applies to every locale. Everything else about [navigation](/docs/content/navigation) works the same, per language.
|
|
85
87
|
|
|
86
88
|
Header tabs are configured, not derived from content, so their labels localize in `blume.config.ts`: a tab `label` accepts a per-locale map (`{ en: "Docs", fr: "Documentation" }`) alongside the plain-string form, falling back to the default locale's entry for locales you haven't filled in. See [Tabs](/docs/content/navigation#tabs). Tab paths, header links, and the header logo's link move into the reader's locale too, whenever that locale serves the route, so the header stays inside one language. A route only the default locale serves — a [custom page](/docs/advanced/custom-pages) or the generated [changelog](/docs/advanced/changelog) index — keeps its own path instead of pointing at a localized URL that would 404.
|
|
87
89
|
|
package/docs/content/index.mdx
CHANGED
|
@@ -29,15 +29,19 @@ Each file maps to a route by its path under the content root:
|
|
|
29
29
|
|
|
30
30
|
Nested folders become nested routes, and an `index.mdx` inside a folder becomes that folder's own page.
|
|
31
31
|
|
|
32
|
+
Characters that would break a page's URL — `#`, `?`, `%`, and `:` — are dropped from its route, so `100%.mdx` publishes at `/100`. Keep `#` and `?` out of file and folder names altogether: Astro's content loader can't read such a file, so Blume reports it as an error and leaves it out of the site. Rename `sdks/c#.mdx` to `sdks/c.mdx` and it publishes at `/sdks/c`, the route the characters would have been dropped from anyway.
|
|
33
|
+
|
|
32
34
|
## Ordering with numeric prefixes
|
|
33
35
|
|
|
34
|
-
Prefix a file or folder with a number to control its order in the sidebar. The prefix is stripped from the URL, so you can reorder pages without breaking links:
|
|
36
|
+
Prefix a file or folder with a number and a `-`, `_`, or `.` to control its order in the sidebar. The prefix is stripped from the URL, so you can reorder pages without breaking links:
|
|
35
37
|
|
|
36
38
|
```txt
|
|
37
39
|
01-introduction.mdx -> /introduction
|
|
38
40
|
02-installation.mdx -> /installation
|
|
39
41
|
```
|
|
40
42
|
|
|
43
|
+
A version or an ISO date at the start of a name is part of the name, not an order: `1.2.0.mdx` routes to `/1.2.0`, and `2024-01-05-launch.mdx` to `/2024-01-05-launch`. Only file and folder names lose a prefix (an Obsidian vault's notes count as files). A frontmatter `slug`, and a page from a [content source](/docs/content/sources) such as a CMS or GitHub Releases, keep the name they were given.
|
|
44
|
+
|
|
41
45
|
Ordering has several layers — see [Navigation](/docs/content/navigation) for the full precedence rules.
|
|
42
46
|
|
|
43
47
|
## Group folders
|
|
@@ -48,7 +52,7 @@ Wrap a folder name in parentheses to group its pages in the sidebar **without**
|
|
|
48
52
|
docs/(internal)/security.mdx -> /security
|
|
49
53
|
```
|
|
50
54
|
|
|
51
|
-
The pages share an “Internal” sidebar group but keep flat, parenthesis-free URLs.
|
|
55
|
+
The pages share an “Internal” sidebar group but keep flat, parenthesis-free URLs. A group folder takes a [numeric prefix](#ordering-with-numeric-prefixes) like any folder, inside or outside the parentheses: `(01-internal)` and `01-(internal)` both sort first and route like `(internal)`.
|
|
52
56
|
|
|
53
57
|
## Drafts
|
|
54
58
|
|
|
@@ -82,7 +86,7 @@ The type is independent of where the file lives, but by convention blog posts go
|
|
|
82
86
|
|
|
83
87
|
## Feeds
|
|
84
88
|
|
|
85
|
-
Blume generates an RSS feed automatically for each content type listed in [`rss.types`](/docs/discoverability/rss) — `blog` and `changelog` by default — as long as it has at least one page. Feeds are served at `/<type>/rss.xml`:
|
|
89
|
+
Blume generates an RSS feed automatically for each content type listed in [`seo.rss.types`](/docs/discoverability/rss) — `blog` and `changelog` by default — as long as it has at least one page. Feeds are served at `/<type>/rss.xml`:
|
|
86
90
|
|
|
87
91
|
| Type | Feed |
|
|
88
92
|
| ----------- | -------------------- |
|
|
@@ -108,7 +112,7 @@ Every page gets an automatic table of contents, built from its headings. On wide
|
|
|
108
112
|
|
|
109
113
|
Blume slugifies each heading into an anchor, so every entry links straight to its section — and you can deep-link to any heading by appending its slug to the URL (`.../my-page#getting-started`).
|
|
110
114
|
|
|
111
|
-
|
|
115
|
+
By default the contents list your `##` and `###` headings (H2 and H3); set [`toc`](/docs/configuration#table-of-contents) to change the heading range or turn the table of contents off. A page with no headings in that range simply has no table of contents.
|
|
112
116
|
|
|
113
117
|
## Where to next
|
|
114
118
|
|
package/docs/content/islands.mdx
CHANGED
|
@@ -22,7 +22,7 @@ export default function Counter() {
|
|
|
22
22
|
Here's a live counter: <Counter />
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
-
The filename is the component name, so it **must be a PascalCase identifier** — letters, digits, and underscores only (`Counter.tsx` → `<Counter />`). Lowercase filenames
|
|
25
|
+
The filename is the component name, so it **must be a PascalCase identifier** — letters, digits, and underscores only (`Counter.tsx` → `<Counter />`). Lowercase filenames and names with dashes/dots/spaces (like `Time-Picker.tsx`) are skipped with a build warning. When two islands resolve to the same name — `Counter.tsx` and `Counter.vue`, or two `Counter.tsx` files in different subfolders — Blume keeps the first by file path and ignores the other, with a build warning.
|
|
26
26
|
|
|
27
27
|
:::note
|
|
28
28
|
Islands are for **interactive** UI. For a static component you reuse across pages (a styled callout, a pricing table), use an [MDX override](/docs/configuration/customization) instead — it ships no JavaScript.
|
package/docs/content/meta.mdx
CHANGED
|
@@ -23,6 +23,8 @@ export default defineMeta({
|
|
|
23
23
|
|
|
24
24
|
Every field is optional — set only what you want to override.
|
|
25
25
|
|
|
26
|
+
Blume only reads `meta.ts` files from folders your content covers: one under a folder your content `exclude` globs skip, or outside every `include` glob, is never imported. With `root: "."` and `exclude: ["**/_*", "**/.*", "src/**"]`, an unrelated `src/lib/meta.ts` is left alone. An `exclude` replaces the default `["**/_*", "**/.*"]` rather than adding to it, so list those two as well to keep `_`-prefixed partials and dot-files unpublished.
|
|
27
|
+
|
|
26
28
|
## Fields
|
|
27
29
|
|
|
28
30
|
| Field | Type | Description |
|
|
@@ -34,7 +36,9 @@ Every field is optional — set only what you want to override.
|
|
|
34
36
|
| `display` | `"flat" \| "group" \| "page"` | Render mode for this group; overrides the global [`navigation.sidebar.display`](/docs/content/navigation#display-modes). |
|
|
35
37
|
| `pages` | `string[]` | Explicit order for the group's children, by slug. |
|
|
36
38
|
|
|
37
|
-
The `pages` array lists children by slug — the folder or file name with its numeric prefix and any parentheses stripped (so `01-quickstart.mdx` is `"quickstart"`). Children you leave out still appear,
|
|
39
|
+
The `pages` array lists children by slug — the folder or file name with its numeric prefix and any parentheses stripped (so `01-quickstart.mdx` is `"quickstart"`). Each listed child takes its position in the array as its order (`0`, `1`, `2`, …). Children you leave out still appear, sorted by their own order: an `index` page stays first, a child with a `sidebar.order`, a numeric prefix, or its own `meta.ts` `order` sorts by that number among the listed ones, and a child with none of these goes after them. List every child when the array should be the whole order.
|
|
40
|
+
|
|
41
|
+
The array orders pages among pages and groups among groups, but it doesn't interleave the two where loose pages list above groups: at the top of the sidebar (and of each [tab](/docs/content/navigation#tabs) section), and in any group with a [`flat`](/docs/content/navigation#display-modes) subgroup, whose header would otherwise seem to own the pages after it. There, `pages: ["advanced", "intro"]` still lists the `intro` page above the `advanced` group.
|
|
38
42
|
|
|
39
43
|
How groups render — flat headers, collapsible disclosures, or drill-in panels — defaults to the sidebar-wide `navigation.sidebar.display`; set `display` here to override it for this group alone. A folder's `index` page can also set it from frontmatter, which wins over `meta.ts` — see [per-group overrides](/docs/content/navigation#per-group-overrides).
|
|
40
44
|
|
|
@@ -53,13 +57,13 @@ export default defineMeta(async () => ({
|
|
|
53
57
|
|
|
54
58
|
## Ordering within a group
|
|
55
59
|
|
|
56
|
-
The `pages` array sets the order of a group's children. Anything it omits falls back to each page's frontmatter `sidebar.order`, then the file system (an `index` page first, then numeric prefixes, then alphabetical). For the full sidebar precedence — including an explicit config sidebar — see [Navigation › Ordering](/docs/content/navigation#ordering).
|
|
60
|
+
The `pages` array sets the order of a group's children, and it wins over a listed page's own `sidebar.order` or a listed subfolder's own `order`. Anything it omits falls back to each page's frontmatter `sidebar.order`, then the file system (an `index` page first, then numeric prefixes, then alphabetical). For the full sidebar precedence — including an explicit config sidebar — see [Navigation › Ordering](/docs/content/navigation#ordering).
|
|
57
61
|
|
|
58
62
|
To group pages _without_ adding a URL segment, you don't need a `meta.ts` at all: use a parenthesized folder name — see [Pages › Group folders](/docs/content#group-folders).
|
|
59
63
|
|
|
60
64
|
## Internationalization
|
|
61
65
|
|
|
62
|
-
Under [i18n](/docs/content/i18n), folder meta resolves per locale: put a `meta.ts` under `fr/guides/` to order the French group independently.
|
|
66
|
+
Under [i18n](/docs/content/i18n), folder meta resolves per locale: put a `meta.ts` under `fr/guides/` to order the French group independently. Without one (or a shared `meta.$.ts`, below), the French group mirrors the fallback locale's `meta.ts`.
|
|
63
67
|
|
|
64
68
|
For folder meta that's identical in every language, add a `$` marker so one file serves all locales without duplication:
|
|
65
69
|
|
|
@@ -150,7 +150,9 @@ navigation: {
|
|
|
150
150
|
}
|
|
151
151
|
```
|
|
152
152
|
|
|
153
|
-
|
|
153
|
+
A tab's optional `icon` (a [built-in icon](/docs/content/components#icon) name, image path/URL, or inline SVG) shows beside its label, in the header and in the mobile navigation drawer.
|
|
154
|
+
|
|
155
|
+
An enabled [OpenAPI](/docs/references/openapi), [AsyncAPI](/docs/references/asyncapi), or [GraphQL](/docs/references/graphql) reference mounts at its route but doesn't add a tab on its own — point a tab at that route to surface it in the header (and, for the native renderer, to scope its operations sidebar), with whatever label you like:
|
|
154
156
|
|
|
155
157
|
```ts blume.config.ts
|
|
156
158
|
navigation: {
|
|
@@ -174,6 +176,24 @@ navigation: {
|
|
|
174
176
|
|
|
175
177
|
Tabs that don't set `href` keep the resolution above.
|
|
176
178
|
|
|
179
|
+
Give a tab `items` to make it a dropdown. The tab no longer links anywhere itself: it opens a menu of its items in the header, and expands them in place in the mobile navigation drawer. Its `path` still scopes the sidebar and marks the tab as current, and `href` doesn't apply. Each item takes a `label` and a `path`, plus an optional `icon`, `description`, and `tag`, like a [selector](#selectors) item:
|
|
180
|
+
|
|
181
|
+
```ts blume.config.ts lineNumbers
|
|
182
|
+
navigation: {
|
|
183
|
+
tabs: [
|
|
184
|
+
{ label: "Guides", path: "/guides" },
|
|
185
|
+
{
|
|
186
|
+
label: "SDKs",
|
|
187
|
+
path: "/sdks",
|
|
188
|
+
items: [
|
|
189
|
+
{ label: "JavaScript", path: "/sdks/javascript", description: "Node and the browser" },
|
|
190
|
+
{ label: "Python", path: "/sdks/python", tag: "Beta" },
|
|
191
|
+
],
|
|
192
|
+
},
|
|
193
|
+
],
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
177
197
|
On an [i18n](/docs/content/i18n) site, a tab's `label` (and a dropdown item's) can be a per-locale map instead of a string — the active locale's entry wins, then the default locale's:
|
|
178
198
|
|
|
179
199
|
```ts blume.config.ts
|
|
@@ -185,6 +205,8 @@ navigation: {
|
|
|
185
205
|
}
|
|
186
206
|
```
|
|
187
207
|
|
|
208
|
+
A [selector](#selectors)'s labels don't take a map: its `label` and each of its items' labels are plain strings.
|
|
209
|
+
|
|
188
210
|
Tabs also **scope the sidebar**: when the current route falls under a tab's `path`, the sidebar shows only that section's pages — so `/adapters/*` lists the adapters and nothing else. The folder at a tab's `path` becomes the section, so this needs no extra config beyond the tabs themselves; structure your content into a folder per tab and point each tab at it.
|
|
189
211
|
|
|
190
212
|
On a route under no tab (or a tab whose `path` is `/`), the sidebar shows the pages that _don't_ belong to a tab — each tab's folder is hidden from it, since that section already has its own tab in the header. So a root landing page lists your loose top-level pages while the sectioned content stays behind its tab, mirroring Fumadocs' root folders. If a route has no pages of its own to show this way, the full tree is shown instead, so the sidebar is never left blank.
|
|
@@ -247,6 +269,8 @@ navigation: {
|
|
|
247
269
|
|
|
248
270
|
Each item is a page route (a string), a group (`label` + `items`), or a link (`label` + `href`). Groups can nest, override the global [`display` mode](#display-modes), and start `collapsed`.
|
|
249
271
|
|
|
272
|
+
Blume warns about an item it can't render as written: a route that matches no page (the item is left out), a `root` that matches no page (its link would 404), or an item with no route, `href`, `root`, or `items` (left out).
|
|
273
|
+
|
|
250
274
|
## Header actions
|
|
251
275
|
|
|
252
276
|
`navigation.actions` puts plain links in the header, left of the icon buttons, and `navigation.cta` is the one filled button:
|
|
@@ -293,7 +317,7 @@ These come for free from the sidebar tree — no configuration:
|
|
|
293
317
|
|
|
294
318
|
## On this page
|
|
295
319
|
|
|
296
|
-
A right-rail outline is generated automatically from each page's `##` and `###`
|
|
320
|
+
A right-rail outline is generated automatically from each page's headings — `##` and `###` by default — so long pages stay scannable. Set [`toc`](/docs/configuration#table-of-contents) to change the heading range or turn the outline off. On narrower screens, where the right rail is hidden, it collapses into an “On this page” dropdown above the content.
|
|
297
321
|
|
|
298
322
|
## Page actions
|
|
299
323
|
|
|
@@ -301,8 +325,9 @@ Below the table of contents, every page shows a set of quick actions:
|
|
|
301
325
|
|
|
302
326
|
- **Edit on GitHub** — links straight to the source file. Appears once you set [`github`](/docs/configuration) in your config.
|
|
303
327
|
- **Scroll to top** — smoothly returns to the top of long pages.
|
|
304
|
-
- **Give feedback** — opens a prefilled GitHub issue with an optional reaction and note (also requires `github`).
|
|
305
328
|
|
|
306
|
-
Others hand the page to AI tools — **Copy as Markdown** and **Open in chat** — covered in [
|
|
329
|
+
Others hand the page to AI tools — **Copy as Markdown** and **Open in chat** — covered in [Markdown for agents](/docs/discoverability/markdown#copy-as-markdown).
|
|
330
|
+
|
|
331
|
+
Feedback lives at the foot of the page instead: a "Was this page helpful?" yes/no rating that sends a `feedback` analytics event and doesn't need `github` — see [Page feedback](/docs/configuration#page-feedback).
|
|
307
332
|
|
|
308
333
|
With [`export`](/docs/configuration/export) on, an **Export** action also lets readers download the page as a PDF or EPUB.
|