blume 2.0.3 → 2.1.1
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/AGENTS.md +1 -0
- package/CHANGELOG.md +142 -0
- package/README.md +1 -1
- package/dist/cli/{chunk-5f86nr5m.js → chunk-073rdvgb.js} +21 -48
- package/dist/cli/{chunk-5f86nr5m.js.map → chunk-073rdvgb.js.map} +4 -5
- package/dist/cli/{chunk-ga0pf4aj.js → chunk-0n9xkp3d.js} +12 -3
- package/dist/cli/{chunk-ga0pf4aj.js.map → chunk-0n9xkp3d.js.map} +3 -3
- package/dist/cli/chunk-150jk7km.js +52 -0
- package/dist/cli/chunk-150jk7km.js.map +10 -0
- package/dist/cli/{chunk-9t7a85s3.js → chunk-313vnn40.js} +30 -19
- package/dist/cli/chunk-313vnn40.js.map +10 -0
- package/dist/cli/{chunk-tkacnehg.js → chunk-3v3ffbrj.js} +2 -2
- package/dist/cli/{chunk-q58y5e6a.js → chunk-3x6x3pph.js} +46 -24
- package/dist/cli/chunk-3x6x3pph.js.map +10 -0
- package/dist/cli/{chunk-1d7ve1dm.js → chunk-42t4jxdx.js} +37 -5
- package/dist/cli/chunk-42t4jxdx.js.map +12 -0
- package/dist/cli/{chunk-8ktnccpt.js → chunk-54ztw1nj.js} +21 -2
- package/dist/cli/chunk-54ztw1nj.js.map +10 -0
- package/dist/cli/{chunk-hm3vjy5s.js → chunk-5vjtgs6e.js} +28 -10
- package/dist/cli/{chunk-hm3vjy5s.js.map → chunk-5vjtgs6e.js.map} +4 -4
- package/dist/cli/chunk-66w9j7p6.js +322 -0
- package/dist/cli/chunk-66w9j7p6.js.map +14 -0
- package/dist/cli/{chunk-2hsdwb9n.js → chunk-7ppf1rva.js} +34 -18
- package/dist/cli/chunk-7ppf1rva.js.map +10 -0
- package/dist/cli/{chunk-r9rcc4w7.js → chunk-8y2kmjv8.js} +7 -7
- package/dist/cli/{chunk-r20tn01b.js → chunk-c1y538kd.js} +8 -2
- package/dist/cli/{chunk-r20tn01b.js.map → chunk-c1y538kd.js.map} +3 -3
- package/dist/cli/{chunk-2eytanqx.js → chunk-c887fj0s.js} +2 -2
- package/dist/cli/{chunk-p3v96n38.js → chunk-cfyg47zg.js} +16 -6
- package/dist/cli/chunk-cfyg47zg.js.map +10 -0
- package/dist/cli/chunk-cm89scdv.js +443 -0
- package/dist/cli/chunk-cm89scdv.js.map +11 -0
- package/dist/cli/{chunk-akbpwfxc.js → chunk-dzwehpy7.js} +2 -2
- package/dist/cli/{chunk-wrr3j9w9.js → chunk-e6atmn4h.js} +299 -72
- package/dist/cli/chunk-e6atmn4h.js.map +36 -0
- package/dist/cli/{chunk-tzmab476.js → chunk-e8xw9qkh.js} +8 -6
- package/dist/cli/{chunk-tzmab476.js.map → chunk-e8xw9qkh.js.map} +3 -3
- package/dist/cli/{chunk-6dsbexzp.js → chunk-e9q7a2ak.js} +17 -15
- package/dist/cli/{chunk-6dsbexzp.js.map → chunk-e9q7a2ak.js.map} +2 -2
- package/dist/cli/{chunk-pv29h0wf.js → chunk-ehweg4fr.js} +5155 -1249
- package/dist/cli/chunk-ehweg4fr.js.map +218 -0
- package/dist/cli/{chunk-c8chx29p.js → chunk-ep6nd0rn.js} +390 -318
- package/dist/cli/chunk-ep6nd0rn.js.map +36 -0
- package/dist/cli/{chunk-p73c0m7w.js → chunk-fdrkhpjy.js} +18 -15
- package/dist/cli/{chunk-p73c0m7w.js.map → chunk-fdrkhpjy.js.map} +3 -3
- package/dist/cli/{chunk-2z928egk.js → chunk-ft9vfys6.js} +5 -5
- package/dist/cli/{chunk-5m5nmvyq.js → chunk-gb420vvz.js} +316 -79
- package/dist/cli/chunk-gb420vvz.js.map +17 -0
- package/dist/cli/{chunk-vg9r4eb9.js → chunk-hebn0tpx.js} +86 -13
- package/dist/cli/chunk-hebn0tpx.js.map +14 -0
- package/dist/cli/{chunk-35d4wj9f.js → chunk-htrwgabr.js} +41 -23
- package/dist/cli/chunk-htrwgabr.js.map +15 -0
- package/dist/cli/{chunk-g4hq16wv.js → chunk-hx3xqnk9.js} +16 -14
- package/dist/cli/{chunk-g4hq16wv.js.map → chunk-hx3xqnk9.js.map} +2 -2
- package/dist/cli/chunk-j134vrp2.js +65 -0
- package/dist/cli/chunk-j134vrp2.js.map +10 -0
- package/dist/cli/{chunk-a58773jm.js → chunk-kma9f6sf.js} +2 -2
- package/dist/cli/chunk-kwrg63tm.js +31 -0
- package/dist/cli/chunk-kwrg63tm.js.map +10 -0
- package/dist/cli/{chunk-ey84smr6.js → chunk-mrcccgnh.js} +6 -6
- package/dist/cli/{chunk-ey84smr6.js.map → chunk-mrcccgnh.js.map} +1 -1
- package/dist/cli/{chunk-yfyb25rh.js → chunk-n0v7m8ry.js} +24 -8
- package/dist/cli/chunk-n0v7m8ry.js.map +14 -0
- package/dist/cli/{chunk-j85vccga.js → chunk-ncj7w596.js} +576 -367
- package/dist/cli/chunk-ncj7w596.js.map +35 -0
- package/dist/cli/{chunk-5xvm6tfj.js → chunk-nq1d20w2.js} +17 -15
- package/dist/cli/{chunk-5xvm6tfj.js.map → chunk-nq1d20w2.js.map} +2 -2
- package/dist/cli/{chunk-pehfxfta.js → chunk-nrns10mj.js} +6 -98
- package/dist/cli/chunk-nrns10mj.js.map +10 -0
- package/dist/cli/{chunk-crgn1q09.js → chunk-sds923fa.js} +4 -4
- package/dist/cli/chunk-t2m5j4pr.js +104 -0
- package/dist/cli/chunk-t2m5j4pr.js.map +11 -0
- package/dist/cli/{chunk-acanzt5p.js → chunk-tdqhyxfz.js} +6 -6
- package/dist/cli/chunk-tphac74f.js +126 -0
- package/dist/cli/chunk-tphac74f.js.map +11 -0
- package/dist/cli/chunk-w1r4vase.js +18 -0
- package/dist/cli/chunk-w1r4vase.js.map +10 -0
- package/dist/cli/{chunk-3em5wd2y.js → chunk-zccbjcj0.js} +4 -3
- package/dist/cli/{chunk-3em5wd2y.js.map → chunk-zccbjcj0.js.map} +2 -2
- package/dist/cli/index.js +31 -20
- package/dist/cli/index.js.map +5 -5
- package/dist/types/ai/agent-surface.d.ts +8 -7
- package/dist/types/ai/ai-catalog.d.ts +7 -0
- package/dist/types/ai/ask-context.d.ts +26 -0
- package/dist/types/ai/ask.d.ts +271 -58
- package/dist/types/ai/component-markdown.d.ts +2 -0
- package/dist/types/ai/index.d.ts +2 -2
- package/dist/types/ai/openapi-components.d.ts +4 -1
- package/dist/types/ai/site-skill.d.ts +26 -0
- package/dist/types/ai/skills.d.ts +16 -0
- package/dist/types/astro/integration.d.ts +9 -0
- package/dist/types/astro/markdown-negotiation.d.ts +3 -0
- package/dist/types/astro/pages.d.ts +10 -0
- package/dist/types/captcha/hcaptcha.d.ts +27 -0
- package/dist/types/captcha/index.d.ts +28 -0
- package/dist/types/captcha/schema.d.ts +29 -0
- package/dist/types/captcha/turnstile.d.ts +28 -0
- package/dist/types/cli/init/scaffold.d.ts +1 -1
- package/dist/types/components/content/api-field.d.ts +62 -0
- package/dist/types/components/content/api-page.d.ts +100 -0
- package/dist/types/components/layout/nav-utils.d.ts +26 -0
- package/dist/types/components/openapi/code-samples.d.ts +29 -0
- package/dist/types/components/openapi/helpers.d.ts +158 -0
- package/dist/types/components/openapi/security.d.ts +95 -0
- package/dist/types/components/openapi/snippets.d.ts +60 -0
- package/dist/types/consent/ethyca.d.ts +48 -0
- package/dist/types/consent/index.d.ts +37 -0
- package/dist/types/consent/native.d.ts +28 -0
- package/dist/types/consent/osano.d.ts +42 -0
- package/dist/types/consent/schema.d.ts +110 -0
- package/dist/types/core/changelog-index.d.ts +8 -0
- package/dist/types/core/config-input.d.ts +217 -23
- package/dist/types/core/data.d.ts +53 -4
- package/dist/types/core/footer.d.ts +8 -0
- package/dist/types/core/i18n-ui.d.ts +88 -0
- package/dist/types/core/includes.d.ts +8 -2
- package/dist/types/core/links.d.ts +8 -0
- package/dist/types/core/localizable.d.ts +7 -0
- package/dist/types/core/page-modes.d.ts +29 -0
- package/dist/types/core/probe.d.ts +2 -0
- package/dist/types/core/project-graph.d.ts +6 -0
- package/dist/types/core/redirect-patterns.d.ts +152 -0
- package/dist/types/core/related.d.ts +40 -0
- package/dist/types/core/schema.d.ts +670 -56
- package/dist/types/core/sources/cache.d.ts +3 -0
- package/dist/types/core/sources/contentful-rich-text.d.ts +11 -2
- package/dist/types/core/sources/contentful.d.ts +17 -1
- package/dist/types/core/sources/lexical.d.ts +5 -0
- package/dist/types/core/sources/normalize.d.ts +20 -1
- package/dist/types/core/sources/read.d.ts +5 -0
- package/dist/types/core/sources/remote.d.ts +37 -10
- package/dist/types/core/sources/sanity.d.ts +1 -1
- package/dist/types/core/types.d.ts +18 -1
- package/dist/types/core/variables.d.ts +42 -0
- package/dist/types/deploy/adapter-output.d.ts +2 -1
- package/dist/types/deploy/adapters/cloudflare.d.ts +7 -5
- package/dist/types/deploy/adapters/node.d.ts +58 -23
- package/dist/types/deploy/adapters/registry.d.ts +10 -0
- package/dist/types/deploy/adapters/types.d.ts +3 -2
- package/dist/types/deploy/node-headers.d.ts +13 -2
- package/dist/types/deploy/platforms/cloudflare.d.ts +15 -7
- package/dist/types/deploy/platforms/netlify.d.ts +7 -0
- package/dist/types/deploy/platforms/node.d.ts +3 -1
- package/dist/types/deploy/platforms/types.d.ts +18 -7
- package/dist/types/deploy/platforms/vercel.d.ts +26 -1
- package/dist/types/deploy/redirects.d.ts +55 -11
- package/dist/types/deploy/sitemap.d.ts +2 -1
- package/dist/types/deploy/vercel-negotiation.d.ts +51 -21
- package/dist/types/markdown/code-title.d.ts +17 -0
- package/dist/types/markdown/features.d.ts +3 -2
- package/dist/types/narration/build.d.ts +70 -0
- package/dist/types/narration/provider.d.ts +26 -0
- package/dist/types/narration/script.d.ts +154 -0
- package/dist/types/openapi/checks.d.ts +27 -0
- package/dist/types/openapi/graphql.d.ts +6 -0
- package/dist/types/openapi/model.d.ts +27 -10
- package/dist/types/openapi/overlay.d.ts +54 -0
- package/dist/types/openapi/parse.d.ts +16 -0
- package/dist/types/openapi/references.d.ts +30 -4
- package/dist/types/ratelimit/cloudflare.d.ts +39 -0
- package/dist/types/ratelimit/index.d.ts +27 -0
- package/dist/types/ratelimit/memory.d.ts +36 -0
- package/dist/types/ratelimit/schema.d.ts +119 -0
- package/dist/types/ratelimit/upstash.d.ts +46 -0
- package/dist/types/ratelimit/wrangler.d.ts +23 -0
- package/dist/types/reference/asyncapi.d.ts +10 -10
- package/dist/types/reference/graphql.d.ts +89 -11
- package/dist/types/reference/index.d.ts +1 -1
- package/dist/types/reference/openapi.d.ts +33 -12
- package/dist/types/reference/options.d.ts +82 -6
- package/dist/types/reference/scalar.d.ts +13 -0
- package/dist/types/reference/schema.d.ts +144 -36
- package/dist/types/search/adapters/registry.d.ts +3 -0
- package/dist/types/search/adapters/typesense.d.ts +14 -4
- package/dist/types/search/build.d.ts +3 -1
- package/dist/types/search/documents.d.ts +12 -1
- package/dist/types/search/orama-index.d.ts +13 -9
- package/dist/types/search/sync/algolia.d.ts +5 -2
- package/dist/types/search/sync/index.d.ts +3 -1
- package/dist/types/search/sync/typesense.d.ts +11 -7
- package/dist/types/seo/metatags.d.ts +20 -0
- package/dist/types/sources/contentful.d.ts +16 -0
- package/dist/types/sources/github-releases.d.ts +8 -1
- package/dist/types/sources/payload.d.ts +2 -0
- package/dist/types/sources/registry.d.ts +54 -0
- package/dist/types/sources/shared.d.ts +3 -0
- package/dist/types/sources/strapi.d.ts +2 -0
- package/docs/01-quickstart.mdx +4 -2
- package/docs/02-deployment.mdx +71 -17
- package/docs/03-upgrading.mdx +4 -4
- package/docs/04-migrating.mdx +1 -1
- package/docs/advanced/changelog.mdx +13 -2
- package/docs/advanced/skills.mdx +15 -1
- package/docs/cli/audit.mdx +51 -8
- package/docs/cli/doctor.mdx +5 -1
- package/docs/cli/evals.mdx +4 -4
- package/docs/cli/index.mdx +1 -0
- package/docs/cli/translate.mdx +1 -0
- package/docs/cli/validate.mdx +4 -3
- package/docs/configuration/analytics.mdx +3 -1
- package/docs/configuration/assistant.mdx +194 -38
- package/docs/configuration/consent.mdx +100 -0
- package/docs/configuration/customization.mdx +8 -6
- package/docs/configuration/export.mdx +5 -3
- package/docs/configuration/index.mdx +64 -5
- package/docs/configuration/meta.ts +3 -0
- package/docs/configuration/narration.mdx +119 -0
- package/docs/configuration/rate-limiting.mdx +90 -0
- package/docs/configuration/search.mdx +63 -12
- package/docs/configuration/theming.mdx +3 -1
- package/docs/content/components.mdx +108 -2
- package/docs/content/frontmatter.mdx +80 -2
- package/docs/content/i18n.mdx +39 -4
- package/docs/content/includes.mdx +16 -0
- package/docs/content/meta.mdx +1 -0
- package/docs/content/meta.ts +1 -0
- package/docs/content/navigation.mdx +32 -10
- package/docs/content/sources/contentful.mdx +35 -0
- package/docs/content/sources/custom.mdx +43 -0
- package/docs/content/sources/github-releases.mdx +39 -0
- package/docs/content/sources/index.mdx +91 -0
- package/docs/content/sources/meta.ts +16 -0
- package/docs/content/sources/notion.mdx +32 -0
- package/docs/content/sources/obsidian.mdx +37 -0
- package/docs/content/sources/payload.mdx +31 -0
- package/docs/content/sources/remote-mdx.mdx +44 -0
- package/docs/content/sources/sanity.mdx +29 -0
- package/docs/content/sources/strapi.mdx +32 -0
- package/docs/content/syntax.mdx +69 -4
- package/docs/content/variables.mdx +41 -0
- package/docs/discoverability/agent-discovery.mdx +29 -2
- package/docs/discoverability/index.mdx +2 -2
- package/docs/discoverability/json-api.mdx +2 -0
- package/docs/discoverability/llms-txt.mdx +2 -2
- package/docs/discoverability/markdown.mdx +3 -1
- package/docs/discoverability/mcp.mdx +4 -0
- package/docs/discoverability/metadata.mdx +17 -0
- package/docs/discoverability/sitemap-and-robots.mdx +1 -1
- package/docs/references/api-pages.mdx +74 -0
- package/docs/references/asyncapi.mdx +4 -2
- package/docs/references/graphql.mdx +14 -2
- package/docs/references/meta.ts +1 -1
- package/docs/references/openapi.mdx +148 -7
- package/docs/references/scalar.mdx +3 -1
- package/package.json +43 -8
- package/skills/blume/SKILL.md +3 -0
- package/skills/blume-migrate/SKILL.md +6 -6
- package/skills/blume-migrate/references/docusaurus.md +7 -7
- package/skills/blume-migrate/references/fumadocs.md +17 -13
- package/skills/blume-migrate/references/mintlify.md +37 -19
- package/skills/blume-migrate/references/nextra.md +10 -7
- package/skills/blume-migrate/references/starlight.md +11 -8
- package/skills/blume-migrate/scripts/mintlify-codemod.mjs +60 -14
- package/skills/blume-write-skill/SKILL.md +82 -0
- package/src/ai/agent-readability.ts +2 -1
- package/src/ai/agent-surface.ts +9 -7
- package/src/ai/ai-catalog.ts +6 -3
- package/src/ai/ask-context.ts +103 -20
- package/src/ai/ask-data.ts +6 -0
- package/src/ai/ask-limits.ts +13 -0
- package/src/ai/ask-tools.ts +142 -0
- package/src/ai/ask.ts +354 -76
- package/src/ai/changelog-markdown.ts +11 -6
- package/src/ai/component-markdown.ts +76 -1
- package/src/ai/cors.ts +14 -3
- package/src/ai/index.ts +12 -0
- package/src/ai/llms.ts +6 -2
- package/src/ai/markdown.ts +2 -1
- package/src/ai/mcp/data.ts +6 -0
- package/src/ai/mcp/query.ts +14 -6
- package/src/ai/openapi-components.ts +36 -6
- package/src/ai/relative-links.ts +4 -38
- package/src/ai/site-skill.ts +274 -0
- package/src/ai/skills.ts +35 -2
- package/src/ai/write-skill.ts +97 -0
- package/src/astro/generate.ts +210 -66
- package/src/astro/index.ts +1 -0
- package/src/astro/integration.ts +42 -4
- package/src/astro/markdown-negotiation.ts +3 -0
- package/src/astro/module-types.ts +9 -1
- package/src/astro/pages.ts +23 -0
- package/src/astro/templates.ts +406 -108
- package/src/astro/variables.ts +31 -0
- package/src/audit/catalog.ts +38 -3
- package/src/audit/checks/contrast.ts +183 -0
- package/src/audit/checks/i18n.ts +2 -3
- package/src/audit/checks/indexability.ts +2 -3
- package/src/audit/checks/links.ts +19 -13
- package/src/audit/checks/network.ts +110 -6
- package/src/audit/checks/redirects.ts +6 -4
- package/src/audit/checks/robots.ts +58 -2
- package/src/audit/checks/sitemap.ts +2 -3
- package/src/audit/redirects.ts +46 -15
- package/src/audit/run.ts +5 -0
- package/src/audit/types.ts +4 -1
- package/src/audit/url.ts +14 -5
- package/src/blume-modules.d.ts +12 -1
- package/src/captcha/client.ts +152 -0
- package/src/captcha/hcaptcha.ts +36 -0
- package/src/captcha/index.ts +28 -0
- package/src/captcha/schema.ts +32 -0
- package/src/captcha/turnstile.ts +38 -0
- package/src/captcha/verify.ts +71 -0
- package/src/cli/args.ts +51 -0
- package/src/cli/build-failure.ts +23 -0
- package/src/cli/command-meta.ts +5 -0
- package/src/cli/commands/audit.ts +10 -1
- package/src/cli/commands/dev.ts +18 -2
- package/src/cli/commands/doctor.ts +67 -28
- package/src/cli/commands/eval.ts +36 -4
- package/src/cli/commands/init.ts +6 -4
- package/src/cli/commands/skill.ts +96 -0
- package/src/cli/commands/validate.ts +10 -1
- package/src/cli/index.ts +5 -0
- package/src/cli/init/scaffold.ts +3 -3
- package/src/cli/prepare.ts +6 -3
- package/src/cli/required-secrets.ts +72 -30
- package/src/components/BlumePage.astro +2 -0
- package/src/components/content/ApiEndpoint.astro +18 -0
- package/src/components/content/ApiField.astro +79 -0
- package/src/components/content/ApiPlayground.astro +66 -0
- package/src/components/content/ApiRail.astro +19 -0
- package/src/components/content/Color.astro +1 -0
- package/src/components/content/FileTree.astro +1 -0
- package/src/components/content/GithubInfo.astro +1 -0
- package/src/components/content/Panel.astro +1 -0
- package/src/components/content/ParamField.astro +25 -0
- package/src/components/content/RequestExample.astro +17 -0
- package/src/components/content/ResponseExample.astro +17 -0
- package/src/components/content/ResponseField.astro +32 -0
- package/src/components/content/Step.astro +1 -0
- package/src/components/content/Tile.astro +1 -0
- package/src/components/content/Tooltip.astro +1 -0
- package/src/components/content/Tree.astro +1 -0
- package/src/components/content/TypeTable.astro +4 -1
- package/src/components/content/View.astro +21 -0
- package/src/components/content/ViewSwitcher.astro +168 -0
- package/src/components/content/api-field.ts +103 -0
- package/src/components/content/api-page.ts +248 -0
- package/src/components/content/mermaid-element.ts +15 -1
- package/src/components/content/view-switcher.ts +71 -0
- package/src/components/index.ts +2 -0
- package/src/components/islands/Assistant.astro +10 -1
- package/src/components/islands/assistant.tsx +104 -14
- package/src/components/islands/code-question.ts +62 -0
- package/src/components/islands/hooks.ts +136 -21
- package/src/components/islands/support-link.ts +68 -0
- package/src/components/layout/Analytics.astro +11 -2
- package/src/components/layout/Banner.astro +14 -10
- package/src/components/layout/Breadcrumbs.astro +6 -2
- package/src/components/layout/ConsentBanner.astro +62 -0
- package/src/components/layout/ConsentHead.astro +38 -0
- package/src/components/layout/Directory.astro +94 -0
- package/src/components/layout/DrawerSwitchers.astro +51 -0
- package/src/components/layout/Empty.astro +2 -2
- package/src/components/layout/Header.astro +122 -80
- package/src/components/layout/LanguageSwitcher.astro +48 -15
- package/src/components/layout/NarrationPlayer.astro +1085 -0
- package/src/components/layout/NavSelector.astro +33 -7
- package/src/components/layout/PageActions.astro +139 -24
- package/src/components/layout/PageFeedback.astro +54 -49
- package/src/components/layout/PageLayout.astro +71 -3
- package/src/components/layout/ReferenceLayout.astro +17 -6
- package/src/components/layout/RelatedPages.astro +42 -0
- package/src/components/layout/RootLayout.astro +318 -47
- package/src/components/layout/Search.astro +47 -19
- package/src/components/layout/SiteFooter.astro +124 -0
- package/src/components/layout/SiteMetatags.astro +16 -0
- package/src/components/layout/TableOfContents.astro +24 -17
- package/src/components/layout/consent/native.ts +79 -0
- package/src/components/layout/consent/types.ts +37 -0
- package/src/components/layout/footer-links.ts +53 -0
- package/src/components/layout/footer-socials.ts +87 -0
- package/src/components/layout/head-scripts.ts +6 -1
- package/src/components/layout/locale-redirect.ts +107 -0
- package/src/components/layout/nav-utils.ts +83 -0
- package/src/components/layout/page-feedback.ts +96 -0
- package/src/components/layout/search/algolia.ts +10 -1
- package/src/components/layout/search/analytics.ts +126 -0
- package/src/components/layout/search/endpoint.ts +48 -5
- package/src/components/layout/search/flexsearch.ts +17 -5
- package/src/components/layout/search/orama-cloud.ts +26 -14
- package/src/components/layout/search/pagefind.ts +114 -5
- package/src/components/layout/search/types.ts +32 -0
- package/src/components/layout/search/typesense.ts +19 -3
- package/src/components/openapi/AsyncApiOperation.astro +14 -7
- package/src/components/openapi/Authorization.astro +10 -0
- package/src/components/openapi/GraphqlOperation.astro +5 -0
- package/src/components/openapi/Operation.astro +184 -13
- package/src/components/openapi/ParametersTable.astro +8 -4
- package/src/components/openapi/Playground.astro +7 -1
- package/src/components/openapi/RequestBody.astro +24 -5
- package/src/components/openapi/RequestPanel.astro +59 -7
- package/src/components/openapi/Responses.astro +7 -4
- package/src/components/openapi/SchemaTable.astro +15 -3
- package/src/components/openapi/async-snippets.ts +65 -9
- package/src/components/openapi/async.ts +123 -29
- package/src/components/openapi/code-samples.ts +97 -0
- package/src/components/openapi/graphql-helpers.ts +35 -12
- package/src/components/openapi/helpers.ts +36 -2
- package/src/components/openapi/message-model.ts +54 -11
- package/src/components/openapi/message.ts +14 -4
- package/src/components/openapi/operation-model.ts +16 -7
- package/src/components/openapi/playground-client.ts +24 -5
- package/src/components/openapi/playground-schema.ts +1 -1
- package/src/components/openapi/schema-tree.ts +44 -14
- package/src/components/openapi/security.ts +16 -3
- package/src/components/openapi/snippets.ts +873 -10
- package/src/components/openapi/validate-json.ts +4 -3
- package/src/components/props.ts +6 -0
- package/src/consent/client.ts +95 -0
- package/src/consent/clients.ts +19 -0
- package/src/consent/ethyca.ts +71 -0
- package/src/consent/head.ts +24 -0
- package/src/consent/index.ts +37 -0
- package/src/consent/init.ts +29 -0
- package/src/consent/native.ts +36 -0
- package/src/consent/osano.ts +59 -0
- package/src/consent/schema.ts +30 -0
- package/src/core/builtin-tags.ts +5 -0
- package/src/core/changelog-index.ts +31 -1
- package/src/core/client-address.ts +19 -0
- package/src/core/component-diagnostics.ts +53 -0
- package/src/core/component-overrides.ts +32 -0
- package/src/core/config-input.ts +225 -23
- package/src/core/data.ts +46 -4
- package/src/core/diagnostics.ts +8 -2
- package/src/core/footer.ts +26 -0
- package/src/core/graph.ts +39 -36
- package/src/core/i18n-ui.ts +84 -2
- package/src/core/includes.ts +21 -4
- package/src/core/links.ts +63 -19
- package/src/core/localizable.ts +26 -0
- package/src/core/navigation.ts +43 -12
- package/src/core/page-modes.ts +56 -0
- package/src/core/probe.ts +26 -6
- package/src/core/project-graph.ts +163 -16
- package/src/core/redirect-patterns.ts +520 -0
- package/src/core/related.ts +131 -0
- package/src/core/schema.ts +339 -66
- package/src/core/sources/cache.ts +6 -0
- package/src/core/sources/contentful-rich-text.ts +29 -6
- package/src/core/sources/contentful.ts +135 -25
- package/src/core/sources/filesystem.ts +26 -4
- package/src/core/sources/github-releases.ts +12 -1
- package/src/core/sources/lexical.ts +15 -10
- package/src/core/sources/mdx-remote.ts +62 -10
- package/src/core/sources/normalize.ts +228 -41
- package/src/core/sources/notion.ts +7 -1
- package/src/core/sources/obsidian.ts +16 -3
- package/src/core/sources/payload.ts +38 -15
- package/src/core/sources/read.ts +8 -3
- package/src/core/sources/remote.ts +72 -15
- package/src/core/sources/resolve.ts +11 -1
- package/src/core/sources/sanity.ts +43 -25
- package/src/core/sources/strapi.ts +2 -2
- package/src/core/types.ts +19 -1
- package/src/core/ui-packs/ar.ts +44 -0
- package/src/core/ui-packs/bg.ts +46 -0
- package/src/core/ui-packs/bn.ts +44 -0
- package/src/core/ui-packs/ca.ts +47 -0
- package/src/core/ui-packs/cs.ts +45 -0
- package/src/core/ui-packs/da.ts +46 -0
- package/src/core/ui-packs/de.ts +47 -0
- package/src/core/ui-packs/el.ts +46 -0
- package/src/core/ui-packs/es.ts +47 -0
- package/src/core/ui-packs/fa.ts +46 -0
- package/src/core/ui-packs/fi.ts +46 -0
- package/src/core/ui-packs/fr.ts +47 -0
- package/src/core/ui-packs/he.ts +44 -0
- package/src/core/ui-packs/hi.ts +45 -0
- package/src/core/ui-packs/hr.ts +46 -0
- package/src/core/ui-packs/hu.ts +45 -0
- package/src/core/ui-packs/id.ts +46 -0
- package/src/core/ui-packs/it.ts +46 -0
- package/src/core/ui-packs/ja.ts +46 -0
- package/src/core/ui-packs/ko.ts +45 -0
- package/src/core/ui-packs/nl.ts +47 -0
- package/src/core/ui-packs/no.ts +45 -0
- package/src/core/ui-packs/pl.ts +46 -0
- package/src/core/ui-packs/pt-br.ts +47 -0
- package/src/core/ui-packs/pt.ts +46 -0
- package/src/core/ui-packs/ro.ts +46 -0
- package/src/core/ui-packs/ru.ts +46 -0
- package/src/core/ui-packs/sk.ts +45 -0
- package/src/core/ui-packs/sr.ts +46 -0
- package/src/core/ui-packs/sv.ts +45 -0
- package/src/core/ui-packs/th.ts +44 -0
- package/src/core/ui-packs/tr.ts +46 -0
- package/src/core/ui-packs/uk.ts +46 -0
- package/src/core/ui-packs/vi.ts +46 -0
- package/src/core/ui-packs/zh-tw.ts +44 -0
- package/src/core/ui-packs/zh.ts +44 -0
- package/src/core/variables.ts +103 -0
- package/src/deploy/adapter-output.ts +7 -2
- package/src/deploy/adapters/cloudflare.ts +7 -5
- package/src/deploy/adapters/node.ts +47 -9
- package/src/deploy/adapters/types.ts +7 -3
- package/src/deploy/artifacts.ts +79 -9
- package/src/deploy/cloudflare-negotiation.ts +35 -5
- package/src/deploy/headers.ts +2 -1
- package/src/deploy/node-headers.ts +63 -9
- package/src/deploy/platforms/cloudflare.ts +45 -9
- package/src/deploy/platforms/netlify.ts +35 -2
- package/src/deploy/platforms/node.ts +12 -2
- package/src/deploy/platforms/types.ts +21 -7
- package/src/deploy/platforms/vercel.ts +149 -17
- package/src/deploy/redirects.ts +151 -24
- package/src/deploy/rss.ts +3 -1
- package/src/deploy/sitemap.ts +39 -5
- package/src/deploy/vercel-negotiation.ts +326 -102
- package/src/eval/agents.ts +18 -1
- package/src/eval/prompts.ts +6 -3
- package/src/eval/report.ts +34 -13
- package/src/eval/run.ts +5 -0
- package/src/markdown/api-rail.ts +259 -0
- package/src/markdown/code-title.ts +35 -9
- package/src/markdown/features.ts +3 -2
- package/src/markdown/fence-meta.ts +2 -0
- package/src/markdown/include.ts +11 -1
- package/src/markdown/index.ts +28 -5
- package/src/markdown/math.ts +4 -4
- package/src/markdown/relative-links.ts +3 -2
- package/src/markdown/variables.ts +56 -0
- package/src/markdown/views.ts +82 -0
- package/src/narration/build.ts +412 -0
- package/src/narration/player.ts +249 -0
- package/src/narration/provider.ts +29 -0
- package/src/narration/script.ts +592 -0
- package/src/og/card.ts +7 -6
- package/src/openapi/checks.ts +273 -0
- package/src/openapi/graphql-build.ts +21 -0
- package/src/openapi/graphql.ts +11 -0
- package/src/openapi/model.ts +72 -27
- package/src/openapi/overlay.ts +256 -0
- package/src/openapi/parse.ts +182 -4
- package/src/openapi/references.ts +64 -8
- package/src/openapi/render-mdx.ts +5 -1
- package/src/openapi/scalar.ts +40 -6
- package/src/openapi/source.ts +40 -15
- package/src/ratelimit/cloudflare.ts +54 -0
- package/src/ratelimit/index.ts +30 -0
- package/src/ratelimit/memory.ts +45 -0
- package/src/ratelimit/runtime.ts +247 -0
- package/src/ratelimit/schema.ts +28 -0
- package/src/ratelimit/upstash.ts +60 -0
- package/src/ratelimit/wrangler.ts +70 -0
- package/src/reference/asyncapi.ts +2 -2
- package/src/reference/graphql.ts +20 -3
- package/src/reference/index.ts +1 -0
- package/src/reference/openapi.ts +21 -7
- package/src/reference/options.ts +80 -8
- package/src/reference/scalar.ts +33 -8
- package/src/registry/eject.ts +23 -5
- package/src/registry/registry.ts +7 -0
- package/src/search/adapters/locale-scope.ts +30 -0
- package/src/search/adapters/typesense.ts +14 -4
- package/src/search/build.ts +21 -3
- package/src/search/documents.ts +26 -2
- package/src/search/orama-index.ts +191 -34
- package/src/search/pagefind-ranking.ts +39 -0
- package/src/search/source-pages.ts +29 -0
- package/src/search/sync/algolia.ts +111 -10
- package/src/search/sync/index.ts +52 -13
- package/src/search/sync/orama-cloud.ts +3 -0
- package/src/search/sync/typesense.ts +76 -26
- package/src/seo/metatags.ts +67 -0
- package/src/sources/contentful.ts +12 -0
- package/src/sources/github-releases.ts +7 -1
- package/src/sources/shared.ts +3 -0
- package/src/theme/chrome-icons.ts +1 -0
- package/src/theme/color.ts +500 -0
- package/src/theme/entry.ts +85 -6
- package/src/theme/palette.ts +121 -45
- package/src/translate/prompts.ts +1 -0
- package/src/translate/validate.ts +31 -3
- package/src/upgrade/upgrade.ts +4 -171
- package/dist/cli/chunk-1d7ve1dm.js.map +0 -12
- package/dist/cli/chunk-2hsdwb9n.js.map +0 -10
- package/dist/cli/chunk-35d4wj9f.js.map +0 -15
- package/dist/cli/chunk-364znk6q.js +0 -75
- package/dist/cli/chunk-364znk6q.js.map +0 -11
- package/dist/cli/chunk-5m5nmvyq.js.map +0 -13
- package/dist/cli/chunk-8ktnccpt.js.map +0 -10
- package/dist/cli/chunk-9t7a85s3.js.map +0 -10
- package/dist/cli/chunk-b07cmahc.js +0 -145
- package/dist/cli/chunk-b07cmahc.js.map +0 -11
- package/dist/cli/chunk-c8chx29p.js.map +0 -36
- package/dist/cli/chunk-e04dxsz1.js +0 -39
- package/dist/cli/chunk-e04dxsz1.js.map +0 -10
- package/dist/cli/chunk-j85vccga.js.map +0 -36
- package/dist/cli/chunk-p3v96n38.js.map +0 -10
- package/dist/cli/chunk-pehfxfta.js.map +0 -10
- package/dist/cli/chunk-pv29h0wf.js.map +0 -190
- package/dist/cli/chunk-q58y5e6a.js.map +0 -10
- package/dist/cli/chunk-vg9r4eb9.js.map +0 -14
- package/dist/cli/chunk-wrr3j9w9.js.map +0 -35
- package/dist/cli/chunk-yfyb25rh.js.map +0 -14
- package/docs/content/sources.mdx +0 -334
- /package/dist/cli/{chunk-tkacnehg.js.map → chunk-3v3ffbrj.js.map} +0 -0
- /package/dist/cli/{chunk-r9rcc4w7.js.map → chunk-8y2kmjv8.js.map} +0 -0
- /package/dist/cli/{chunk-2eytanqx.js.map → chunk-c887fj0s.js.map} +0 -0
- /package/dist/cli/{chunk-akbpwfxc.js.map → chunk-dzwehpy7.js.map} +0 -0
- /package/dist/cli/{chunk-2z928egk.js.map → chunk-ft9vfys6.js.map} +0 -0
- /package/dist/cli/{chunk-a58773jm.js.map → chunk-kma9f6sf.js.map} +0 -0
- /package/dist/cli/{chunk-crgn1q09.js.map → chunk-sds923fa.js.map} +0 -0
- /package/dist/cli/{chunk-acanzt5p.js.map → chunk-tdqhyxfz.js.map} +0 -0
|
@@ -89,6 +89,36 @@ The active tab is written to the URL hash, so a link opens on it; pass `hash={fa
|
|
|
89
89
|
</Tabs>
|
|
90
90
|
```
|
|
91
91
|
|
|
92
|
+
## View
|
|
93
|
+
|
|
94
|
+
Write one page for several audiences, such as readers of different programming languages or frameworks, with `<View>` blocks. Each distinct `title` becomes an option in a picker above the page's content, and only the chosen view's blocks show. The table of contents follows: headings inside hidden views drop out of it. Prose outside any `<View>` shows in every view, and blocks sharing a title show and hide together, so a page can alternate shared and view-specific sections. `icon` shows beside the view's name in the picker.
|
|
95
|
+
|
|
96
|
+
````mdx lineNumbers
|
|
97
|
+
Everyone reads this paragraph.
|
|
98
|
+
|
|
99
|
+
<View title="JavaScript" icon="braces">
|
|
100
|
+
|
|
101
|
+
## Install the client
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
npm install @acme/commerce
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
</View>
|
|
108
|
+
|
|
109
|
+
<View title="Python" icon="terminal">
|
|
110
|
+
|
|
111
|
+
## Install the client
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
pip install acme-commerce
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
</View>
|
|
118
|
+
````
|
|
119
|
+
|
|
120
|
+
The first view shows until the reader picks another. Blume remembers that pick across pages written in views, and writes it to the URL as `?view=Python`, so a link opens on the same view. A link to a heading inside a view opens that view. Use `<View>` when most of the page changes with the choice, and [Tabs](#tabs) when only one part of the page does. The agent-facing Markdown includes every view, each under its name.
|
|
121
|
+
|
|
92
122
|
## Badge
|
|
93
123
|
|
|
94
124
|
A small inline label for status or metadata — version tags, “new” or “beta” markers, stability levels. The `variant` tunes the color to the meaning.
|
|
@@ -514,7 +544,7 @@ A **Prop / Type** grid where each row expands to reveal its description and deta
|
|
|
514
544
|
|
|
515
545
|
### Auto type table
|
|
516
546
|
|
|
517
|
-
Generate a type table from a TypeScript type so the docs stay in sync with the source. Point `AutoTypeTable` at a file with `path` (resolved from your project root) and a type `name`. Descriptions come from JSDoc comments, defaults from `@default` tags, and optional properties (`?`) are marked accordingly.
|
|
547
|
+
Generate a type table from a TypeScript type so the docs stay in sync with the source. Point `AutoTypeTable` at a file with `path` (resolved from your project root, the folder you run `blume` in) and a type `name`. Descriptions come from JSDoc comments, defaults from `@default` tags, and optional properties (`?`) are marked accordingly.
|
|
518
548
|
|
|
519
549
|
```astro
|
|
520
550
|
<AutoTypeTable path="./src/button.ts" name="ButtonProps" />
|
|
@@ -558,6 +588,82 @@ export interface ButtonProps {
|
|
|
558
588
|
/>
|
|
559
589
|
```
|
|
560
590
|
|
|
591
|
+
## API fields
|
|
592
|
+
|
|
593
|
+
Rows for documenting an endpoint by hand, one field at a time, styled like the generated [OpenAPI reference](/docs/references/openapi). `ParamField` is a request parameter, named by the attribute that says where it goes: `path`, `query`, `header`, or `body`. `ResponseField` is a field of the response, named by `name`. Both take a `type`, `required`, `deprecated`, and a `default`, with the description as their content; `ResponseField` also takes `pre` and `post` labels around the name.
|
|
594
|
+
|
|
595
|
+
<ParamField path="userId" type="string" required>
|
|
596
|
+
The user's ID.
|
|
597
|
+
</ParamField>
|
|
598
|
+
|
|
599
|
+
<ParamField query="limit" type="integer" default={20}>
|
|
600
|
+
How many results to return, up to 100.
|
|
601
|
+
</ParamField>
|
|
602
|
+
|
|
603
|
+
<ResponseField name="plan" type="string" post={["beta"]}>
|
|
604
|
+
The user's plan.
|
|
605
|
+
</ResponseField>
|
|
606
|
+
|
|
607
|
+
```mdx lineNumbers
|
|
608
|
+
<ParamField path="userId" type="string" required>
|
|
609
|
+
The user's ID.
|
|
610
|
+
</ParamField>
|
|
611
|
+
|
|
612
|
+
<ParamField query="limit" type="integer" default={20}>
|
|
613
|
+
How many results to return, up to 100.
|
|
614
|
+
</ParamField>
|
|
615
|
+
|
|
616
|
+
<ResponseField name="plan" type="string" post={["beta"]}>
|
|
617
|
+
The user's plan.
|
|
618
|
+
</ResponseField>
|
|
619
|
+
```
|
|
620
|
+
|
|
621
|
+
Nest an object's fields inside its description with an [`Expandable`](#expandable):
|
|
622
|
+
|
|
623
|
+
```mdx lineNumbers
|
|
624
|
+
<ResponseField name="address" type="object">
|
|
625
|
+
Where the order ships.
|
|
626
|
+
|
|
627
|
+
<Expandable title="properties">
|
|
628
|
+
<ResponseField name="city" type="string" required>
|
|
629
|
+
City name.
|
|
630
|
+
</ResponseField>
|
|
631
|
+
</Expandable>
|
|
632
|
+
</ResponseField>
|
|
633
|
+
```
|
|
634
|
+
|
|
635
|
+
On a page with `api` frontmatter, the `ParamField`s also build the page's Try it panel and request samples: see [Hand-written API pages](/docs/references/api-pages). The fields use the same names and props as Mintlify's, so pages written for it render as they are. The Markdown copy of the page lists each field with its type and flags.
|
|
636
|
+
|
|
637
|
+
### Request and response examples
|
|
638
|
+
|
|
639
|
+
`RequestExample` and `ResponseExample` hold code blocks, one tab per titled fence (`dropdown` switches to a language menu, as on [`CodeGroup`](#codegroup)). On a wide screen they pin to a column beside the page, the request above the response, and stay in view as the reader scrolls the fields, the way an OpenAPI operation's examples do; the page drops its table of contents to make room. On a narrow screen they follow the page's content.
|
|
640
|
+
|
|
641
|
+
````mdx lineNumbers
|
|
642
|
+
<RequestExample>
|
|
643
|
+
|
|
644
|
+
```bash cURL
|
|
645
|
+
curl --request POST https://api.acme.dev/v1/users \
|
|
646
|
+
--header "Authorization: Bearer $ACME_TOKEN" \
|
|
647
|
+
--data '{ "email": "ada@example.com" }'
|
|
648
|
+
```
|
|
649
|
+
|
|
650
|
+
```ts title="Acme SDK"
|
|
651
|
+
await acme.users.create({ email: "ada@example.com" });
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
</RequestExample>
|
|
655
|
+
|
|
656
|
+
<ResponseExample>
|
|
657
|
+
|
|
658
|
+
```json 201
|
|
659
|
+
{ "id": "usr_8f2k", "status": "invited" }
|
|
660
|
+
```
|
|
661
|
+
|
|
662
|
+
</ResponseExample>
|
|
663
|
+
````
|
|
664
|
+
|
|
665
|
+
Write them anywhere at the top level of the page; each moves to the column. One nested inside another component, such as a `Tab`, stays where it is written.
|
|
666
|
+
|
|
561
667
|
## GitHub info
|
|
562
668
|
|
|
563
669
|
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.
|
|
@@ -579,7 +685,7 @@ The card reads the instance from [`github.host`](/docs/configuration#github-ente
|
|
|
579
685
|
|
|
580
686
|
## Component
|
|
581
687
|
|
|
582
|
-
`Component` renders an example file from your project's `examples/` directory as a live preview alongside its highlighted source, in tabs. Point it at a file with `path` — its location under `examples/`, without the extension (so `examples/counter.tsx` is `path="counter"`). React, Vue, Svelte, and Astro examples are all supported; framework examples hydrate, Astro ones render statically. It keeps the preview and the code in sync from a single file.
|
|
688
|
+
`Component` renders an example file from your project's `examples/` directory as a live preview alongside its highlighted source, in tabs. Point it at a file with `path` — its location under `examples/`, without the extension (so `examples/counter.tsx` is `path="counter"`). React, Vue, Svelte, and Astro examples are all supported; framework examples hydrate, Astro ones render statically. It keeps the preview and the code in sync from a single file. A `path` that names no example renders a "No example found" box instead, and `blume dev`, `blume build`, and [`blume doctor`](/docs/cli/doctor) warn about it (`BLUME_EXAMPLE_NOT_FOUND`) at its line.
|
|
583
689
|
|
|
584
690
|
The preview renders in an isolated frame that the docs styles never reach — no prose margins, typography, or theme chrome bleed into your component. The frame gets Tailwind (preflight + utilities scanned from your project and your examples directory), Blume's design tokens so classes like `bg-background` follow the site palette by default, and it follows the site's light/dark toggle live. The pane sizes itself to the rendered example — and keeps tracking it if the example grows or shrinks after load — with the Preview and Code tabs sharing one height so toggling them never shifts the page.
|
|
585
691
|
|
|
@@ -5,6 +5,8 @@ description: Every frontmatter field a page accepts, all optional — title, des
|
|
|
5
5
|
|
|
6
6
|
Every page accepts the following frontmatter. All fields are optional.
|
|
7
7
|
|
|
8
|
+
Frontmatter is YAML, so quote a value that holds a colon followed by a space, like `description: "Setup: the easy way"`. Unquoted, YAML reads the second colon as the start of a nested key, and Blume reports the file and line as `BLUME_FRONTMATTER_INVALID`.
|
|
9
|
+
|
|
8
10
|
<TypeTable
|
|
9
11
|
type={{
|
|
10
12
|
title: { type: "string", description: "Page title." },
|
|
@@ -49,6 +51,23 @@ Every page accepts the following frontmatter. All fields are optional.
|
|
|
49
51
|
default: "false",
|
|
50
52
|
description: "Shorthand for seo.noindex.",
|
|
51
53
|
},
|
|
54
|
+
narration: {
|
|
55
|
+
type: "boolean",
|
|
56
|
+
default: "true",
|
|
57
|
+
description:
|
|
58
|
+
"Set to false to leave this page without the Listen to this page player when narration is on.",
|
|
59
|
+
},
|
|
60
|
+
related: {
|
|
61
|
+
type: "(string | { [title]: string })[] | false",
|
|
62
|
+
description:
|
|
63
|
+
"Pages to suggest at the foot of this one, up to ten: root-relative paths, absolute URLs, or { Title: link } to name a link. See Related pages below.",
|
|
64
|
+
},
|
|
65
|
+
pagination: {
|
|
66
|
+
type: "boolean",
|
|
67
|
+
default: "true",
|
|
68
|
+
description:
|
|
69
|
+
"Set to false to drop the previous and next links at the foot of the page. The page stays in the order, so its neighbors still link to it.",
|
|
70
|
+
},
|
|
52
71
|
icon: {
|
|
53
72
|
type: "string",
|
|
54
73
|
description:
|
|
@@ -59,9 +78,64 @@ Every page accepts the following frontmatter. All fields are optional.
|
|
|
59
78
|
description:
|
|
60
79
|
'Pin the page\'s "last updated" date (ISO or YAML date); overrides the git-derived date.',
|
|
61
80
|
},
|
|
81
|
+
mode: {
|
|
82
|
+
type: '"default" | "wide" | "center" | "custom" | "frame"',
|
|
83
|
+
default: '"default"',
|
|
84
|
+
description: "What the page shows around its content. See Layout below.",
|
|
85
|
+
},
|
|
86
|
+
api: {
|
|
87
|
+
type: "string",
|
|
88
|
+
description:
|
|
89
|
+
"An endpoint this page documents by hand, as an HTTP method and a path or URL (POST /v1/users). See Hand-written API pages.",
|
|
90
|
+
},
|
|
91
|
+
authMethod: {
|
|
92
|
+
type: '"bearer" | "basic" | "key" | "none"',
|
|
93
|
+
description:
|
|
94
|
+
"How an api page's endpoint authenticates, over the site's api.auth.",
|
|
95
|
+
},
|
|
96
|
+
playground: {
|
|
97
|
+
type: '"interactive" | "simple" | "none"',
|
|
98
|
+
default: '"interactive"',
|
|
99
|
+
description:
|
|
100
|
+
"What an api page shows: the Try it panel and samples, the samples only, or neither.",
|
|
101
|
+
},
|
|
62
102
|
}}
|
|
63
103
|
/>
|
|
64
104
|
|
|
105
|
+
## Layout
|
|
106
|
+
|
|
107
|
+
`mode` sets what a page shows around its content:
|
|
108
|
+
|
|
109
|
+
| Mode | Sidebar | Title and table of contents | Page-end links and footer | Content width |
|
|
110
|
+
| --- | --- | --- | --- | --- |
|
|
111
|
+
| `default` | Yes | Yes | Yes | The prose measure |
|
|
112
|
+
| `wide` | Yes | Title only | Yes | The whole column |
|
|
113
|
+
| `center` | No | Title only | Yes | A wider column, centered |
|
|
114
|
+
| `frame` | Yes | No | No | The whole column |
|
|
115
|
+
| `custom` | No | No | No | The whole page |
|
|
116
|
+
|
|
117
|
+
`wide` suits a page of wide tables or diagrams, and `center` release notes or an announcement read top to bottom. `custom` keeps only the header, for a landing page written in MDX, and `frame` keeps the sidebar too, for a tool or dashboard that sits in the docs' navigation. Neither renders the page's title or description, so write your own heading. Every mode stays in search and keeps its Markdown copy.
|
|
118
|
+
|
|
119
|
+
```yaml lineNumbers
|
|
120
|
+
title: Welcome
|
|
121
|
+
mode: custom
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
The values match Mintlify's; its `assistant` mode, a full-page chat, has no equivalent.
|
|
125
|
+
|
|
126
|
+
## Related pages
|
|
127
|
+
|
|
128
|
+
`related` lists pages to suggest at the foot of this one, as cards under a **Related pages** heading:
|
|
129
|
+
|
|
130
|
+
```yaml lineNumbers
|
|
131
|
+
related:
|
|
132
|
+
- /guides/deployment
|
|
133
|
+
- Search setup: /configuration/search
|
|
134
|
+
- https://astro.build
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
A root-relative path names another page, which the card shows with that page's title and description; on a translated page it links to the translation when there is one. A `Title: link` entry sets the card's title itself, and an absolute URL links off the site under its host name. Paths are checked like any link on the page, so [`blume validate`](/docs/cli/validate) reports one that matches no page. The key matches Mintlify's, so migrated pages keep it as written.
|
|
138
|
+
|
|
65
139
|
## Sidebar
|
|
66
140
|
|
|
67
141
|
```yaml lineNumbers
|
|
@@ -91,7 +165,7 @@ seo:
|
|
|
91
165
|
creator: "@jane"
|
|
92
166
|
```
|
|
93
167
|
|
|
94
|
-
`noindex` emits a robots `noindex`, drops the page from the sitemap, and skips its structured data. `x.creator` credits the page to an X account (`twitter:creator`) — a guest post's author, say. See [Metadata](/docs/discoverability/metadata#per-page-overrides) for every field.
|
|
168
|
+
`noindex` emits a robots `noindex`, drops the page from the sitemap, and skips its structured data. A `canonical` that names another URL drops the page from the sitemap too, since the sitemap lists canonical URLs only. `x.creator` credits the page to an X account (`twitter:creator`) — a guest post's author, say. See [Metadata](/docs/discoverability/metadata#per-page-overrides) for every field.
|
|
95
169
|
|
|
96
170
|
## Search
|
|
97
171
|
|
|
@@ -99,8 +173,12 @@ seo:
|
|
|
99
173
|
search:
|
|
100
174
|
exclude: false
|
|
101
175
|
tags: [api]
|
|
176
|
+
keywords: [install, setup]
|
|
177
|
+
boost: 3
|
|
102
178
|
```
|
|
103
179
|
|
|
180
|
+
`exclude` keeps the page out of search, and `tags` labels its record for a hosted search adapter to filter on (see [Tags](/docs/configuration/search#tags)). `keywords` are extra terms the page is found by, beyond its own text. `boost` multiplies the page's relevance: above 1 ranks it higher, below 1 lower. See [Ranking](/docs/configuration/search#ranking).
|
|
181
|
+
|
|
104
182
|
## AI
|
|
105
183
|
|
|
106
184
|
```yaml lineNumbers
|
|
@@ -108,7 +186,7 @@ ai:
|
|
|
108
186
|
exclude: true
|
|
109
187
|
```
|
|
110
188
|
|
|
111
|
-
`ai.exclude` keeps the page out of [`llms.txt` and `llms-full.txt`](/docs/discoverability/llms-txt#excluding-a-page). The page still renders, stays in search, and keeps its place in the sitemap.
|
|
189
|
+
`ai.exclude` keeps the page out of [`llms.txt` and `llms-full.txt`](/docs/discoverability/llms-txt#excluding-a-page) and out of the page map in your [site's skill](/docs/discoverability/agent-discovery#your-sites-skill). The page still renders, stays in search, the [MCP server](/docs/discoverability/mcp), and the [JSON API](/docs/discoverability/json-api), and keeps its place in the sitemap.
|
|
112
190
|
|
|
113
191
|
## Changelog
|
|
114
192
|
|
package/docs/content/i18n.mdx
CHANGED
|
@@ -85,7 +85,23 @@ i18n: {
|
|
|
85
85
|
|
|
86
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.
|
|
87
87
|
|
|
88
|
-
Header tabs are configured, not derived from content, so their labels localize in `blume.config.ts
|
|
88
|
+
Header tabs, header links, and the footer are configured, not derived from content, so their labels localize in `blume.config.ts`. Every configured 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: tab and dropdown labels ([Tabs](/docs/content/navigation#tabs)), [featured links](/docs/content/navigation#featured-links), [header actions](/docs/content/navigation#header-actions) and the call to action, [footer](/docs/configuration#footer) links, and the [banner](/docs/configuration#banner)'s text and link text.
|
|
89
|
+
|
|
90
|
+
```ts blume.config.ts lineNumbers
|
|
91
|
+
navigation: {
|
|
92
|
+
cta: {
|
|
93
|
+
href: "https://acme.dev/signup",
|
|
94
|
+
label: { en: "Start free", fr: "Essai gratuit" },
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
footer: {
|
|
98
|
+
links: [
|
|
99
|
+
{ label: { en: "Pricing", fr: "Tarifs" }, href: "https://acme.dev/pricing" },
|
|
100
|
+
],
|
|
101
|
+
},
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Tab paths, header and footer links, and the header logo's link move into the reader's locale too, whenever that locale serves the route, so the chrome 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.
|
|
89
105
|
|
|
90
106
|
## Fallbacks
|
|
91
107
|
|
|
@@ -100,7 +116,7 @@ i18n: {
|
|
|
100
116
|
|
|
101
117
|
Fallback pages point their canonical link at the page they copy, are left out of the search index, `llms.txt`, and the MCP and JSON API page lists, and aren't advertised as real translations in `hreflang`, so untranslated content doesn't compete for ranking. They still appear in that locale's sidebar, so navigation stays complete — a reader can reach every page in any language.
|
|
102
118
|
|
|
103
|
-
Release notes from a [`githubReleases()`](/docs/content/sources
|
|
119
|
+
Release notes from a [`githubReleases()`](/docs/content/sources/github-releases) source are the exception: they're published in one language, so they're never copied to other locales' URLs and show no language switcher.
|
|
104
120
|
|
|
105
121
|
:::tip
|
|
106
122
|
Start by translating your most important pages — the homepage, quickstart, and top guides — and let the rest fall back. You can fill in translations over time without breaking any links.
|
|
@@ -124,7 +140,26 @@ Blume validates each result's structure — frontmatter, code fences, links —
|
|
|
124
140
|
|
|
125
141
|
## The language switcher
|
|
126
142
|
|
|
127
|
-
When i18n is on, a language switcher appears in the header automatically, generated from your `locales`. For each page it links the matching translation in every language; where a translation is missing it links the fallback page and marks it as not translated. There's nothing to configure. Pages from a [GitHub Releases](/docs/content/sources
|
|
143
|
+
When i18n is on, a language switcher appears in the header automatically, generated from your `locales`. For each page it links the matching translation in every language; where a translation is missing it links the fallback page and marks it as not translated. With fallbacks off (`fallbackLocale: null`) there's no page to link, so the switcher leaves that language out. There's nothing to configure. Pages from a [GitHub Releases](/docs/content/sources/github-releases) source are the exception: release notes exist in one language only, so those pages render without a switcher.
|
|
144
|
+
|
|
145
|
+
## Routing by browser language
|
|
146
|
+
|
|
147
|
+
To send visitors to their own language, turn on `routeByBrowserLanguage`:
|
|
148
|
+
|
|
149
|
+
```ts blume.config.ts lineNumbers
|
|
150
|
+
i18n: {
|
|
151
|
+
defaultLocale: "en",
|
|
152
|
+
locales: [
|
|
153
|
+
{ code: "en", label: "English" },
|
|
154
|
+
{ code: "fr", label: "Français" },
|
|
155
|
+
],
|
|
156
|
+
routeByBrowserLanguage: true,
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
A visitor who lands on the default language's home page from outside the site then goes to the home page in their browser's preferred language, when the site has it. Blume tries each language the browser prefers, in order, matching an exact code first and then the base language (`fr-CA` finds `fr`). If the default language comes first, the visitor stays. Once a reader picks a language with the switcher, Blume remembers the pick and stops routing them. Only the home page routes; a link to any other page opens as written.
|
|
161
|
+
|
|
162
|
+
The redirect runs in the browser before the page paints, so it works on any host, static builds included. It's off by default because search engines crawl in one language: with it on, keep the [`hreflang` alternates](#seo) Blume emits so each language's pages are still indexed.
|
|
128
163
|
|
|
129
164
|
## Translated UI
|
|
130
165
|
|
|
@@ -158,7 +193,7 @@ Set [`deployment.site`](/docs/deployment) so these can be emitted as absolute UR
|
|
|
158
193
|
|
|
159
194
|
## Search
|
|
160
195
|
|
|
161
|
-
Search is scoped to the active language: on a `/fr/…` page the dialog returns French results, with an **All languages** toggle to search across every locale at once. The default (Orama) and FlexSearch indexes filter in the browser
|
|
196
|
+
Search is scoped to the active language: on a `/fr/…` page the dialog returns French results, with an **All languages** toggle to search across every locale at once. The default (Orama) and FlexSearch indexes filter in the browser, Pagefind keeps an index per language, and Algolia, Orama Cloud, and Typesense carry a `locale` field on each record. Mixedbread can't scope by language, so with it every search spans every locale and the dialog has no toggle. See [Search](/docs/configuration/search) for how each adapter handles it.
|
|
162
197
|
|
|
163
198
|
## Right-to-left
|
|
164
199
|
|
|
@@ -41,6 +41,22 @@ Relative image references inside a partial keep working: they're rebased onto th
|
|
|
41
41
|
|
|
42
42
|
Editing a partial while `blume dev` is running reloads every page that includes it.
|
|
43
43
|
|
|
44
|
+
## Props
|
|
45
|
+
|
|
46
|
+
Pass values into a partial as attributes, and read them in the partial with `{{name}}`, the same syntax as [variables](/docs/content/variables). One partial then serves every page that needs a variation of it:
|
|
47
|
+
|
|
48
|
+
```mdx docs/_snippets/upgrade.mdx
|
|
49
|
+
Upgrade to the **{{plan}}** plan to use {{feature}}.
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
```mdx docs/sso.mdx
|
|
53
|
+
<include plan="Enterprise" feature="SSO">
|
|
54
|
+
./_snippets/upgrade.mdx
|
|
55
|
+
</include>
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
A prop applies to the included file and to anything it includes in turn, and takes precedence over a site-wide variable with the same name. Every attribute except `lang` and `meta` is a prop; attribute names are lowercase, and values are quoted plain text. Props reach Markdown and MDX partials only: a `{{name}}` in an included [code file](#including-code-files) isn't replaced by a prop.
|
|
59
|
+
|
|
44
60
|
## Including code files
|
|
45
61
|
|
|
46
62
|
A target that isn't `.md`/`.mdx` is embedded as a fenced code block, with the language inferred from the extension. Use `lang` to override the language (or to show a Markdown file as source rather than splicing it), and `meta` to pass a fence meta string such as a title:
|
package/docs/content/meta.mdx
CHANGED
|
@@ -34,6 +34,7 @@ Blume only reads `meta.ts` files from folders your content covers: one under a f
|
|
|
34
34
|
| `order` | `number` | Position among sibling groups and pages. Lower numbers sort first. |
|
|
35
35
|
| `collapsed` | `boolean` | Under the [`group` display mode](/docs/content/navigation#display-modes), whether the group starts collapsed. |
|
|
36
36
|
| `display` | `"flat" \| "group" \| "page"` | Render mode for this group; overrides the global [`navigation.sidebar.display`](/docs/content/navigation#display-modes). |
|
|
37
|
+
| `directory` | `"card" \| "accordion" \| "none"` | List the group's pages below its `index` page's content. Nested folders inherit it. See [directory listings](/docs/content/navigation#directory-listings). |
|
|
37
38
|
| `pages` | `string[]` | Explicit order for the group's children, by slug. |
|
|
38
39
|
|
|
39
40
|
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.
|
package/docs/content/meta.ts
CHANGED
|
@@ -106,6 +106,24 @@ A group's `display` applies to that group only — nested subgroups resolve thei
|
|
|
106
106
|
|
|
107
107
|
A group in an [explicit sidebar](#explicit-sidebar) overrides the global mode with its own `display`, exactly as before.
|
|
108
108
|
|
|
109
|
+
## Directory listings
|
|
110
|
+
|
|
111
|
+
A group's own page can list the group's other pages below its content, so a section's landing page doubles as its table of contents. Set `directory` in the folder's [`meta.ts`](/docs/content/meta):
|
|
112
|
+
|
|
113
|
+
```ts guides/meta.ts lineNumbers
|
|
114
|
+
import { defineMeta } from "blume";
|
|
115
|
+
|
|
116
|
+
export default defineMeta({
|
|
117
|
+
directory: "card",
|
|
118
|
+
});
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
- **`card`** shows each page and subgroup as a card with its icon and description.
|
|
122
|
+
- **`accordion`** lists the pages as rows, and each subgroup as a section that opens to its pages.
|
|
123
|
+
- **`none`** lists nothing. This is the default.
|
|
124
|
+
|
|
125
|
+
Only a group with its own page has somewhere to show the listing: a folder's `index` page, or an explicit group's `root`. The setting carries down to nested folders, so one `directory` on the content root's `meta.ts` gives every section a listing, and a folder can set its own value (`none` included) to override what it inherits. An [explicit sidebar](#explicit-sidebar) sets `directory` on its groups the same way.
|
|
126
|
+
|
|
109
127
|
## Ordering
|
|
110
128
|
|
|
111
129
|
When the sidebar is generated, order is resolved highest priority first:
|
|
@@ -234,6 +252,8 @@ Each item takes a `label`, a `path`, and optional `icon`, `description`, and `ta
|
|
|
234
252
|
|
|
235
253
|
With [versioning](/docs/content/versioning) configured, Blume renders a version selector automatically — declaring your own `kind: "version"` selector here replaces the automatic one, so hand-rolled setups keep working.
|
|
236
254
|
|
|
255
|
+
On screens narrower than the desktop sidebar, selectors, the version selector, and the [language switcher](/docs/content/i18n#the-language-switcher) move out of the header and into the top of the mobile navigation drawer, where each spans the drawer's width.
|
|
256
|
+
|
|
237
257
|
## Featured links
|
|
238
258
|
|
|
239
259
|
Pin links to the top of the sidebar, above every section — a blog, a changelog, a contact or support page that should always be one click away. Unlike the generated tree, featured links are **not scoped by tab**: they show on every route, on every breakpoint.
|
|
@@ -247,7 +267,7 @@ navigation: {
|
|
|
247
267
|
}
|
|
248
268
|
```
|
|
249
269
|
|
|
250
|
-
Each link takes a `label`, an `href`, and an optional `icon` (a [built-in icon](/docs/content/components#icon) name, image path/URL, or inline SVG — the same as anywhere else). An `href` may point anywhere: an external URL opens in a new tab, while an internal route (`/contact`) is validated against your pages at build time, warning you if nothing matches.
|
|
270
|
+
Each link takes a `label`, an `href`, and an optional `icon` (a [built-in icon](/docs/content/components#icon) name, image path/URL, or inline SVG — the same as anywhere else). An `href` may point anywhere: an external URL opens in a new tab, while an internal route (`/contact`) is validated against your pages at build time and by [`blume doctor`](/docs/cli/doctor), warning you if nothing matches.
|
|
251
271
|
|
|
252
272
|
## Explicit sidebar
|
|
253
273
|
|
|
@@ -267,7 +287,7 @@ navigation: {
|
|
|
267
287
|
}
|
|
268
288
|
```
|
|
269
289
|
|
|
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
|
|
290
|
+
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), start `collapsed`, and link a `root` page, which can list the group's pages with a [`directory`](#directory-listings).
|
|
271
291
|
|
|
272
292
|
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
293
|
|
|
@@ -282,23 +302,25 @@ navigation: {
|
|
|
282
302
|
}
|
|
283
303
|
```
|
|
284
304
|
|
|
305
|
+
Like tab labels, a `label` here can be a map of locale code to text on a [multilingual](/docs/content/i18n#per-locale-navigation) site.
|
|
306
|
+
|
|
285
307
|
`cta` is singular on purpose — a docs header has room for exactly one thing a reader is being asked to do, and a row of buttons asks for nothing. Secondary links belong in `actions`, or in [`featured`](#featured-links) if they should sit with the sidebar instead.
|
|
286
308
|
|
|
287
309
|
An `http(s)` or protocol-relative href opens in a new tab; a route stays in the tab, and is validated against your pages at build time like a `featured` link — so a page served by another app on the same host (`/signup` on the product, say) should be written as an absolute URL. `actions` are hidden below the `sm` breakpoint, where the header has room for the logo and the navigation toggle and nothing else. `cta` hides there too, except on a page with no navigation toggle — a landing page on `PageLayout` with no tabs — where it stays, since nothing else can surface it on a phone.
|
|
288
310
|
|
|
289
311
|
## Repository link
|
|
290
312
|
|
|
291
|
-
When you set [`github`](/docs/configuration) in your config, Blume shows a GitHub icon in the
|
|
313
|
+
When you set [`github`](/docs/configuration) in your config, Blume shows a GitHub icon in the [footer](/docs/configuration#footer), ahead of your social profiles, that links to your repository. It's on by default; hide it with `navigation.repo`:
|
|
292
314
|
|
|
293
315
|
```ts blume.config.ts lineNumbers
|
|
294
316
|
navigation: {
|
|
295
|
-
repo: false, // hide the
|
|
317
|
+
repo: false, // hide the footer's GitHub link (default: true)
|
|
296
318
|
}
|
|
297
319
|
```
|
|
298
320
|
|
|
299
321
|
The link only appears when `github` is configured, so projects without a repo are unaffected either way.
|
|
300
322
|
|
|
301
|
-
`repo` also takes an absolute URL, which points the
|
|
323
|
+
`repo` also takes an absolute URL, which points the GitHub mark anywhere on GitHub:
|
|
302
324
|
|
|
303
325
|
```ts blume.config.ts lineNumbers
|
|
304
326
|
navigation: {
|
|
@@ -306,25 +328,25 @@ navigation: {
|
|
|
306
328
|
}
|
|
307
329
|
```
|
|
308
330
|
|
|
309
|
-
That's for a project whose docs repo is private. `github` drives the per-page edit link, the
|
|
331
|
+
That's for a project whose docs repo is private. `github` drives the per-page edit link, the GitHub mark and the [agent manifest](/docs/discoverability/agent-discovery)'s repository together, so such a project has to leave `github` unset — and a URL is what lets it still show a mark pointing somewhere public. A `footer.socials.github` URL takes the mark's place, and a link to another host belongs in the footer's `links` or [`actions`](#header-actions).
|
|
310
332
|
|
|
311
333
|
## Breadcrumbs and pagination
|
|
312
334
|
|
|
313
335
|
These come for free from the sidebar tree — no configuration:
|
|
314
336
|
|
|
315
337
|
- **Breadcrumbs** show the current page's parent group above the title.
|
|
316
|
-
- **Previous and next** links at the foot of each page follow sidebar order, skipping hidden pages.
|
|
338
|
+
- **Previous and next** links at the foot of each page follow sidebar order, skipping hidden pages. Set [`pagination: false`](/docs/content/frontmatter) in a page's frontmatter to leave them off that page.
|
|
317
339
|
|
|
318
340
|
## On this page
|
|
319
341
|
|
|
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.
|
|
342
|
+
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, which also holds the [page actions](#page-actions).
|
|
321
343
|
|
|
322
344
|
## Page actions
|
|
323
345
|
|
|
324
|
-
Below the table of contents, every page shows a set of quick actions:
|
|
346
|
+
Below the table of contents, every page shows a set of quick actions. In windows at least 1,280px wide they sit in the right-hand column with the outline. In narrower windows and on phones they sit at the bottom of the “On this page” dropdown above the content, which shows on a page with no headings too:
|
|
325
347
|
|
|
326
348
|
- **Edit on GitHub** — links straight to the source file. Appears once you set [`github`](/docs/configuration) in your config.
|
|
327
|
-
- **Scroll to top** — smoothly returns to the top of long pages.
|
|
349
|
+
- **Scroll to top** — smoothly returns to the top of long pages. It's in the right-hand column only, since the dropdown already sits at the top of the page.
|
|
328
350
|
|
|
329
351
|
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
352
|
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Contentful
|
|
3
|
+
description: Read a Contentful content type through the Delivery API with the contentful() source, lowering rich text bodies to Markdown with nothing to install.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
The built-in `contentful()` adapter reads the entries of one content type through the Content Delivery API and lowers each entry's rich text body to Markdown: headings, marks, links, lists, quotes, and tables map to their Markdown equivalents, an embedded image asset to an image, and any other embedded file (a PDF, say) to a link to it. A body held in a Markdown long-text field passes through as written, except that a link that isn't a web, mail, phone, or relative address (a `javascript:` URL, say) keeps only its label, as it does in rich text. Nothing to install — the adapter speaks the REST API directly.
|
|
7
|
+
|
|
8
|
+
```ts blume.config.ts
|
|
9
|
+
import { defineConfig } from "blume";
|
|
10
|
+
import { contentful, filesystem } from "blume/sources";
|
|
11
|
+
|
|
12
|
+
export default defineConfig({
|
|
13
|
+
content: {
|
|
14
|
+
sources: [
|
|
15
|
+
filesystem({ root: "docs" }),
|
|
16
|
+
contentful({
|
|
17
|
+
prefix: "guides",
|
|
18
|
+
space: "abc123",
|
|
19
|
+
contentType: "guide",
|
|
20
|
+
// environment: "master", locale: "en-US"
|
|
21
|
+
// Field ids default to title / description / slug / body, and the
|
|
22
|
+
// date to sys.updatedAt; order (no default) sets the sidebar order
|
|
23
|
+
fields: { body: "content", order: "position" },
|
|
24
|
+
// Extra Delivery API query parameters
|
|
25
|
+
params: { "fields.section": "sdk" },
|
|
26
|
+
// A space with EU data residency:
|
|
27
|
+
// host: "cdn.eu.contentful.com",
|
|
28
|
+
// previewHost: "preview.eu.contentful.com",
|
|
29
|
+
}),
|
|
30
|
+
],
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
The Delivery API token comes from the `CONTENTFUL_ACCESS_TOKEN` environment variable, which the adapter declares. Without it, the source stops before its first request with a `BLUME_MISSING_SECRET` error rather than Contentful's `401`, unless it has a [cached snapshot](/docs/content/sources#caching-and-offline-builds) to serve instead. Under `--preview` the adapter reads drafts through the Preview API with `CONTENTFUL_PREVIEW_TOKEN`. The Preview API rejects delivery tokens, so `--preview` without a preview token fails with a clear error rather than falling back to `CONTENTFUL_ACCESS_TOKEN`. A space with EU data residency is served from other hosts: set `host` to `cdn.eu.contentful.com` and `previewHost` to `preview.eu.contentful.com`. Map `fields.order` to a number field to set each page's sidebar order; it has no default. Assets are referenced from Contentful's CDN rather than downloaded — their URLs are stable. A link to another entry of the source's `contentType` points at that entry's page, at the route the page is built at (its slug under the source's `prefix`). A link to an entry the source doesn't turn into a page, one of another content type or one your `params` filter out, keeps only its text. The Delivery API leaves an unpublished, archived, or deleted asset or entry out of its response, so a page that embeds or links one renders without it (a link keeps its text) and the source warns with `BLUME_SOURCE_UNRESOLVED_LINK`. An embedded entry maps to a Blume component through the engine's `serializers` option, keyed by content type id, when you construct `contentfulSource` directly and pass it to [`custom()`](/docs/content/sources/custom); setting `serializers` writes the source's pages as MDX so the returned components render, and an embedded entry without a serializer is noted in a comment.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Custom sources
|
|
3
|
+
description: Plug any backend into Blume with custom() — pass an object that implements the ContentSource interface, or a built-in engine with custom serializers.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Any object implementing the `ContentSource` interface can be passed to `custom()`, which is how an adapter with custom serializers — or any backend not built in — plugs in without its SDK touching the core install:
|
|
7
|
+
|
|
8
|
+
```ts blume.config.ts
|
|
9
|
+
import { defineConfig } from "blume";
|
|
10
|
+
import { custom, filesystem } from "blume/sources";
|
|
11
|
+
import { escapeMarkdownText } from "blume/sources/lower.ts";
|
|
12
|
+
import { sanitySource } from "blume/sources/sanity.ts";
|
|
13
|
+
|
|
14
|
+
export default defineConfig({
|
|
15
|
+
content: {
|
|
16
|
+
sources: [
|
|
17
|
+
filesystem({ root: "docs" }),
|
|
18
|
+
custom(
|
|
19
|
+
sanitySource({
|
|
20
|
+
name: "guides",
|
|
21
|
+
prefix: "guides",
|
|
22
|
+
projectId: "abc123",
|
|
23
|
+
dataset: "production",
|
|
24
|
+
query: `*[_type == "guide"]`,
|
|
25
|
+
// Map custom Portable Text blocks to Blume components
|
|
26
|
+
serializers: {
|
|
27
|
+
callout: (block) =>
|
|
28
|
+
`<Callout>${escapeMarkdownText(String(block.text ?? ""))}</Callout>`,
|
|
29
|
+
},
|
|
30
|
+
})
|
|
31
|
+
),
|
|
32
|
+
],
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
A serializer's return value is written into the page as MDX, as is, so text it takes from the CMS must be escaped: a `{` in an editor's text would otherwise run as an expression and fail the build, and a `<b>` would render as HTML. `escapeMarkdownText` escapes it the way Blume's built-in lowering does, so the text renders as written.
|
|
38
|
+
|
|
39
|
+
A source built with one of Blume's engine factories, like `sanitySource` above, is rebuilt on the running command's context, so it reads drafts under `--preview` and keeps its snapshot in `.blume/cache` the way the built-in adapter does. A source of your own can do the same by implementing `withContext(ctx)` and returning itself rebuilt on that context. Unlike a built-in adapter's, a `custom()` source's snapshot is kept per preview mode only, not per set of options, since Blume sees an instance rather than its options. `blume dev` serves that snapshot after you edit the source's query, fields, or serializers, so run `blume sync` to fetch afresh.
|
|
40
|
+
|
|
41
|
+
`custom()` takes a `ContentSource` instance rather than an options object, so there is nothing to pass the [shared options](/docs/content/sources#adapters) `prefix` or `pollInterval` to. The source sets its own `prefix` property, and re-fetching is whatever its `watch` method implements. It carries a live instance rather than plain data, so it declares no runtime dependency or secret of its own — the instance manages those itself. `blume dev` and `blume build` don't warn about an unset variable a `custom()` source reads; an engine whose API requires its token (`notionSource`, `contentfulSource`) stops before its first request with `BLUME_MISSING_SECRET` instead.
|
|
42
|
+
|
|
43
|
+
A custom source that reads local files should set `sourcePath` on each entry and `contentRoot` on the source itself. `sourcePath` names the file in diagnostics and resolves relative images beside it; `contentRoot` bounds the git `log` that dates pages, so without it the source's pages get no git-derived ["Last updated" date](/docs/configuration#last-modified).
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: GitHub Releases
|
|
3
|
+
description: Turn a repository's GitHub releases into changelog entries with the githubReleases() source, so your release notes are your changelog.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
The built-in `githubReleases()` adapter turns a repo's releases into a changelog: each release becomes a `type: changelog` entry, so your release notes _are_ your changelog — nothing to write twice. Combined with the generated [changelog timeline](/docs/advanced/changelog), publishing a GitHub release ships a changelog entry.
|
|
7
|
+
|
|
8
|
+
```ts blume.config.ts
|
|
9
|
+
import { defineConfig } from "blume";
|
|
10
|
+
import { filesystem, githubReleases } from "blume/sources";
|
|
11
|
+
|
|
12
|
+
export default defineConfig({
|
|
13
|
+
content: {
|
|
14
|
+
sources: [
|
|
15
|
+
filesystem({ root: "content" }),
|
|
16
|
+
githubReleases({
|
|
17
|
+
prefix: "changelog",
|
|
18
|
+
owner: "acme",
|
|
19
|
+
repo: "sdk",
|
|
20
|
+
// prereleases: false, // include prereleases (default off)
|
|
21
|
+
// drafts: false, // include drafts (needs a write token)
|
|
22
|
+
// limit: 100, // cap releases, newest-first
|
|
23
|
+
// baseUrl: "https://github.acme.com/api/v3", // GitHub Enterprise Server
|
|
24
|
+
}),
|
|
25
|
+
],
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Each release maps to the changelog fields automatically: its name (or tag) becomes the title, its published date drives the timeline order, the tag becomes `changelog.version`, and prereleases are tagged `Prerelease`, drafts (when `drafts` includes them) `Draft`, and the rest `Release`. A draft is published like any other release, so include drafts only in a build readers don't see. A summary of the notes becomes the page's meta description, which the changelog's RSS feed uses as the item's description too. The notes render as the entry body, with two changes to their links: a link that isn't a web, mail, phone, or relative address (a `javascript:` URL, say) keeps only its label, and a link back to your own [`deployment.site`](/docs/deployment) is rewritten to its root-relative path, so it follows preview deploys and your deployment base. Give the source a `prefix` so its release pages nest under a route like `/changelog/v1-2-0`. The timeline at `/changelog` takes its title and description from the top-level [`changelog`](/docs/advanced/changelog#the-index-page) config, not from the source:
|
|
31
|
+
|
|
32
|
+
```ts blume.config.ts
|
|
33
|
+
changelog: {
|
|
34
|
+
title: "SDK releases",
|
|
35
|
+
description: "Every release of the Acme SDK, from GitHub.",
|
|
36
|
+
},
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
A private repo authenticates with the `GITHUB_TOKEN` environment variable — the same token the other GitHub features use, never inlined into your config; the adapter declares it, so a build without it warns. For a repository on GitHub Enterprise Server, set `baseUrl` to its REST API (`https://<host>/api/v3`); `GITHUB_TOKEN` is sent there, so it must be a token for that server. Like [every remote source](/docs/content/sources#caching-and-offline-builds) it's cached under `.blume/cache/<source>/` and served offline if the API is unreachable. Because a changelog is supplementary, a fetch failure with no cache (say a CI build without a token) degrades to an empty changelog with a warning rather than failing the build — set `GITHUB_TOKEN` in your CI and deploy environments to populate it.
|