blume 2.0.2 → 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 +65 -0
- package/dist/cli/{chunk-6k4ftwze.js → chunk-1d7ve1dm.js} +1 -1
- package/dist/cli/{chunk-zp79m0ts.js → chunk-2eytanqx.js} +2 -2
- package/dist/cli/{chunk-8g8ytmgx.js → chunk-2hsdwb9n.js} +19 -19
- package/dist/cli/{chunk-8g8ytmgx.js.map → chunk-2hsdwb9n.js.map} +1 -1
- package/dist/cli/{chunk-g698a744.js → chunk-2z928egk.js} +5 -5
- package/dist/cli/{chunk-ppzjqwx2.js → chunk-35d4wj9f.js} +17 -18
- package/dist/cli/{chunk-ppzjqwx2.js.map → chunk-35d4wj9f.js.map} +3 -3
- package/dist/cli/{chunk-mqc662a6.js → chunk-364znk6q.js} +2 -2
- package/dist/cli/{chunk-gs7r695n.js → chunk-3em5wd2y.js} +21 -8
- package/dist/cli/{chunk-gs7r695n.js.map → chunk-3em5wd2y.js.map} +3 -3
- package/dist/cli/{chunk-k7pj68a8.js → chunk-5f86nr5m.js} +15 -15
- package/dist/cli/{chunk-hr8ne106.js → chunk-5m5nmvyq.js} +68 -43
- package/dist/cli/chunk-5m5nmvyq.js.map +13 -0
- package/dist/cli/{chunk-91ws1n6j.js → chunk-5xvm6tfj.js} +14 -14
- package/dist/cli/{chunk-w4bxdvsa.js → chunk-6dsbexzp.js} +14 -14
- package/dist/cli/{chunk-00gs3wqs.js → chunk-8ktnccpt.js} +1 -1
- package/dist/cli/{chunk-j85scx15.js → chunk-9t7a85s3.js} +130 -44
- package/dist/cli/chunk-9t7a85s3.js.map +10 -0
- package/dist/cli/{chunk-bbnwccaz.js → chunk-a58773jm.js} +2 -2
- package/dist/cli/{chunk-nfcyttvj.js → chunk-acanzt5p.js} +9 -9
- package/dist/cli/{chunk-nfcyttvj.js.map → chunk-acanzt5p.js.map} +1 -1
- package/dist/cli/{chunk-wdrt2k2v.js → chunk-akbpwfxc.js} +90 -26
- package/dist/cli/chunk-akbpwfxc.js.map +10 -0
- package/dist/cli/{chunk-sqw4ekg1.js → chunk-b07cmahc.js} +2 -2
- package/dist/cli/{chunk-xh43dwgw.js → chunk-c8chx29p.js} +42 -29
- package/dist/cli/{chunk-xh43dwgw.js.map → chunk-c8chx29p.js.map} +9 -9
- package/dist/cli/{chunk-7mbqtmgb.js → chunk-crgn1q09.js} +21 -12
- 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-4e9b9ra6.js → chunk-ey84smr6.js} +3 -3
- package/dist/cli/{chunk-d1v5rhy0.js → chunk-g4hq16wv.js} +13 -13
- package/dist/cli/{chunk-273ygyr4.js → chunk-ga0pf4aj.js} +7 -7
- package/dist/cli/{chunk-273ygyr4.js.map → chunk-ga0pf4aj.js.map} +3 -3
- package/dist/cli/{chunk-pbg5a4s3.js → chunk-hm3vjy5s.js} +64 -45
- package/dist/cli/chunk-hm3vjy5s.js.map +19 -0
- package/dist/cli/{chunk-5r8g91qn.js → chunk-j85vccga.js} +306 -107
- package/dist/cli/chunk-j85vccga.js.map +36 -0
- package/dist/cli/{chunk-n1yg3tj3.js → chunk-p3v96n38.js} +6 -6
- package/dist/cli/{chunk-n1yg3tj3.js.map → chunk-p3v96n38.js.map} +3 -3
- package/dist/cli/{chunk-7vtckvaw.js → chunk-p73c0m7w.js} +14 -14
- package/dist/cli/{chunk-7vtckvaw.js.map → chunk-p73c0m7w.js.map} +1 -1
- package/dist/cli/{chunk-qkb5a8sa.js → chunk-pehfxfta.js} +3 -3
- package/dist/cli/{chunk-v6ya5kcb.js → chunk-pv29h0wf.js} +1223 -978
- package/dist/cli/{chunk-v6ya5kcb.js.map → chunk-pv29h0wf.js.map} +47 -46
- package/dist/cli/{chunk-6dtt0zfn.js → chunk-q58y5e6a.js} +10 -10
- package/dist/cli/{chunk-6dtt0zfn.js.map → chunk-q58y5e6a.js.map} +3 -3
- package/dist/cli/{chunk-fsmrqk8a.js → chunk-r20tn01b.js} +1 -1
- package/dist/cli/{chunk-bfwp9vp6.js → chunk-r9rcc4w7.js} +7 -7
- package/dist/cli/{chunk-h7k3nq3v.js → chunk-tkacnehg.js} +2 -2
- package/dist/cli/{chunk-h2ez8dzb.js → chunk-tzmab476.js} +4 -4
- package/dist/cli/{chunk-3yce002v.js → chunk-vg9r4eb9.js} +6 -6
- package/dist/cli/{chunk-3yce002v.js.map → chunk-vg9r4eb9.js.map} +4 -4
- package/dist/cli/{chunk-hqp2ajnh.js → chunk-wrr3j9w9.js} +16 -17
- package/dist/cli/{chunk-hqp2ajnh.js.map → chunk-wrr3j9w9.js.map} +7 -7
- package/dist/cli/{chunk-ddndchfr.js → chunk-yfyb25rh.js} +38 -26
- package/dist/cli/chunk-yfyb25rh.js.map +14 -0
- package/dist/cli/index.js +20 -18
- package/dist/cli/index.js.map +3 -3
- 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 +9 -7
- package/dist/types/ai/skills.d.ts +4 -1
- package/dist/types/ai/tar.d.ts +1 -3
- package/dist/types/analytics/index.d.ts +2 -0
- package/dist/types/analytics/one-dollar-stats.d.ts +48 -0
- package/dist/types/analytics/schema.d.ts +14 -0
- package/dist/types/astro/integration.d.ts +3 -2
- package/dist/types/core/base-path.d.ts +21 -7
- package/dist/types/core/config-input.d.ts +9 -7
- package/dist/types/core/directive-diagnostics.d.ts +12 -0
- package/dist/types/core/heading-markers.d.ts +5 -7
- package/dist/types/core/i18n.d.ts +2 -0
- package/dist/types/core/last-modified.d.ts +10 -0
- package/dist/types/core/meta.d.ts +8 -0
- package/dist/types/core/schema.d.ts +7 -0
- package/dist/types/core/sources/lower.d.ts +29 -16
- package/dist/types/core/sources/normalize.d.ts +13 -1
- package/dist/types/core/sources/watch.d.ts +12 -5
- package/dist/types/core/standard-schema.d.ts +5 -0
- package/dist/types/deploy/artifacts.d.ts +6 -4
- package/dist/types/deploy/headers.d.ts +5 -0
- package/dist/types/deploy/platforms/types.d.ts +8 -0
- package/dist/types/deploy/redirects.d.ts +24 -13
- 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/docs/02-deployment.mdx +4 -2
- package/docs/08-faq.mdx +1 -1
- package/docs/advanced/custom-pages.mdx +3 -3
- package/docs/cli/audit.mdx +17 -1
- package/docs/cli/evals.mdx +3 -3
- package/docs/cli/translate.mdx +3 -3
- package/docs/cli/version.mdx +1 -1
- package/docs/configuration/analytics.mdx +20 -1
- package/docs/configuration/customization.mdx +2 -0
- package/docs/configuration/search.mdx +1 -1
- package/docs/content/components.mdx +1 -1
- package/docs/content/frontmatter.mdx +1 -1
- package/docs/content/i18n.mdx +2 -0
- package/docs/content/index.mdx +4 -2
- package/docs/content/islands.mdx +1 -1
- package/docs/content/meta.mdx +3 -1
- package/docs/content/sources.mdx +1 -5
- package/docs/content/syntax.mdx +14 -0
- package/docs/content/versioning.mdx +1 -1
- package/docs/discoverability/agent-discovery.mdx +1 -1
- package/docs/discoverability/index.mdx +2 -1
- package/docs/discoverability/markdown.mdx +2 -2
- package/docs/discoverability/open-graph.mdx +5 -3
- package/docs/discoverability/rss.mdx +1 -1
- package/docs/references/asyncapi.mdx +1 -1
- package/docs/references/graphql.mdx +1 -1
- package/docs/references/openapi.mdx +5 -3
- package/package.json +1 -1
- package/skills/blume-migrate/references/fumadocs.md +1 -1
- package/skills/blume-migrate/references/nextra.md +1 -1
- package/skills/blume-migrate/scripts/mintlify-codemod.mjs +7 -2
- package/src/ai/agent-readability.ts +2 -2
- package/src/ai/ai-catalog.ts +6 -2
- package/src/ai/api/handlers.ts +2 -2
- package/src/ai/api/spec.ts +2 -2
- package/src/ai/api-catalog.ts +6 -2
- package/src/ai/changelog-markdown.ts +2 -2
- package/src/ai/link-headers.ts +14 -5
- package/src/ai/llms.ts +18 -7
- package/src/ai/mcp/discovery.ts +2 -2
- package/src/ai/mcp/query.ts +2 -2
- package/src/ai/mcp/server.ts +2 -2
- package/src/ai/openapi-components.ts +22 -6
- package/src/ai/relative-links.ts +42 -26
- package/src/ai/serializers.ts +2 -1
- package/src/ai/skills.ts +14 -1
- package/src/ai/tar.ts +139 -12
- package/src/analytics/head.ts +4 -0
- package/src/analytics/index.ts +5 -0
- package/src/analytics/one-dollar-stats.ts +86 -0
- package/src/analytics/schema.ts +2 -0
- package/src/astro/generate.ts +1 -1
- 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 +81 -37
- package/src/audit/checks/links.ts +8 -1
- package/src/audit/graph.ts +3 -1
- package/src/audit/run.ts +12 -9
- package/src/audit/snapshot.ts +5 -0
- package/src/cli/args.ts +32 -0
- package/src/cli/commands/audit.ts +4 -1
- package/src/cli/commands/doctor.ts +3 -1
- package/src/cli/commands/eval.ts +19 -11
- package/src/cli/commands/translate.ts +9 -12
- package/src/cli/commands/validate.ts +3 -1
- package/src/cli/dev-lock.ts +157 -37
- package/src/cli/report-format.ts +11 -6
- package/src/components/colors.ts +19 -0
- package/src/components/content/Badge.astro +5 -3
- package/src/components/content/Component.astro +2 -2
- package/src/components/content/Tab.astro +0 -1
- package/src/components/content/Tabs.astro +4 -0
- package/src/components/content/badge-color.ts +5 -2
- package/src/components/content/base-href.ts +13 -36
- package/src/components/islands/assistant.tsx +21 -4
- package/src/components/islands/base-path.ts +47 -10
- package/src/components/islands/hooks.ts +35 -19
- package/src/components/islands/webmcp.ts +4 -2
- package/src/components/layout/Breadcrumbs.astro +5 -2
- package/src/components/layout/DiscoveryLinks.astro +9 -5
- package/src/components/layout/Header.astro +2 -2
- package/src/components/layout/LanguageSwitcher.astro +2 -2
- package/src/components/layout/NavSelector.astro +2 -2
- package/src/components/layout/NavTabMenu.astro +3 -3
- package/src/components/layout/NavTree.astro +16 -6
- package/src/components/layout/PageActions.astro +4 -3
- package/src/components/layout/PageLayout.astro +7 -6
- package/src/components/layout/Pagination.astro +3 -3
- package/src/components/layout/RootLayout.astro +5 -5
- package/src/components/layout/Search.astro +33 -13
- package/src/components/layout/VersionBanner.astro +2 -2
- package/src/components/layout/analytics-client.ts +12 -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/Operation.astro +2 -0
- package/src/components/openapi/Playground.astro +4 -4
- package/src/components/openapi/RequestPanel.astro +5 -2
- package/src/components/openapi/SchemaTable.astro +7 -0
- package/src/components/openapi/async.ts +38 -6
- package/src/components/openapi/helpers.ts +19 -9
- package/src/components/openapi/message-composer.ts +6 -1
- package/src/components/openapi/message.ts +17 -2
- package/src/components/openapi/operation-model.ts +81 -11
- package/src/components/openapi/panel.ts +4 -2
- package/src/components/openapi/param-style.ts +181 -0
- package/src/components/openapi/playground-client.ts +73 -16
- package/src/components/openapi/request.ts +190 -26
- package/src/components/openapi/schema-tree.ts +30 -24
- package/src/components/openapi/snippets.ts +85 -6
- package/src/components/openapi/ws-client.ts +18 -2
- package/src/core/base-path.ts +62 -16
- package/src/core/config-input.ts +9 -7
- package/src/core/diagnostics.ts +2 -0
- package/src/core/directive-diagnostics.ts +99 -0
- package/src/core/frontmatter.ts +21 -18
- package/src/core/heading-markers.ts +5 -18
- package/src/core/i18n.ts +31 -3
- package/src/core/last-modified.ts +25 -3
- package/src/core/locale-links.ts +5 -1
- package/src/core/meta.ts +33 -19
- package/src/core/navigation.ts +28 -8
- package/src/core/project-graph.ts +27 -5
- package/src/core/schema.ts +24 -4
- package/src/core/sources/contentful-rich-text.ts +27 -20
- package/src/core/sources/filesystem.ts +20 -2
- package/src/core/sources/github-releases.ts +25 -6
- package/src/core/sources/lexical.ts +23 -18
- package/src/core/sources/lower.ts +201 -34
- package/src/core/sources/mdx-remote.ts +51 -16
- package/src/core/sources/normalize.ts +325 -90
- package/src/core/sources/notion.ts +52 -25
- package/src/core/sources/obsidian.ts +23 -6
- package/src/core/sources/portable-text.ts +38 -21
- package/src/core/sources/strapi-blocks.ts +20 -16
- package/src/core/sources/watch.ts +20 -7
- package/src/core/standard-schema.ts +10 -6
- package/src/core/version-cut.ts +52 -15
- package/src/deploy/artifacts.ts +27 -6
- package/src/deploy/cloudflare-negotiation.ts +4 -12
- package/src/deploy/headers.ts +8 -4
- package/src/deploy/node-headers.ts +1 -1
- package/src/deploy/platforms/cloudflare.ts +12 -3
- package/src/deploy/platforms/netlify.ts +1 -0
- package/src/deploy/platforms/node.ts +1 -0
- package/src/deploy/platforms/static.ts +1 -0
- package/src/deploy/platforms/types.ts +8 -0
- package/src/deploy/platforms/vercel.ts +1 -0
- package/src/deploy/redirects.ts +54 -18
- package/src/deploy/robots.ts +2 -2
- package/src/deploy/rss.ts +4 -3
- package/src/deploy/sitemap.ts +7 -5
- package/src/markdown/base-links.ts +34 -36
- package/src/markdown/directives.ts +242 -36
- package/src/markdown/features.ts +17 -0
- package/src/markdown/index.ts +7 -6
- package/src/markdown/mdast.ts +5 -2
- package/src/markdown/relative-links.ts +12 -4
- package/src/og/card.ts +129 -5
- package/src/og/derive.ts +41 -31
- package/src/og/index.ts +1 -0
- package/src/openapi/asyncapi.ts +4 -2
- package/src/openapi/model.ts +22 -14
- package/src/openapi/proxy.ts +63 -10
- package/src/openapi/render-mdx.ts +41 -2
- package/src/registry/eject.ts +181 -24
- package/src/search/adapters/version-scope.ts +30 -0
- package/src/search/documents.ts +67 -26
- package/src/search/popular.ts +2 -1
- package/src/seo/jsonld.ts +7 -3
- package/src/translate/meta.ts +68 -24
- package/src/translate/run.ts +3 -3
- package/src/translate/validate.ts +4 -1
- package/src/translate/work-list.ts +56 -17
- package/dist/cli/chunk-5r8g91qn.js.map +0 -34
- package/dist/cli/chunk-7mbqtmgb.js.map +0 -10
- package/dist/cli/chunk-ddndchfr.js.map +0 -14
- package/dist/cli/chunk-esh98wmb.js +0 -23
- package/dist/cli/chunk-esh98wmb.js.map +0 -10
- package/dist/cli/chunk-hr8ne106.js.map +0 -13
- package/dist/cli/chunk-j85scx15.js.map +0 -10
- package/dist/cli/chunk-pbg5a4s3.js.map +0 -19
- package/dist/cli/chunk-wdrt2k2v.js.map +0 -10
- /package/dist/cli/{chunk-6k4ftwze.js.map → chunk-1d7ve1dm.js.map} +0 -0
- /package/dist/cli/{chunk-zp79m0ts.js.map → chunk-2eytanqx.js.map} +0 -0
- /package/dist/cli/{chunk-g698a744.js.map → chunk-2z928egk.js.map} +0 -0
- /package/dist/cli/{chunk-mqc662a6.js.map → chunk-364znk6q.js.map} +0 -0
- /package/dist/cli/{chunk-k7pj68a8.js.map → chunk-5f86nr5m.js.map} +0 -0
- /package/dist/cli/{chunk-91ws1n6j.js.map → chunk-5xvm6tfj.js.map} +0 -0
- /package/dist/cli/{chunk-w4bxdvsa.js.map → chunk-6dsbexzp.js.map} +0 -0
- /package/dist/cli/{chunk-00gs3wqs.js.map → chunk-8ktnccpt.js.map} +0 -0
- /package/dist/cli/{chunk-bbnwccaz.js.map → chunk-a58773jm.js.map} +0 -0
- /package/dist/cli/{chunk-sqw4ekg1.js.map → chunk-b07cmahc.js.map} +0 -0
- /package/dist/cli/{chunk-4e9b9ra6.js.map → chunk-ey84smr6.js.map} +0 -0
- /package/dist/cli/{chunk-d1v5rhy0.js.map → chunk-g4hq16wv.js.map} +0 -0
- /package/dist/cli/{chunk-qkb5a8sa.js.map → chunk-pehfxfta.js.map} +0 -0
- /package/dist/cli/{chunk-fsmrqk8a.js.map → chunk-r20tn01b.js.map} +0 -0
- /package/dist/cli/{chunk-bfwp9vp6.js.map → chunk-r9rcc4w7.js.map} +0 -0
- /package/dist/cli/{chunk-h7k3nq3v.js.map → chunk-tkacnehg.js.map} +0 -0
- /package/dist/cli/{chunk-h2ez8dzb.js.map → chunk-tzmab476.js.map} +0 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal structural types and node builders for the (alpha) Satteri MDAST
|
|
3
|
+
* plugin API. We model only what Blume's plugins read and construct; the full
|
|
4
|
+
* types live in `satteri`, a transitive dependency. Plugins are bridged to
|
|
5
|
+
* Satteri's real `MdastPlugin` type at a single boundary in `index.ts`.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* A property value on an MDAST node: primitives, nested nodes, and lists of
|
|
9
|
+
* either. Covers everything Blume's plugins read or build (positions, data
|
|
10
|
+
* flags, attribute lists) without admitting functions or class instances.
|
|
11
|
+
*/
|
|
12
|
+
export type MdastValue = string | number | boolean | null | undefined | MdastValue[] | {
|
|
13
|
+
[key: string]: MdastValue;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* The visitor context Blume's plugins use to mutate the tree. A list of
|
|
17
|
+
* nodes takes the replaced node's place in order.
|
|
18
|
+
*/
|
|
19
|
+
export interface MdastVisitorContext {
|
|
20
|
+
replaceNode: (node: MdastNode, replacement: MdastNode | MdastNode[]) => void;
|
|
21
|
+
}
|
|
22
|
+
/** Any MDAST node, keyed loosely since we build a small subset by hand. */
|
|
23
|
+
export interface MdastNode {
|
|
24
|
+
type: string;
|
|
25
|
+
[key: string]: MdastValue;
|
|
26
|
+
}
|
|
27
|
+
/** Build an MDX JSX attribute. A `null` value renders as a boolean attribute. */
|
|
28
|
+
export declare const jsxAttribute: (name: string, value?: string | null) => {
|
|
29
|
+
name: string;
|
|
30
|
+
type: string;
|
|
31
|
+
value: string | null;
|
|
32
|
+
};
|
|
33
|
+
type JsxAttribute = ReturnType<typeof jsxAttribute>;
|
|
34
|
+
/** Build a block-level MDX JSX element (`<Name>…</Name>`). */
|
|
35
|
+
export declare const jsxFlowElement: (name: string, attributes: JsxAttribute[], children: MdastValue[]) => {
|
|
36
|
+
attributes: {
|
|
37
|
+
name: string;
|
|
38
|
+
type: string;
|
|
39
|
+
value: string | null;
|
|
40
|
+
}[];
|
|
41
|
+
children: MdastValue[];
|
|
42
|
+
name: string;
|
|
43
|
+
type: string;
|
|
44
|
+
};
|
|
45
|
+
/** Build an inline MDX JSX element (phrasing context). */
|
|
46
|
+
export declare const jsxTextElement: (name: string, attributes: JsxAttribute[], children?: MdastValue[]) => {
|
|
47
|
+
attributes: {
|
|
48
|
+
name: string;
|
|
49
|
+
type: string;
|
|
50
|
+
value: string | null;
|
|
51
|
+
}[];
|
|
52
|
+
children: MdastValue[];
|
|
53
|
+
name: string;
|
|
54
|
+
type: string;
|
|
55
|
+
};
|
|
56
|
+
/** Build a fenced code block node, optionally with a fence-meta string. */
|
|
57
|
+
export declare const codeBlock: (lang: string, value: string, meta?: string | null) => {
|
|
58
|
+
lang: string;
|
|
59
|
+
meta: string | null;
|
|
60
|
+
type: string;
|
|
61
|
+
value: string;
|
|
62
|
+
};
|
|
63
|
+
export {};
|
|
@@ -34,7 +34,8 @@ export interface AsyncApiChannelObject {
|
|
|
34
34
|
messages?: Record<string, AsyncApiRefLike>;
|
|
35
35
|
parameters?: Record<string, AsyncApiRefLike>;
|
|
36
36
|
servers?: AsyncApiRefLike[];
|
|
37
|
-
|
|
37
|
+
/** Protocol-keyed binding objects, or a `$ref` to a components entry. */
|
|
38
|
+
bindings?: Record<string, AsyncApiSpecValue>;
|
|
38
39
|
[key: string]: AsyncApiSpecValue;
|
|
39
40
|
}
|
|
40
41
|
/** A permissive view of an AsyncAPI 3.x operation — only the fields we render. */
|
|
@@ -51,7 +52,8 @@ export interface AsyncApiOperationObject {
|
|
|
51
52
|
}[];
|
|
52
53
|
security?: AsyncApiRefLike[];
|
|
53
54
|
messages?: AsyncApiRefLike[];
|
|
54
|
-
|
|
55
|
+
/** Protocol-keyed binding objects, or a `$ref` to a components entry. */
|
|
56
|
+
bindings?: Record<string, AsyncApiSpecValue>;
|
|
55
57
|
[key: string]: AsyncApiSpecValue;
|
|
56
58
|
}
|
|
57
59
|
/** A permissive view of an AsyncAPI 3.x server object. */
|
package/docs/02-deployment.mdx
CHANGED
|
@@ -67,6 +67,8 @@ deployment: {
|
|
|
67
67
|
|
|
68
68
|
`base` (and `site`) are options of every host adapter too: `vercel({ base: "/docs" })`.
|
|
69
69
|
|
|
70
|
+
Every page keeps its own path under the base, even in a content folder that shares the base's name: with `base: "/docs"`, `docs/setup.md` is served at `/docs/docs/setup`, and its canonical URL, sidebar link, and `llms.txt` entry point there. A root-relative link you write that already starts with the base is taken to include it and left as written, so link to that page with a relative link (`./docs/setup`) or its full path (`/docs/docs/setup`).
|
|
71
|
+
|
|
70
72
|
## Mount the docs under a path
|
|
71
73
|
|
|
72
74
|
`basePath` mounts every generated route under a segment (`/docs/getting-started`) while leaving the sidebar untouched — the top level is your sections, not a wrapper group. Use it when the docs live at `/docs/*` but the site root stays yours (like Docusaurus `routeBasePath` or Fumadocs `baseUrl`).
|
|
@@ -75,7 +77,7 @@ deployment: {
|
|
|
75
77
|
basePath: "/docs",
|
|
76
78
|
```
|
|
77
79
|
|
|
78
|
-
Write links as if mounted at root (`/getting-started`); Blume rewrites them, along with redirects, the sitemap, canonical URLs, Open Graph images, `llms.txt`, and the search index. Public assets (images, files under `public/`) stay at the site root.
|
|
80
|
+
Write links as if mounted at root (`/getting-started`); Blume rewrites them, along with redirects, the sitemap, canonical URLs, Open Graph images, `llms.txt`, and the search index. Public assets (images, files under `public/`) stay at the site root, or under [`base`](#subpath-deploys) when you set one.
|
|
79
81
|
|
|
80
82
|
This is a distinct concept from the two paths above:
|
|
81
83
|
|
|
@@ -154,7 +156,7 @@ Two hosts need more than the file:
|
|
|
154
156
|
:::
|
|
155
157
|
|
|
156
158
|
:::note
|
|
157
|
-
Write both `from` and `to` as if mounted at root, starting with `/` (`to` can also be a full `https://` URL) — under [`base`](#subpath-deploys) and [`basePath`](#mount-the-docs-under-a-path) alike, Blume rewrites both sides for you, so a redirect lands inside the base. A base you've already written into `to` by hand is preserved rather than doubled.
|
|
159
|
+
Write both `from` and `to` as if mounted at root, starting with `/` (`to` can also be a full `https://` URL) — under [`base`](#subpath-deploys) and [`basePath`](#mount-the-docs-under-a-path) alike, Blume rewrites both sides for you, so a redirect lands inside the base. A `to` that names a file in `public/` (`/files/guide.pdf`) gains `base` but not `basePath`, since that's where the file is served. A base you've already written into `to` by hand is preserved rather than doubled.
|
|
158
160
|
:::
|
|
159
161
|
|
|
160
162
|
## Content types
|
package/docs/08-faq.mdx
CHANGED
|
@@ -45,7 +45,7 @@ No. A folder of Markdown is a complete site — navigation, search, and theming
|
|
|
45
45
|
|
|
46
46
|
## Can I use React components and MDX?
|
|
47
47
|
|
|
48
|
-
Yes. Any page can be `.md` or `.mdx`, and MDX lets you drop in the [built-in components](/docs/content/components) with no imports. You can also add your own `.tsx`/`.jsx` [islands](/docs/content/islands)
|
|
48
|
+
Yes. Any page can be `.md` or `.mdx`, and MDX lets you drop in the [built-in components](/docs/content/components) with no imports. You can also add your own `.tsx`/`.jsx` [islands](/docs/content/islands). Blume switches React on only when your project uses it — any `.tsx` or `.jsx` file in the project (your islands included), a React [`<Component>`](/docs/content/components#component) example, a [component override](/docs/configuration/customization), or the [assistant](/docs/configuration/assistant) — so a site with none of those ships no framework JavaScript.
|
|
49
49
|
|
|
50
50
|
## Where can I deploy it?
|
|
51
51
|
|
|
@@ -102,10 +102,10 @@ The module exposes:
|
|
|
102
102
|
description: "Generated RSS feeds: { href, title }.",
|
|
103
103
|
},
|
|
104
104
|
fontCssVars: {
|
|
105
|
-
type: "
|
|
105
|
+
type: "FontHead[]",
|
|
106
106
|
required: true,
|
|
107
107
|
description:
|
|
108
|
-
"
|
|
108
|
+
"The configured fonts for Astro's <Font> component in the head, one per family: { cssVariable, preloadWeights, preloadSubsets? }.",
|
|
109
109
|
},
|
|
110
110
|
ui: {
|
|
111
111
|
type: "UIStrings",
|
|
@@ -290,7 +290,7 @@ Blume ships a default **not found** page out of the box: a centered "404" messag
|
|
|
290
290
|
|
|
291
291
|
The page also has a Markdown twin at `/404.md` and a JSON twin at `/404.json` ([RFC 9457](https://www.rfc-editor.org/rfc/rfc9457) problem details) with the same recovery links (absolute URLs once [`deployment.site`](/docs/deployment) is set), plus the [`openapi.json`](/docs/discoverability/json-api) description when the JSON API is on. On a [Vercel or Cloudflare server build](/docs/deployment#server-rendering), a request for a missing page that sends [`Accept: text/markdown`](/docs/discoverability/markdown#content-negotiation) gets the Markdown body with the `404` status instead of the HTML shell, and one that sends `Accept: application/json` gets the problem document — so an agent never has to parse a page of chrome to learn where to go next. On Vercel the same goes for a `.md` or `.json` URL no file backs.
|
|
292
292
|
|
|
293
|
-
To replace it with your own, add a `pages/404.astro`. It owns the `/404` route the same way `pages/changelog.astro` takes over the changelog — your page wins and the default is dropped. Build it like any other custom page, in `PageLayout` or `RootLayout`:
|
|
293
|
+
To replace it with your own, add a `pages/404.astro`. It owns the `/404` route the same way `pages/changelog.astro` takes over the changelog — your page wins and the default is dropped, along with its `/404.md` and `/404.json` twins. Build it like any other custom page, in `PageLayout` or `RootLayout`:
|
|
294
294
|
|
|
295
295
|
```astro pages/404.astro lineNumbers
|
|
296
296
|
---
|
package/docs/cli/audit.mdx
CHANGED
|
@@ -83,7 +83,23 @@ Anything the audit did not run is reported as skipped rather than silently passi
|
|
|
83
83
|
|
|
84
84
|
## Check catalog
|
|
85
85
|
|
|
86
|
-
Every check `blume audit` can report, grouped by category, with its default severity, the tier it runs in, and the fix the report suggests. `--only` and `--skip` accept these ids (without the `BLUME_AUDIT_` prefix is fine too) or the category
|
|
86
|
+
Every check `blume audit` can report, grouped by category, with its default severity, the tier it runs in, and the fix the report suggests. `--only` and `--skip` accept these ids (without the `BLUME_AUDIT_` prefix is fine too) or a category's key. The key isn't always the category's heading, so use this table: `blume audit --only i18n`, not `--only Internationalization`.
|
|
87
|
+
|
|
88
|
+
| Category | Key |
|
|
89
|
+
| -------------------- | ----------------- |
|
|
90
|
+
| Content | `content` |
|
|
91
|
+
| Duplicates | `duplicates` |
|
|
92
|
+
| Indexability | `indexability` |
|
|
93
|
+
| Links | `links` |
|
|
94
|
+
| Redirects | `redirects` |
|
|
95
|
+
| Social cards | `social` |
|
|
96
|
+
| Internationalization | `i18n` |
|
|
97
|
+
| Assets | `assets` |
|
|
98
|
+
| Sitemap | `sitemap` |
|
|
99
|
+
| robots.txt | `robots` |
|
|
100
|
+
| AI discoverability | `ai` |
|
|
101
|
+
| Structured data | `structured-data` |
|
|
102
|
+
| Live deployment | `network` |
|
|
87
103
|
|
|
88
104
|
### Content
|
|
89
105
|
|
package/docs/cli/evals.mdx
CHANGED
|
@@ -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, with `severity: warning` misses counted as passing. 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/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
|
|
|
@@ -77,5 +77,5 @@ The JSON report carries the same `diagnostics` + `summary` shape as `blume valid
|
|
|
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
|
|
|
@@ -47,6 +47,7 @@ Every identifier below — a project key, a measurement ID, a site token — is
|
|
|
47
47
|
| `hotjar()` | [Hotjar](#hotjar) | `id` |
|
|
48
48
|
| `logrocket()` | [LogRocket](#logrocket) | `id` |
|
|
49
49
|
| `mixpanel()` | [Mixpanel](#mixpanel) | `token` |
|
|
50
|
+
| `oneDollarStats()` | [OneDollarStats](#onedollarstats) | — |
|
|
50
51
|
| `pirsch()` | [Pirsch](#pirsch) | `code` |
|
|
51
52
|
| `plausible()` | [Plausible](#plausible) | `domain` |
|
|
52
53
|
| `posthog()` | [PostHog](#posthog) | `key` |
|
|
@@ -191,6 +192,22 @@ analytics: [
|
|
|
191
192
|
|
|
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.
|
|
193
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
|
+
|
|
194
211
|
## Mixpanel
|
|
195
212
|
|
|
196
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.
|
|
@@ -391,6 +408,8 @@ analytics: [
|
|
|
391
408
|
| `mixpanel()` | `token` | — | Mixpanel project token. Required. |
|
|
392
409
|
| `mixpanel()` | `region` | `us` | Data residency region: `us`, `eu`, or `in`. |
|
|
393
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). |
|
|
394
413
|
| `pirsch()` | `code` | — | Pirsch identification code. Required. |
|
|
395
414
|
| `pirsch()` | anything else | — | Rendered as a `data-` attribute on the tag. |
|
|
396
415
|
| `plausible()` | `domain` | — | The site's domain in Plausible. Required. |
|
|
@@ -410,4 +429,4 @@ analytics: [
|
|
|
410
429
|
|
|
411
430
|
## Custom events
|
|
412
431
|
|
|
413
|
-
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, 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).
|
|
@@ -191,4 +191,6 @@ From then on, run the app through its own scripts (`npm run dev`, `npm run build
|
|
|
191
191
|
|
|
192
192
|
### What eject keeps
|
|
193
193
|
|
|
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
|
+
|
|
194
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.
|
|
@@ -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
|
|
|
@@ -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
|
|
|
@@ -26,7 +26,7 @@ Every page accepts the following frontmatter. All fields are optional.
|
|
|
26
26
|
slug: {
|
|
27
27
|
type: "string",
|
|
28
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.",
|
|
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
30
|
},
|
|
31
31
|
draft: {
|
|
32
32
|
type: "boolean",
|
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
|
package/docs/content/index.mdx
CHANGED
|
@@ -29,6 +29,8 @@ 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
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:
|
|
@@ -50,7 +52,7 @@ Wrap a folder name in parentheses to group its pages in the sidebar **without**
|
|
|
50
52
|
docs/(internal)/security.mdx -> /security
|
|
51
53
|
```
|
|
52
54
|
|
|
53
|
-
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)`.
|
|
54
56
|
|
|
55
57
|
## Drafts
|
|
56
58
|
|
|
@@ -84,7 +86,7 @@ The type is independent of where the file lives, but by convention blog posts go
|
|
|
84
86
|
|
|
85
87
|
## Feeds
|
|
86
88
|
|
|
87
|
-
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`:
|
|
88
90
|
|
|
89
91
|
| Type | Feed |
|
|
90
92
|
| ----------- | -------------------- |
|
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,7 +23,7 @@ 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.
|
|
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
27
|
|
|
28
28
|
## Fields
|
|
29
29
|
|
|
@@ -38,6 +38,8 @@ Blume only reads `meta.ts` files from folders your content covers: one under a f
|
|
|
38
38
|
|
|
39
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
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.
|
|
42
|
+
|
|
41
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).
|
|
42
44
|
|
|
43
45
|
## Computed meta
|
package/docs/content/sources.mdx
CHANGED
|
@@ -81,13 +81,9 @@ Frontmatter keeps what Blume's [page schema](/docs/content/frontmatter) accepts
|
|
|
81
81
|
|
|
82
82
|
Locale directories and version snapshots inside the vault are read the same way the filesystem source reads them: `fr/Note.md` publishes under `/fr/` with [i18n](/docs/content/i18n) configured, `v1.0/Note.md` under `/v1.0/` with [versions](/docs/content/versioning), and wikilinks to those notes point at the route each one publishes.
|
|
83
83
|
|
|
84
|
-
:::note
|
|
85
|
-
A heading that itself contains a link gets its manifest anchor from the heading's Markdown and its rendered `id` from its text content. The two differ for that heading, so a wikilink to it may land on the page rather than on the section.
|
|
86
|
-
:::
|
|
87
|
-
|
|
88
84
|
A link to an `index` note lands on its folder's route rather than a phantom `/index`. **An unresolved wikilink degrades to plain text with a build warning instead of failing the build**, so a vault mid-refactor still publishes. Single-line `%%comments%%` are stripped, a wikilink inside an HTML comment (`<!-- [[Draft]] -->`) is left alone since Obsidian hides it too, and a note with no `title` in its frontmatter is titled by its filename — the same rule Obsidian itself applies. An `index` note is the one exception: it names a route rather than a note, so its title falls through to Blume's usual derivation (first heading, then the humanized segment). Fenced, indented, and inline code passes through verbatim, so a note documenting the syntax survives.
|
|
89
85
|
|
|
90
|
-
Dot-folders are skipped, including Obsidian's own `.obsidian` config directory and `.trash` — which the dev watcher also ignores, so moving a pane in the app or deleting a note to the trash doesn't rebuild your site. Editing a note does. The directories no content scan reads (`node_modules`, `dist`, `.git`, …) are skipped too, so a vault rooted at the project itself doesn't publish dependency READMEs. Symlinks inside the vault are followed, the way the filesystem source follows them, so a shared folder linked into the vault publishes with it. A vault that sits inside the filesystem source's root must be excluded from it (`filesystem({ root: "docs", exclude: ["vault/**"] })`); [`blume version <id>`](/docs/cli/version) then leaves it out of the snapshot, since the vault keeps publishing its own notes as current.
|
|
86
|
+
Dot-folders are skipped, including Obsidian's own `.obsidian` config directory and `.trash` — which the dev watcher also ignores, so moving a pane in the app or deleting a note to the trash doesn't rebuild your site. Editing a note does. The directories no content scan reads (`node_modules`, `dist`, `.git`, …) are skipped too, so a vault rooted at the project itself doesn't publish dependency READMEs. A note with `#` or `?` in its path is left out with an error, the way a [content file](/docs/content#files-and-routes) is: Astro can't load its copy, so rename it. Symlinks inside the vault are followed, the way the filesystem source follows them, so a shared folder linked into the vault publishes with it. A vault that sits inside the filesystem source's root must be excluded from it (`filesystem({ root: "docs", exclude: ["**/_*", "**/.*", "vault/**"] })` — an `exclude` replaces the default `["**/_*", "**/.*"]` rather than adding to it, so keep those two to leave `_`-prefixed partials and dot-files unpublished); [`blume version <id>`](/docs/cli/version) then leaves it out of the snapshot, since the vault keeps publishing its own notes as current.
|
|
91
87
|
|
|
92
88
|
Not yet lowered: callouts (`> [!note]`) render as plain blockquotes, embeds (`![[image.png]]`) pass through untouched, multi-line `%%comments%%` are left in place, and there is no backlink graph.
|
|
93
89
|
|
package/docs/content/syntax.mdx
CHANGED
|
@@ -609,6 +609,20 @@ The core theme ships no client framework JS.
|
|
|
609
609
|
|
|
610
610
|
The names `caution`, `error`, `important`, and `warn` are accepted as aliases for `warning`, `danger`, `note`, and `warning` respectively.
|
|
611
611
|
|
|
612
|
+
Any other name isn't a callout. Its content still renders — between its `:::` lines, which stay on the page as written — so a `:::details` carried over from another docs tool, or a typo like `:::warnig`, never hides what's inside it. `blume dev`, `blume build`, and `blume check` warn about it as `BLUME_UNKNOWN_DIRECTIVE`, naming the callout types above.
|
|
613
|
+
|
|
614
|
+
To put a callout inside another, give the outer one a longer fence:
|
|
615
|
+
|
|
616
|
+
```md
|
|
617
|
+
::::note
|
|
618
|
+
Blume regenerates `.blume/` on every run.
|
|
619
|
+
|
|
620
|
+
:::tip
|
|
621
|
+
Commit `blume.config.ts`, not `.blume/`.
|
|
622
|
+
:::
|
|
623
|
+
::::
|
|
624
|
+
```
|
|
625
|
+
|
|
612
626
|
## Math
|
|
613
627
|
|
|
614
628
|
Render LaTeX with KaTeX as centered blocks — useful for math-heavy or scientific docs. Wrap a formula in `$$…$$`:
|
|
@@ -81,7 +81,7 @@ The sitemap follows suit: archived pages whose canonical points at a live equiva
|
|
|
81
81
|
|
|
82
82
|
## Search
|
|
83
83
|
|
|
84
|
-
The search dialog scopes results to the version being viewed, with an "All versions" toggle (remembered per reader) beside the language one. Cross-version hits name their version on the result row. Orama (the default), FlexSearch, Algolia, and Typesense all honor the scoping — hosted records carry a `version` facet, with the current docs uploaded as `"current"
|
|
84
|
+
The search dialog scopes results to the version being viewed, with an "All versions" toggle (remembered per reader) beside the language one. Cross-version hits name their version on the result row. Orama (the default), FlexSearch, Algolia, and Typesense all 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.
|
|
85
85
|
|
|
86
86
|
## Agents
|
|
87
87
|
|
|
@@ -62,7 +62,7 @@ Link: </.well-known/api-catalog>; rel="api-catalog"; type="application/linkset+j
|
|
|
62
62
|
</index.md>; rel="alternate"; type="text/markdown"
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
-
Each entry appears only when its feature is on. The `alternate` link points at the homepage's Markdown mirror — the page's own [raw Markdown](/docs/discoverability/markdown) when the home route is a content page, or the synthesized `llms.txt` fallback when it's a landing page. The `service-desc` link ([RFC 8631](https://www.rfc-editor.org/rfc/rfc8631)) points at the [JSON API](/docs/discoverability/json-api)'s OpenAPI description, `api-catalog` at the [generated API catalog](#api-catalog), and `ai-catalog` at the [AI catalog](#ai-catalog). The header rides on every surface Blume controls: the dev server (check it with `curl -I localhost:4321`)
|
|
65
|
+
Each entry appears only when its feature is on. The `alternate` link points at the homepage's Markdown mirror — the page's own [raw Markdown](/docs/discoverability/markdown) when the home route is a content page, or the synthesized `llms.txt` fallback when it's a landing page. The `service-desc` link ([RFC 8631](https://www.rfc-editor.org/rfc/rfc8631)) points at the [JSON API](/docs/discoverability/json-api)'s OpenAPI description, `api-catalog` at the [generated API catalog](#api-catalog), and `ai-catalog` at the [AI catalog](#ai-catalog). The header rides on every surface Blume controls: static builds via the emitted `_headers` file (Netlify and Cloudflare), Vercel server builds via the deploy's routing rules, and the dev server (check it with `curl -I localhost:4321`). The dev server's header lists only what it serves — the `service-desc` and `alternate` links — because `blume build` writes the catalogs, `agent-readability.json`, and `llms.txt` into the build output.
|
|
66
66
|
|
|
67
67
|
Not every agent enters through the root, though — one following a search result or a shared link lands on a deep page and never sees the homepage header. So every rendered page also carries the same discovery links in its HTML `<head>`, using the same IANA-registered relations:
|
|
68
68
|
|
|
@@ -37,7 +37,8 @@ Most of this is sharper with an absolute site URL — set [`deployment.site`](/d
|
|
|
37
37
|
| Raw Markdown mirrors, content negotiation, Copy as Markdown, Open in chat | `/<route>.md` | on | [Markdown for agents](/docs/discoverability/markdown) |
|
|
38
38
|
| JSON API and its OpenAPI description | `/api/docs/…`, `/openapi.json` | on | [JSON API](/docs/discoverability/json-api) |
|
|
39
39
|
| MCP server | `/mcp` | opt-in, server output | [MCP server](/docs/discoverability/mcp) |
|
|
40
|
-
| `agent-readability.json`, `Link` headers, API catalog, AI catalog (ARD), WebMCP
|
|
40
|
+
| `agent-readability.json`, `Link` headers, API catalog, AI catalog (ARD), WebMCP | site root, `/.well-known/…` | on | [Agent discovery](/docs/discoverability/agent-discovery) |
|
|
41
|
+
| Agent skills, Web Bot Auth keys | `/.well-known/…` | opt-in | [Agent discovery](/docs/discoverability/agent-discovery#skills-discovery) |
|
|
41
42
|
|
|
42
43
|
Every generated file yields to one you ship yourself: drop a `robots.txt`, `sitemap.xml`, `llms.txt`, `openapi.json`, or `agent-readability.json` in `public/` and Blume serves yours in its place.
|
|
43
44
|
|
|
@@ -19,13 +19,13 @@ Nested routes work the same way (`/content/syntax.md`), and the home page is ser
|
|
|
19
19
|
|
|
20
20
|
The `.md` variant _downlevels_ components to plain Markdown for consumers that can't interpret JSX: `<TypeTable>` becomes a Markdown table, `<Callout>` a labeled blockquote, `<Steps>` an ordered list, `<Tabs>` bold-labeled sections, `<Card>` its title as a link over its body (and `<CardGroup>` the cards it holds), `<Accordion>` bold questions over their answers, `<FileTree>` its list, `<CodeGroup>` its titled code blocks, `<YouTube>` a link, and every other built-in component — Columns, Frame, Expandable, Badge, Tooltip, and the rest — its readable content. `<AutoTypeTable>`, which needs the type checker, stays as written, as do a `<Diff>` that reads its sides from files (`src`, or `before` and `after`) and a `<GithubInfo>` without `owner` and `repo`. The components a generated [API reference](/docs/references/openapi) page is made of downlevel too: `<Operation>` becomes the endpoint in its spec's own notation (`GET /pets/{id}`, `SEND user/signup`, `query pets`) with a deprecation marker, `<ApiTagOperations>` a list of those endpoints linked to their pages with their summaries, and `<ApiOverview>` the API's version and base URLs — so an agent reading a reference page knows what to call, and site search matches an endpoint's path. Props are read as literal data and never executed — strings, numbers, booleans, arrays, objects, and template strings, plus references to the page's `frontmatter`, so a prop like `title={frontmatter.status}` resolves to the same value the rendered page shows. Anything that can't be converted faithfully — a custom component, or a prop computed by a function call or from an import — is left as-is, and component markup inside code, fenced or inline, is never touched. The same conversion applies to [`llms-full.txt`](/docs/discoverability/llms-txt) and the [MCP server](/docs/discoverability/mcp)'s `get_page` tool, so every agent-facing surface reads clean Markdown.
|
|
21
21
|
|
|
22
|
-
When you want the MDX itself, use the `.mdx` variant: its components stay as written, and the rest is prepared for an agent reading it by URL, as in the `.md` variant. [Includes](/docs/content/includes) are spliced in, [`<Visibility>`](/docs/content/components#visibility) resolves for agents (`for="web"` content is removed, `for="agents"` content kept), relative images point at their served URLs, relative page links point at the routes they mean, and root-relative links (`/guides/install`) gain the site's `deployment.base` and `basePath` and, on a translated page, move into the page's locale, the way the rendered page's links do.
|
|
22
|
+
When you want the MDX itself, use the `.mdx` variant: its components stay as written, and the rest is prepared for an agent reading it by URL, as in the `.md` variant. [Includes](/docs/content/includes) are spliced in, [`<Visibility>`](/docs/content/components#visibility) resolves for agents (`for="web"` content is removed, `for="agents"` content kept), relative images point at their served URLs, relative page links point at the routes they mean, and root-relative links (`/guides/install`) gain the site's `deployment.base` and `basePath` and, on a translated page, move into the page's locale, the way the rendered page's links do. Root-relative images and links to files in `public/` (`/spec.pdf`) gain `deployment.base` alone, since that's where those files are served.
|
|
23
23
|
|
|
24
24
|
### Content negotiation
|
|
25
25
|
|
|
26
26
|
Agents don't need to know the `.md` convention: requesting a page's own URL with an [`Accept: text/markdown`](https://acceptmarkdown.com) header serves the Markdown variant at the same address, with `Vary: Accept` so caches keep the two apart. The dev server honors the header out of the box, and a [Vercel or Cloudflare server build](/docs/deployment#server-rendering) wires the same negotiation into the deploy automatically — routing rules on Vercel, a generated Worker on Cloudflare — no configuration needed. The homepage always negotiates, even when it's a custom landing page rather than a content page: its Markdown mirror falls back to the [`llms.txt`](/docs/discoverability/llms-txt) index, so an agent asking the site root for Markdown gets the machine-readable map of the site. Markdown responses also carry an `x-markdown-tokens` header — an estimated token count (~4 characters per token), following the convention of [Cloudflare's Markdown for Agents](https://developers.cloudflare.com/fundamentals/reference/markdown-for-agents/) — on every surface where Blume controls response headers: the dev server, server-rendered responses, and the negotiated homepage on Vercel and Cloudflare. Other deploy targets serve prerendered pages from a static layer with no request-time hook, so agents there fetch the `.md` URL directly; the [agent readability manifest](/docs/discoverability/agent-discovery#agent-readability) advertises `contentNegotiation` only on deployments that honor the header.
|
|
27
27
|
|
|
28
|
-
Missing pages negotiate too.
|
|
28
|
+
Missing pages negotiate too. The default [404 page](/docs/advanced/custom-pages#404-page) has a Markdown twin at `/404.md` — the not-found message followed by recovery links to every top-level section, the sitemap, and `llms.txt` — and on a Vercel or Cloudflare server build a request for a nonexistent URL that prefers Markdown gets that body with a real `404` status rather than the HTML shell. On Vercel the same goes for any `.md` URL with no page behind it. A 404 page of your own (a `pages/404.astro`, or a content page at `/404`) replaces the default along with its `/404.md` twin, so missing pages then answer with your HTML page.
|
|
29
29
|
|
|
30
30
|
### Custom component serializers
|
|
31
31
|
|
|
@@ -72,11 +72,13 @@ seo: {
|
|
|
72
72
|
|
|
73
73
|
By default the card renders in Takumi's built-in font, which covers only basic Latin glyphs — on its own, a title in another script (Japanese, Chinese, Korean, Arabic, Hindi, Russian, …) would render as tofu, empty boxes.
|
|
74
74
|
|
|
75
|
-
**
|
|
75
|
+
**Every script is covered by default.** Behind the built-in font, cards carry a fallback stack of Google Noto families, one per script: `Noto Sans` for Cyrillic, Greek, Vietnamese, and accented Latin, then `Noto Sans JP`, `Noto Sans Arabic`, `Noto Sans Devanagari`, and so on. A Japanese or Hindi title renders with nothing to configure, even on a site with no [locales](/docs/content/i18n). Fallback is per glyph, so Latin text keeps the built-in font. A card fetches from Google Fonts only when its text has a glyph the built-in font can't draw, and then only the subsets those glyphs need: an English card fetches nothing, so a Latin-only site still builds offline. The stack applies unless `og.fonts` is set, which takes over the whole list.
|
|
76
|
+
|
|
77
|
+
Chinese, Japanese, and Korean share most Han characters but draw some of them differently, and cards use Japanese forms by default. Each configured locale moves its own family to the front, so a site with a `zh` locale draws Han in Simplified Chinese forms, and `zh-Hant` or `zh-TW` in Traditional ones.
|
|
76
78
|
|
|
77
79
|
**Set [`theme.fonts`](/docs/configuration/theming#fonts) and the card follows it.** When your config picks its own fonts, the generated cards automatically render the headline in your display font and the description and footer in your body font, so shared links match the site — including non-Latin coverage, with nothing to configure here. (Families from non-Google providers are skipped — the card renderer can only fetch from Google Fonts — but local font files work.)
|
|
78
80
|
|
|
79
|
-
To use different fonts on cards than on the site,
|
|
81
|
+
To use different fonts on cards than on the site, set `og.fonts` explicitly. It always wins over the theme-derived fonts and replaces the script fallbacks, so list every family your cards need:
|
|
80
82
|
|
|
81
83
|
```ts blume.config.ts lineNumbers
|
|
82
84
|
seo: {
|
|
@@ -94,7 +96,7 @@ Each entry is a Google Fonts family name, an object pinning its `weight` (a numb
|
|
|
94
96
|
|
|
95
97
|
Google families are fetched at build — so a build that uses them needs network access — and the renderer only pulls the glyph subsets each title actually uses. Fallback is per-glyph, so adding a family only affects glyphs the other fonts can't draw.
|
|
96
98
|
|
|
97
|
-
An explicit `og.fonts: []` opts out entirely: cards keep the built-in font even when `theme.fonts` is set or a
|
|
99
|
+
An explicit `og.fonts: []` opts out entirely: cards keep the built-in font even when `theme.fonts` is set or a title needs a script fallback.
|
|
98
100
|
|
|
99
101
|
## Card cache
|
|
100
102
|
|
|
@@ -3,7 +3,7 @@ title: RSS feeds
|
|
|
3
3
|
description: A feed per dated content type — blog and changelog by default — served at /<type>/rss.xml and advertised to feed readers automatically.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
Blume builds an RSS feed for each content type in `rss.types` — `blog` and `changelog` by default — that has pages, served at `/<type>/rss.xml`. See [Feeds](/docs/content#feeds) for authoring blog and changelog entries with dates.
|
|
6
|
+
Blume builds an RSS feed for each content type in `seo.rss.types` — `blog` and `changelog` by default — that has pages, served at `/<type>/rss.xml`. See [Feeds](/docs/content#feeds) for authoring blog and changelog entries with dates.
|
|
7
7
|
|
|
8
8
|
A feed's links must be absolute, so feeds need a site URL: set [`deployment.site`](/docs/deployment#set-your-site-url), or deploy to a host Blume detects it from (Vercel, Netlify, Cloudflare). Without one, a build emits no feeds at all. During `blume dev` the local server's URL stands in, so feeds show up there either way.
|
|
9
9
|
|
|
@@ -32,7 +32,7 @@ Code samples are **protocol-aware**, keyed off the operation's binding (or its s
|
|
|
32
32
|
|
|
33
33
|
## Shared options
|
|
34
34
|
|
|
35
|
-
Everything documented for [OpenAPI](/docs/references/openapi) carries over, [`playground`](#try-it-for-events) included: [`route`](/docs/references/openapi#route), [`sources`](/docs/references/openapi#multiple-specs) with `label`/`route`, `expandSchemas`, the [per-source indexing](/docs/references/openapi#per-source-indexing) flags (`seoDescriptionSuffix` too — the generated sentence names the channel and action instead of an endpoint), and search indexing by operation summary and
|
|
35
|
+
Everything documented for [OpenAPI](/docs/references/openapi) carries over, [`playground`](#try-it-for-events) included: [`route`](/docs/references/openapi#route), [`sources`](/docs/references/openapi#multiple-specs) with `label`/`route`, `expandSchemas`, the [per-source indexing](/docs/references/openapi#per-source-indexing) flags (`seoDescriptionSuffix` too — the generated sentence names the channel and action instead of an endpoint), and search indexing by operation summary, description, tag, and endpoint (`SEND user/signup`).
|
|
36
36
|
|
|
37
37
|
## Embedding Scalar instead
|
|
38
38
|
|
|
@@ -82,7 +82,7 @@ reference: [
|
|
|
82
82
|
|
|
83
83
|
Query and mutation pages render an interactive panel: edit the request body (the query and variables), point it at your endpoint or a custom URL, and send — the code samples update live so what you copy is byte-for-byte what was sent. Disable it with `playground: false`. Subscription pages show the generated operation and an example event instead: subscriptions run over a stateful transport (WebSocket or SSE) that the playground's single HTTP `POST` can't speak.
|
|
84
84
|
|
|
85
|
-
If your GraphQL API doesn't allow cross-origin requests from the docs site, route sends through a CORS proxy — a URL of your own, or `true` for the built-in `/_api-proxy` endpoint (under your `basePath`, if you set one; it needs [server output](/docs/deployment#server-rendering): a host adapter such as `deployment: vercel()` from `blume/deploy`). The built-in proxy only forwards to origins your documented specs declare — each configured GraphQL `endpoint`, plus any absolute `servers[].url` from a documented [OpenAPI spec](/docs/references/openapi) — so a public docs deployment can't be aimed at other hosts. That makes `endpoint` required for a working proxy: without one, the proxy has no origin to allow for this reference and refuses every send (the build warns about this). The same body limit and response headers apply as for the [OpenAPI proxy](/docs/references/openapi#try-it-playground).
|
|
85
|
+
If your GraphQL API doesn't allow cross-origin requests from the docs site, route sends through a CORS proxy — a URL of your own, or `true` for the built-in `/_api-proxy` endpoint (under your `basePath`, if you set one; it needs [server output](/docs/deployment#server-rendering): a host adapter such as `deployment: vercel()` from `blume/deploy`). The built-in proxy only forwards to origins your documented specs declare — each configured GraphQL `endpoint`, plus any absolute `servers[].url` from a documented [OpenAPI spec](/docs/references/openapi) — so a public docs deployment can't be aimed at other hosts. That makes `endpoint` required for a working proxy: without one, the proxy has no origin to allow for this reference and refuses every send (the build warns about this). The same body limit, header forwarding, and response headers apply as for the [OpenAPI proxy](/docs/references/openapi#try-it-playground).
|
|
86
86
|
|
|
87
87
|
```ts blume.config.ts lineNumbers
|
|
88
88
|
reference: [
|
|
@@ -29,7 +29,7 @@ navigation: {
|
|
|
29
29
|
```
|
|
30
30
|
|
|
31
31
|
:::note
|
|
32
|
-
Operations are indexed for search by their **summary
|
|
32
|
+
Operations are indexed for search by their **summary, description, tag, and endpoint** (`GET /pets/{id}`). The rendered schema tables and code samples aren't full-text indexed; search matches an operation's title, prose, section, and path, then links to its own page.
|
|
33
33
|
:::
|
|
34
34
|
|
|
35
35
|
## A local spec
|
|
@@ -69,10 +69,12 @@ reference: [
|
|
|
69
69
|
|
|
70
70
|
## Try it playground
|
|
71
71
|
|
|
72
|
-
Operation pages rendered natively ship an interactive **Try it** panel by default. Blume generates the form from the operation itself: an input per path, query, and header parameter, a body editor built from the request-body schema, everything prefilled from the spec's examples. A server picker lists the operation's servers (its own `servers`, else its path's, else the spec's, with each `{variable}` at its `default`), with a free-text field for any other base URL, and auth inputs match the operation's [resolved security](#authorization) — bearer token, API key, and basic credentials, with OAuth2 as a token paste field (bring an access token; Blume doesn't run the flow).
|
|
72
|
+
Operation pages rendered natively ship an interactive **Try it** panel by default. Blume generates the form from the operation itself: an input per path, query, and header parameter, a body editor built from the request-body schema, everything prefilled from the spec's examples. Values go on the wire the way the spec describes them: array and object parameters follow their `style` and `explode` (`tags=dog&tags=cat` in a query, `1,2` in a path, `filter[color]=red` for `deepObject`), and an `application/x-www-form-urlencoded` or `multipart/form-data` body is sent as form fields rather than JSON. A server picker lists the operation's servers (its own `servers`, else its path's, else the spec's, with each `{variable}` at its `default`), with a free-text field for any other base URL, and auth inputs match the operation's [resolved security](#authorization) — bearer token, API key, and basic credentials, with OAuth2 as a token paste field (bring an access token; Blume doesn't run the flow).
|
|
73
73
|
|
|
74
74
|
The panel and the code samples stay in lockstep: values typed into the form update the generated samples live, so a copied curl command always matches exactly what **Send** would do. And it stays out of the way — the panel is server-rendered collapsed, and its JavaScript loads only when a reader first opens it. Readers who never touch it download none of it.
|
|
75
75
|
|
|
76
|
+
The one method a browser can't send is `TRACE`: `fetch` refuses it, so on a `trace` operation **Send** says so instead of sending, and the JavaScript sample (built on `fetch`) is a note rather than code. The cURL and Python samples send it fine.
|
|
77
|
+
|
|
76
78
|
`playground: false` is the entire off switch:
|
|
77
79
|
|
|
78
80
|
```ts blume.config.ts lineNumbers
|
|
@@ -98,7 +100,7 @@ reference: [
|
|
|
98
100
|
],
|
|
99
101
|
```
|
|
100
102
|
|
|
101
|
-
The built-in proxy only forwards requests to the origins your specs declare in `servers` (at the document, path, or operation level, with variables at their defaults) — including across redirects — so a public docs deployment can't be aimed at other hosts on its network. A **Custom base URL** typed into the panel isn't a documented server: with the proxy enabled, requests to it are refused with a 403. It reads a request body only up to 4 MB (anything larger gets a `413`), and every response it relays carries `Content-Security-Policy: sandbox`, `X-Content-Type-Options: nosniff`, and `Cross-Origin-Resource-Policy: same-origin` — plus `Content-Disposition: attachment` for HTML or SVG — so an API error page that echoes its input can't run script on the docs origin.
|
|
103
|
+
The built-in proxy only forwards requests to the origins your specs declare in `servers` (at the document, path, or operation level, with variables at their defaults) — including across redirects — so a public docs deployment can't be aimed at other hosts on its network. A **Custom base URL** typed into the panel isn't a documented server: with the proxy enabled, requests to it are refused with a 403. It forwards only the headers the panel sets itself — the credentials and header parameters filled in, and the body's `Content-Type` — so cookies, credentials the browser attaches for the docs site (HTTP Basic auth on a password-protected preview, say), and headers your host adds (`X-Forwarded-For`, `CF-*`, `X-Vercel-*`) never reach the API. It reads a request body only up to 4 MB (anything larger gets a `413`), and every response it relays carries `Content-Security-Policy: sandbox`, `X-Content-Type-Options: nosniff`, and `Cross-Origin-Resource-Policy: same-origin` — plus `Content-Disposition: attachment` for HTML or SVG — so an API error page that echoes its input can't run script on the docs origin.
|
|
102
104
|
|
|
103
105
|
## Multiple specs
|
|
104
106
|
|