blume 2.0.2 → 2.1.0
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 +113 -0
- package/README.md +1 -1
- package/dist/cli/{chunk-6k4ftwze.js → chunk-0gz36akr.js} +18 -2
- package/dist/cli/{chunk-6k4ftwze.js.map → chunk-0gz36akr.js.map} +3 -3
- package/dist/cli/{chunk-zp79m0ts.js → chunk-1n228xqb.js} +2 -2
- package/dist/cli/{chunk-ddndchfr.js → chunk-2f3ndkpw.js} +57 -29
- package/dist/cli/chunk-2f3ndkpw.js.map +14 -0
- package/dist/cli/{chunk-fsmrqk8a.js → chunk-2f7n4qzt.js} +8 -2
- package/dist/cli/{chunk-fsmrqk8a.js.map → chunk-2f7n4qzt.js.map} +3 -3
- package/dist/cli/{chunk-ppzjqwx2.js → chunk-2n4ps1b3.js} +17 -18
- package/dist/cli/{chunk-ppzjqwx2.js.map → chunk-2n4ps1b3.js.map} +3 -3
- package/dist/cli/{chunk-5r8g91qn.js → chunk-43zcf4gz.js} +398 -159
- package/dist/cli/chunk-43zcf4gz.js.map +36 -0
- package/dist/cli/chunk-4ejxbzee.js +39 -0
- package/dist/cli/chunk-4ejxbzee.js.map +10 -0
- package/dist/cli/{chunk-hr8ne106.js → chunk-4h8z9vv5.js} +296 -77
- package/dist/cli/chunk-4h8z9vv5.js.map +16 -0
- package/dist/cli/{chunk-k7pj68a8.js → chunk-5cg2rzgf.js} +18 -16
- package/dist/cli/{chunk-k7pj68a8.js.map → chunk-5cg2rzgf.js.map} +2 -2
- package/dist/cli/{chunk-h2ez8dzb.js → chunk-5ffywsmb.js} +4 -4
- package/dist/cli/{chunk-g698a744.js → chunk-5wj2qwn2.js} +5 -5
- package/dist/cli/chunk-6bm0xpgd.js +18 -0
- package/dist/cli/chunk-6bm0xpgd.js.map +10 -0
- package/dist/cli/{chunk-3yce002v.js → chunk-713mngdq.js} +15 -8
- package/dist/cli/chunk-713mngdq.js.map +14 -0
- package/dist/cli/{chunk-91ws1n6j.js → chunk-9geymqns.js} +17 -15
- package/dist/cli/{chunk-91ws1n6j.js.map → chunk-9geymqns.js.map} +2 -2
- package/dist/cli/{chunk-6dtt0zfn.js → chunk-9xr4dgee.js} +27 -18
- package/dist/cli/chunk-9xr4dgee.js.map +10 -0
- package/dist/cli/{chunk-sqw4ekg1.js → chunk-amrb6hgh.js} +2 -2
- package/dist/cli/chunk-cm89scdv.js +443 -0
- package/dist/cli/chunk-cm89scdv.js.map +11 -0
- package/dist/cli/{chunk-wdrt2k2v.js → chunk-cmtcnh9f.js} +90 -26
- package/dist/cli/chunk-cmtcnh9f.js.map +10 -0
- package/dist/cli/chunk-cy5bm0j0.js +104 -0
- package/dist/cli/chunk-cy5bm0j0.js.map +11 -0
- package/dist/cli/{chunk-7mbqtmgb.js → chunk-e7vvk5ya.js} +21 -12
- package/dist/cli/chunk-e7vvk5ya.js.map +10 -0
- package/dist/cli/{chunk-qkb5a8sa.js → chunk-g2z9x01v.js} +6 -98
- package/dist/cli/chunk-g2z9x01v.js.map +10 -0
- 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-h7k3nq3v.js → chunk-gp84za0h.js} +2 -2
- package/dist/cli/{chunk-hqp2ajnh.js → chunk-h2a48yhd.js} +195 -73
- package/dist/cli/chunk-h2a48yhd.js.map +36 -0
- package/dist/cli/{chunk-pbg5a4s3.js → chunk-jnwj5kjj.js} +71 -47
- package/dist/cli/chunk-jnwj5kjj.js.map +19 -0
- package/dist/cli/chunk-kwrg63tm.js +31 -0
- package/dist/cli/chunk-kwrg63tm.js.map +10 -0
- package/dist/cli/{chunk-8g8ytmgx.js → chunk-nd1821sk.js} +21 -19
- package/dist/cli/{chunk-8g8ytmgx.js.map → chunk-nd1821sk.js.map} +2 -2
- package/dist/cli/{chunk-w4bxdvsa.js → chunk-ntv4qrt7.js} +17 -15
- package/dist/cli/{chunk-w4bxdvsa.js.map → chunk-ntv4qrt7.js.map} +2 -2
- package/dist/cli/{chunk-bfwp9vp6.js → chunk-p804f3pe.js} +7 -7
- package/dist/cli/{chunk-4e9b9ra6.js → chunk-py62fewh.js} +6 -6
- package/dist/cli/{chunk-4e9b9ra6.js.map → chunk-py62fewh.js.map} +1 -1
- package/dist/cli/chunk-q3wxxq39.js +126 -0
- package/dist/cli/chunk-q3wxxq39.js.map +11 -0
- package/dist/cli/{chunk-j85scx15.js → chunk-rekqz4qg.js} +142 -46
- package/dist/cli/chunk-rekqz4qg.js.map +10 -0
- package/dist/cli/{chunk-00gs3wqs.js → chunk-ta27feev.js} +1 -1
- package/dist/cli/{chunk-v6ya5kcb.js → chunk-xkz5xbtv.js} +4031 -1132
- package/dist/cli/chunk-xkz5xbtv.js.map +213 -0
- package/dist/cli/{chunk-bbnwccaz.js → chunk-y4ykbark.js} +2 -2
- package/dist/cli/{chunk-n1yg3tj3.js → chunk-y5h4r2y0.js} +6 -6
- package/dist/cli/{chunk-n1yg3tj3.js.map → chunk-y5h4r2y0.js.map} +3 -3
- package/dist/cli/{chunk-nfcyttvj.js → chunk-yj17vs39.js} +9 -9
- package/dist/cli/{chunk-nfcyttvj.js.map → chunk-yj17vs39.js.map} +1 -1
- package/dist/cli/{chunk-7vtckvaw.js → chunk-yxmk4pec.js} +16 -14
- package/dist/cli/{chunk-7vtckvaw.js.map → chunk-yxmk4pec.js.map} +2 -2
- package/dist/cli/{chunk-gs7r695n.js → chunk-zccbjcj0.js} +22 -8
- package/dist/cli/{chunk-gs7r695n.js.map → chunk-zccbjcj0.js.map} +3 -3
- package/dist/cli/{chunk-xh43dwgw.js → chunk-zf748avv.js} +415 -225
- package/dist/cli/chunk-zf748avv.js.map +37 -0
- package/dist/cli/{chunk-d1v5rhy0.js → chunk-zhvd6adm.js} +16 -14
- package/dist/cli/{chunk-d1v5rhy0.js.map → chunk-zhvd6adm.js.map} +2 -2
- package/dist/cli/index.js +28 -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 +22 -0
- package/dist/types/ai/ask.d.ts +271 -58
- package/dist/types/ai/index.d.ts +2 -2
- 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/site-skill.d.ts +26 -0
- package/dist/types/ai/skills.d.ts +20 -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 +11 -2
- 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/components/content/api-field.d.ts +59 -0
- package/dist/types/components/content/api-page.d.ts +95 -0
- package/dist/types/components/layout/nav-utils.d.ts +26 -0
- package/dist/types/components/openapi/helpers.d.ts +137 -0
- package/dist/types/components/openapi/security.d.ts +85 -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/base-path.d.ts +21 -7
- package/dist/types/core/config-input.d.ts +196 -27
- package/dist/types/core/data.d.ts +49 -4
- package/dist/types/core/directive-diagnostics.d.ts +12 -0
- package/dist/types/core/footer.d.ts +8 -0
- package/dist/types/core/heading-markers.d.ts +5 -7
- package/dist/types/core/i18n-ui.d.ts +86 -0
- package/dist/types/core/i18n.d.ts +2 -0
- package/dist/types/core/includes.d.ts +8 -2
- package/dist/types/core/last-modified.d.ts +10 -0
- package/dist/types/core/localizable.d.ts +7 -0
- package/dist/types/core/meta.d.ts +8 -0
- package/dist/types/core/page-modes.d.ts +29 -0
- package/dist/types/core/redirect-patterns.d.ts +144 -0
- package/dist/types/core/related.d.ts +40 -0
- package/dist/types/core/schema.d.ts +558 -56
- 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/read.d.ts +5 -0
- package/dist/types/core/sources/watch.d.ts +12 -5
- package/dist/types/core/standard-schema.d.ts +5 -0
- package/dist/types/core/types.d.ts +1 -1
- package/dist/types/core/variables.d.ts +42 -0
- package/dist/types/deploy/artifacts.d.ts +6 -4
- package/dist/types/deploy/headers.d.ts +5 -0
- package/dist/types/deploy/node-headers.d.ts +13 -2
- package/dist/types/deploy/platforms/cloudflare.d.ts +5 -0
- package/dist/types/deploy/platforms/netlify.d.ts +7 -0
- package/dist/types/deploy/platforms/types.d.ts +8 -0
- package/dist/types/deploy/platforms/vercel.d.ts +6 -0
- package/dist/types/deploy/redirects.d.ts +61 -22
- package/dist/types/deploy/vercel-negotiation.d.ts +9 -0
- package/dist/types/markdown/code-title.d.ts +17 -0
- package/dist/types/markdown/directives.d.ts +62 -0
- package/dist/types/markdown/features.d.ts +24 -2
- package/dist/types/markdown/mdast.d.ts +63 -0
- 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/asyncapi.d.ts +4 -2
- package/dist/types/openapi/model.d.ts +12 -6
- package/dist/types/openapi/overlay.d.ts +54 -0
- package/dist/types/openapi/parse.d.ts +13 -0
- package/dist/types/openapi/references.d.ts +14 -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 +111 -0
- package/dist/types/ratelimit/upstash.d.ts +21 -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 +13 -10
- package/dist/types/reference/openapi.d.ts +33 -12
- package/dist/types/reference/options.d.ts +45 -5
- package/dist/types/reference/scalar.d.ts +13 -0
- package/dist/types/reference/schema.d.ts +60 -36
- package/dist/types/search/documents.d.ts +12 -1
- package/dist/types/search/orama-index.d.ts +4 -0
- package/dist/types/seo/metatags.d.ts +20 -0
- package/docs/02-deployment.mdx +44 -6
- package/docs/03-upgrading.mdx +4 -4
- package/docs/04-migrating.mdx +1 -1
- package/docs/08-faq.mdx +1 -1
- package/docs/advanced/changelog.mdx +2 -2
- package/docs/advanced/custom-pages.mdx +3 -3
- package/docs/advanced/skills.mdx +14 -0
- package/docs/cli/audit.mdx +38 -2
- package/docs/cli/evals.mdx +3 -3
- package/docs/cli/index.mdx +1 -0
- package/docs/cli/translate.mdx +3 -3
- package/docs/cli/version.mdx +1 -1
- package/docs/configuration/analytics.mdx +22 -1
- package/docs/configuration/assistant.mdx +188 -36
- package/docs/configuration/consent.mdx +100 -0
- package/docs/configuration/customization.mdx +6 -4
- package/docs/configuration/index.mdx +63 -5
- package/docs/configuration/meta.ts +3 -0
- package/docs/configuration/narration.mdx +119 -0
- package/docs/configuration/rate-limiting.mdx +69 -0
- package/docs/configuration/search.mdx +30 -2
- package/docs/configuration/theming.mdx +3 -1
- package/docs/content/components.mdx +107 -1
- package/docs/content/frontmatter.mdx +77 -1
- package/docs/content/i18n.mdx +40 -3
- package/docs/content/includes.mdx +16 -0
- package/docs/content/index.mdx +4 -2
- package/docs/content/islands.mdx +1 -1
- package/docs/content/meta.mdx +4 -1
- package/docs/content/meta.ts +1 -0
- package/docs/content/navigation.mdx +28 -6
- package/docs/content/sources/contentful.mdx +32 -0
- package/docs/content/sources/custom.mdx +39 -0
- package/docs/content/sources/github-releases.mdx +31 -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 +30 -0
- package/docs/content/sources/remote-mdx.mdx +40 -0
- package/docs/content/sources/sanity.mdx +29 -0
- package/docs/content/sources/strapi.mdx +31 -0
- package/docs/content/syntax.mdx +81 -2
- package/docs/content/variables.mdx +41 -0
- package/docs/content/versioning.mdx +1 -1
- package/docs/discoverability/agent-discovery.mdx +30 -3
- package/docs/discoverability/index.mdx +3 -2
- package/docs/discoverability/llms-txt.mdx +1 -1
- package/docs/discoverability/markdown.mdx +2 -2
- package/docs/discoverability/metadata.mdx +17 -0
- package/docs/discoverability/open-graph.mdx +5 -3
- package/docs/discoverability/rss.mdx +1 -1
- package/docs/references/api-pages.mdx +74 -0
- package/docs/references/asyncapi.mdx +2 -2
- package/docs/references/graphql.mdx +3 -3
- package/docs/references/meta.ts +1 -1
- package/docs/references/openapi.mdx +106 -5
- package/docs/references/scalar.mdx +3 -1
- package/package.json +36 -1
- package/skills/blume/SKILL.md +3 -0
- package/skills/blume-migrate/SKILL.md +5 -5
- package/skills/blume-migrate/references/docusaurus.md +3 -3
- package/skills/blume-migrate/references/fumadocs.md +1 -1
- package/skills/blume-migrate/references/mintlify.md +37 -19
- package/skills/blume-migrate/references/nextra.md +3 -3
- package/skills/blume-migrate/references/starlight.md +2 -1
- package/skills/blume-migrate/scripts/mintlify-codemod.mjs +67 -16
- package/skills/blume-write-skill/SKILL.md +82 -0
- package/src/ai/agent-readability.ts +4 -3
- package/src/ai/agent-surface.ts +9 -7
- package/src/ai/ai-catalog.ts +12 -5
- 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/ask-context.ts +73 -20
- package/src/ai/ask-data.ts +6 -0
- package/src/ai/ask-tools.ts +142 -0
- package/src/ai/ask.ts +354 -76
- package/src/ai/changelog-markdown.ts +2 -2
- package/src/ai/component-markdown.ts +75 -0
- package/src/ai/cors.ts +2 -0
- package/src/ai/index.ts +12 -0
- package/src/ai/link-headers.ts +14 -5
- package/src/ai/llms.ts +24 -9
- package/src/ai/markdown.ts +2 -1
- package/src/ai/mcp/data.ts +6 -0
- 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 +31 -9
- package/src/ai/relative-links.ts +42 -26
- package/src/ai/serializers.ts +2 -1
- package/src/ai/site-skill.ts +274 -0
- package/src/ai/skills.ts +49 -3
- package/src/ai/tar.ts +139 -12
- package/src/ai/write-skill.ts +97 -0
- 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 +133 -19
- package/src/astro/include-hmr.ts +31 -12
- package/src/astro/include-refresh.ts +19 -8
- package/src/astro/index.ts +1 -0
- package/src/astro/integration.ts +143 -14
- package/src/astro/module-types.ts +6 -0
- package/src/astro/runtime-modules.ts +28 -13
- package/src/astro/templates.ts +364 -67
- package/src/astro/variables.ts +31 -0
- package/src/audit/catalog.ts +19 -0
- 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 +13 -13
- package/src/audit/checks/sitemap.ts +2 -3
- package/src/audit/graph.ts +3 -1
- package/src/audit/redirects.ts +46 -15
- package/src/audit/run.ts +14 -9
- package/src/audit/snapshot.ts +5 -0
- package/src/audit/types.ts +2 -1
- package/src/blume-modules.d.ts +7 -0
- 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 +32 -0
- package/src/cli/command-meta.ts +5 -0
- package/src/cli/commands/audit.ts +4 -1
- package/src/cli/commands/doctor.ts +25 -17
- package/src/cli/commands/eval.ts +19 -11
- package/src/cli/commands/skill.ts +96 -0
- 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/index.ts +5 -0
- package/src/cli/report-format.ts +11 -6
- package/src/cli/required-secrets.ts +71 -29
- package/src/components/BlumePage.astro +2 -0
- package/src/components/colors.ts +19 -0
- package/src/components/content/ApiEndpoint.astro +18 -0
- package/src/components/content/ApiField.astro +79 -0
- package/src/components/content/ApiPlayground.astro +62 -0
- package/src/components/content/ApiRail.astro +19 -0
- package/src/components/content/Badge.astro +5 -3
- package/src/components/content/Color.astro +1 -0
- package/src/components/content/Component.astro +2 -2
- 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/Tab.astro +0 -1
- package/src/components/content/Tabs.astro +4 -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 +100 -0
- package/src/components/content/api-page.ts +224 -0
- package/src/components/content/badge-color.ts +5 -2
- package/src/components/content/base-href.ts +13 -36
- 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 +125 -18
- package/src/components/islands/base-path.ts +47 -10
- package/src/components/islands/code-question.ts +62 -0
- package/src/components/islands/hooks.ts +145 -40
- package/src/components/islands/support-link.ts +68 -0
- package/src/components/islands/webmcp.ts +4 -2
- package/src/components/layout/Analytics.astro +11 -2
- package/src/components/layout/Banner.astro +14 -10
- package/src/components/layout/Breadcrumbs.astro +11 -4
- 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/DiscoveryLinks.astro +9 -5
- package/src/components/layout/DrawerSwitchers.astro +51 -0
- package/src/components/layout/Empty.astro +2 -2
- package/src/components/layout/Header.astro +124 -82
- package/src/components/layout/LanguageSwitcher.astro +50 -17
- package/src/components/layout/NarrationPlayer.astro +1085 -0
- package/src/components/layout/NavSelector.astro +35 -9
- 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/PageFeedback.astro +54 -49
- package/src/components/layout/PageLayout.astro +78 -9
- package/src/components/layout/Pagination.astro +3 -3
- package/src/components/layout/ReferenceLayout.astro +17 -6
- package/src/components/layout/RelatedPages.astro +42 -0
- package/src/components/layout/RootLayout.astro +313 -50
- package/src/components/layout/Search.astro +64 -30
- package/src/components/layout/SiteFooter.astro +124 -0
- package/src/components/layout/SiteMetatags.astro +16 -0
- package/src/components/layout/VersionBanner.astro +2 -2
- package/src/components/layout/analytics-client.ts +12 -0
- 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/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/analytics.ts +98 -0
- package/src/components/layout/search/flexsearch.ts +17 -5
- package/src/components/layout/search/orama-cloud.ts +26 -14
- package/src/components/layout/search/types.ts +20 -0
- package/src/components/layout/search/typesense.ts +5 -1
- 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 +163 -13
- package/src/components/openapi/Playground.astro +4 -4
- package/src/components/openapi/RequestBody.astro +6 -4
- package/src/components/openapi/RequestPanel.astro +63 -8
- package/src/components/openapi/Responses.astro +6 -4
- package/src/components/openapi/SchemaTable.astro +7 -0
- package/src/components/openapi/async-snippets.ts +4 -4
- package/src/components/openapi/async.ts +38 -6
- package/src/components/openapi/code-samples.ts +97 -0
- 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/security.ts +6 -3
- package/src/components/openapi/snippets.ts +953 -13
- package/src/components/openapi/ws-client.ts +18 -2
- 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/base-path.ts +62 -16
- package/src/core/builtin-tags.ts +5 -0
- package/src/core/client-address.ts +19 -0
- package/src/core/config-input.ts +203 -27
- package/src/core/data.ts +44 -4
- package/src/core/diagnostics.ts +5 -2
- package/src/core/directive-diagnostics.ts +99 -0
- package/src/core/footer.ts +26 -0
- package/src/core/frontmatter.ts +21 -18
- package/src/core/graph.ts +39 -36
- package/src/core/heading-markers.ts +5 -18
- package/src/core/i18n-ui.ts +82 -2
- package/src/core/i18n.ts +31 -3
- package/src/core/includes.ts +20 -3
- package/src/core/last-modified.ts +25 -3
- package/src/core/links.ts +16 -2
- package/src/core/locale-links.ts +5 -1
- package/src/core/localizable.ts +26 -0
- package/src/core/meta.ts +33 -19
- package/src/core/navigation.ts +71 -20
- package/src/core/page-modes.ts +56 -0
- package/src/core/project-graph.ts +138 -10
- package/src/core/redirect-patterns.ts +491 -0
- package/src/core/related.ts +131 -0
- package/src/core/schema.ts +342 -68
- 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 +327 -91
- 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/read.ts +8 -3
- 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/types.ts +1 -1
- package/src/core/ui-packs/ar.ts +43 -0
- package/src/core/ui-packs/bg.ts +45 -0
- package/src/core/ui-packs/bn.ts +43 -0
- package/src/core/ui-packs/ca.ts +46 -0
- package/src/core/ui-packs/cs.ts +44 -0
- package/src/core/ui-packs/da.ts +45 -0
- package/src/core/ui-packs/de.ts +46 -0
- package/src/core/ui-packs/el.ts +45 -0
- package/src/core/ui-packs/es.ts +46 -0
- package/src/core/ui-packs/fa.ts +45 -0
- package/src/core/ui-packs/fi.ts +45 -0
- package/src/core/ui-packs/fr.ts +46 -0
- package/src/core/ui-packs/he.ts +43 -0
- package/src/core/ui-packs/hi.ts +44 -0
- package/src/core/ui-packs/hr.ts +45 -0
- package/src/core/ui-packs/hu.ts +44 -0
- package/src/core/ui-packs/id.ts +45 -0
- package/src/core/ui-packs/it.ts +45 -0
- package/src/core/ui-packs/ja.ts +45 -0
- package/src/core/ui-packs/ko.ts +44 -0
- package/src/core/ui-packs/nl.ts +46 -0
- package/src/core/ui-packs/no.ts +44 -0
- package/src/core/ui-packs/pl.ts +45 -0
- package/src/core/ui-packs/pt-br.ts +46 -0
- package/src/core/ui-packs/pt.ts +45 -0
- package/src/core/ui-packs/ro.ts +45 -0
- package/src/core/ui-packs/ru.ts +45 -0
- package/src/core/ui-packs/sk.ts +44 -0
- package/src/core/ui-packs/sr.ts +45 -0
- package/src/core/ui-packs/sv.ts +44 -0
- package/src/core/ui-packs/th.ts +43 -0
- package/src/core/ui-packs/tr.ts +45 -0
- package/src/core/ui-packs/uk.ts +45 -0
- package/src/core/ui-packs/vi.ts +45 -0
- package/src/core/ui-packs/zh-tw.ts +43 -0
- package/src/core/ui-packs/zh.ts +43 -0
- package/src/core/variables.ts +103 -0
- package/src/core/version-cut.ts +52 -15
- package/src/deploy/artifacts.ts +104 -14
- package/src/deploy/cloudflare-negotiation.ts +39 -17
- package/src/deploy/headers.ts +10 -5
- package/src/deploy/node-headers.ts +64 -10
- package/src/deploy/platforms/cloudflare.ts +44 -3
- package/src/deploy/platforms/netlify.ts +34 -1
- 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 +38 -2
- package/src/deploy/redirects.ts +139 -36
- package/src/deploy/robots.ts +2 -2
- package/src/deploy/rss.ts +4 -3
- package/src/deploy/sitemap.ts +7 -5
- package/src/deploy/vercel-negotiation.ts +36 -0
- package/src/markdown/api-rail.ts +259 -0
- package/src/markdown/base-links.ts +34 -36
- package/src/markdown/code-title.ts +35 -9
- package/src/markdown/directives.ts +242 -36
- package/src/markdown/features.ts +20 -2
- package/src/markdown/fence-meta.ts +2 -0
- package/src/markdown/include.ts +11 -1
- package/src/markdown/index.ts +35 -11
- package/src/markdown/math.ts +4 -4
- package/src/markdown/mdast.ts +5 -2
- package/src/markdown/relative-links.ts +12 -4
- 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 +136 -11
- 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 +77 -36
- package/src/openapi/overlay.ts +256 -0
- package/src/openapi/parse.ts +55 -2
- package/src/openapi/proxy.ts +63 -10
- package/src/openapi/references.ts +21 -5
- package/src/openapi/render-mdx.ts +46 -3
- package/src/openapi/scalar.ts +40 -6
- package/src/openapi/source.ts +1 -1
- 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 +229 -0
- package/src/ratelimit/schema.ts +28 -0
- package/src/ratelimit/upstash.ts +30 -0
- package/src/ratelimit/wrangler.ts +70 -0
- package/src/reference/asyncapi.ts +2 -2
- package/src/reference/graphql.ts +5 -2
- package/src/reference/openapi.ts +21 -7
- package/src/reference/options.ts +51 -7
- package/src/reference/scalar.ts +33 -8
- package/src/registry/eject.ts +201 -28
- package/src/registry/registry.ts +7 -0
- package/src/search/adapters/version-scope.ts +30 -0
- package/src/search/documents.ts +93 -28
- package/src/search/orama-index.ts +28 -3
- package/src/search/pagefind-ranking.ts +39 -0
- package/src/search/popular.ts +2 -1
- package/src/search/sync/algolia.ts +15 -4
- package/src/search/sync/orama-cloud.ts +3 -0
- package/src/search/sync/typesense.ts +5 -0
- package/src/seo/jsonld.ts +7 -3
- package/src/seo/metatags.ts +67 -0
- package/src/theme/chrome-icons.ts +1 -0
- package/src/theme/color.ts +500 -0
- package/src/theme/entry.ts +56 -3
- package/src/theme/palette.ts +121 -45
- package/src/translate/meta.ts +68 -24
- package/src/translate/prompts.ts +1 -0
- package/src/translate/run.ts +3 -3
- package/src/translate/validate.ts +12 -3
- package/src/translate/work-list.ts +56 -17
- package/src/upgrade/upgrade.ts +4 -171
- package/dist/cli/chunk-3yce002v.js.map +0 -14
- package/dist/cli/chunk-5r8g91qn.js.map +0 -34
- package/dist/cli/chunk-6dtt0zfn.js.map +0 -10
- 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-hqp2ajnh.js.map +0 -35
- package/dist/cli/chunk-hr8ne106.js.map +0 -13
- package/dist/cli/chunk-j85scx15.js.map +0 -10
- package/dist/cli/chunk-mqc662a6.js +0 -75
- package/dist/cli/chunk-mqc662a6.js.map +0 -11
- package/dist/cli/chunk-pbg5a4s3.js.map +0 -19
- package/dist/cli/chunk-qkb5a8sa.js.map +0 -10
- package/dist/cli/chunk-v6ya5kcb.js.map +0 -189
- package/dist/cli/chunk-wdrt2k2v.js.map +0 -10
- package/dist/cli/chunk-xh43dwgw.js.map +0 -36
- package/docs/content/sources.mdx +0 -338
- /package/dist/cli/{chunk-zp79m0ts.js.map → chunk-1n228xqb.js.map} +0 -0
- /package/dist/cli/{chunk-h2ez8dzb.js.map → chunk-5ffywsmb.js.map} +0 -0
- /package/dist/cli/{chunk-g698a744.js.map → chunk-5wj2qwn2.js.map} +0 -0
- /package/dist/cli/{chunk-sqw4ekg1.js.map → chunk-amrb6hgh.js.map} +0 -0
- /package/dist/cli/{chunk-h7k3nq3v.js.map → chunk-gp84za0h.js.map} +0 -0
- /package/dist/cli/{chunk-bfwp9vp6.js.map → chunk-p804f3pe.js.map} +0 -0
- /package/dist/cli/{chunk-00gs3wqs.js.map → chunk-ta27feev.js.map} +0 -0
- /package/dist/cli/{chunk-bbnwccaz.js.map → chunk-y4ykbark.js.map} +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
import {
|
|
2
|
+
import { withMountedBase } from "../islands/base-path.ts";
|
|
3
3
|
// A top-level navigation selector: a dropdown that switches
|
|
4
4
|
// between partitions of the site — a product, a version, or any grouped set of
|
|
5
5
|
// destinations (`navigation.selectors` in the config). Built on
|
|
@@ -19,9 +19,15 @@ interface Props {
|
|
|
19
19
|
* overflow the viewport — pass `end` there.
|
|
20
20
|
*/
|
|
21
21
|
align?: "start" | "end";
|
|
22
|
+
/**
|
|
23
|
+
* `bar` (the default) for the header; `drawer` for the top of the nav
|
|
24
|
+
* drawer, where the trigger spans the drawer, always shows its label, and
|
|
25
|
+
* opens a panel as wide as itself, so nothing reaches past the drawer edge.
|
|
26
|
+
*/
|
|
27
|
+
variant?: "bar" | "drawer";
|
|
22
28
|
}
|
|
23
29
|
|
|
24
|
-
const { selector, route, align = "start" } = Astro.props;
|
|
30
|
+
const { selector, route, align = "start", variant = "bar" } = Astro.props;
|
|
25
31
|
|
|
26
32
|
// The active item is the deepest path the current route sits under (on a path
|
|
27
33
|
// boundary, so `/api` never claims `/api-reference` routes), falling back to
|
|
@@ -37,25 +43,37 @@ const active =
|
|
|
37
43
|
// version like "v2" or "Latest"): on a phone a bare chevron doesn't say what
|
|
38
44
|
// it switches. Longer product names still collapse to the icon there.
|
|
39
45
|
const label = active?.label ?? selector.label;
|
|
40
|
-
|
|
46
|
+
let labelClass: string | undefined;
|
|
47
|
+
if (variant === "drawer") {
|
|
48
|
+
labelClass = "flex-1 text-start";
|
|
49
|
+
} else if (label.length > 6) {
|
|
50
|
+
labelClass = "max-sm:hidden";
|
|
51
|
+
}
|
|
41
52
|
// The accessible name carries the visible active label too (WCAG 2.5.3,
|
|
42
53
|
// label in name), so a voice-control user can say "v2" to open it — the
|
|
43
54
|
// language switcher's pattern.
|
|
44
55
|
const summaryLabel =
|
|
45
56
|
label === selector.label ? selector.label : `${selector.label}: ${label}`;
|
|
46
57
|
|
|
47
|
-
|
|
48
|
-
|
|
58
|
+
// Borderless in the header, like the icon buttons and the language switcher;
|
|
59
|
+
// bordered in the drawer, where the trigger spans it.
|
|
60
|
+
const triggerClass =
|
|
61
|
+
variant === "bar"
|
|
62
|
+
? "inline-flex h-9 cursor-pointer items-center gap-1.5 rounded-full px-3 text-muted-foreground text-sm transition-colors hover:bg-muted hover:text-foreground group-open:bg-muted group-open:text-foreground"
|
|
63
|
+
: "inline-flex h-9 w-full cursor-pointer items-center gap-1.5 rounded-full border border-border bg-background px-3 text-muted-foreground text-sm transition-colors hover:border-foreground hover:text-foreground";
|
|
49
64
|
const menuRowClass =
|
|
50
65
|
"flex w-full items-start gap-2.5 rounded-md px-2 py-1.5 text-start text-muted-foreground text-sm transition-colors hover:bg-muted hover:text-foreground aria-[current=true]:text-foreground";
|
|
51
66
|
---
|
|
52
67
|
|
|
53
68
|
{
|
|
54
69
|
selector.items.length > 0 && (
|
|
55
|
-
<details
|
|
70
|
+
<details
|
|
71
|
+
class:list={["group relative", variant === "drawer" && "w-full"]}
|
|
72
|
+
data-blume-dropdown
|
|
73
|
+
>
|
|
56
74
|
<summary
|
|
57
75
|
aria-label={summaryLabel}
|
|
58
|
-
class={
|
|
76
|
+
class:list={[triggerClass, "list-none [&::-webkit-details-marker]:hidden"]}
|
|
59
77
|
>
|
|
60
78
|
{active?.icon && <Icon name={active.icon} size={16} />}
|
|
61
79
|
<span class={labelClass}>{label}</span>
|
|
@@ -66,14 +84,22 @@ const menuRowClass =
|
|
|
66
84
|
/>
|
|
67
85
|
</summary>
|
|
68
86
|
<div
|
|
69
|
-
class={
|
|
87
|
+
class:list={[
|
|
88
|
+
"absolute z-50 mt-2 rounded-blume border border-border bg-background p-1 shadow-xl",
|
|
89
|
+
variant === "drawer"
|
|
90
|
+
? "inset-x-0"
|
|
91
|
+
: [
|
|
92
|
+
"min-w-56 max-w-[calc(100vw-1rem)]",
|
|
93
|
+
align === "end" ? "end-0" : "start-0",
|
|
94
|
+
],
|
|
95
|
+
]}
|
|
70
96
|
data-blume-dropdown-panel
|
|
71
97
|
>
|
|
72
98
|
{selector.items.map((item) => (
|
|
73
99
|
<a
|
|
74
100
|
aria-current={item.path === active?.path ? "true" : undefined}
|
|
75
101
|
class={menuRowClass}
|
|
76
|
-
href={
|
|
102
|
+
href={withMountedBase(item.path)}
|
|
77
103
|
>
|
|
78
104
|
{item.icon && <Icon class="mt-0.5" name={item.icon} size={16} />}
|
|
79
105
|
<span class="flex-1">
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
// delegate from `document`, so client-router swaps need no re-init.
|
|
11
11
|
import type { NavTab } from "../../core/types.ts";
|
|
12
12
|
import Icon from "../Icon.astro";
|
|
13
|
-
import {
|
|
13
|
+
import { withMountedBase } from "../islands/base-path.ts";
|
|
14
14
|
|
|
15
15
|
interface Props {
|
|
16
16
|
tab: NavTab;
|
|
@@ -60,7 +60,7 @@ const drawerRowClass =
|
|
|
60
60
|
<a
|
|
61
61
|
aria-current={itemCurrent(item.path)}
|
|
62
62
|
class={barRowClass}
|
|
63
|
-
href={
|
|
63
|
+
href={withMountedBase(item.path)}
|
|
64
64
|
>
|
|
65
65
|
{item.icon && <Icon class="mt-0.5" name={item.icon} size={16} />}
|
|
66
66
|
<span class="flex-1">
|
|
@@ -102,7 +102,7 @@ const drawerRowClass =
|
|
|
102
102
|
<a
|
|
103
103
|
aria-current={itemCurrent(item.path)}
|
|
104
104
|
class={drawerRowClass}
|
|
105
|
-
href={
|
|
105
|
+
href={withMountedBase(item.path)}
|
|
106
106
|
>
|
|
107
107
|
{item.icon && (
|
|
108
108
|
<Icon class="shrink-0" name={item.icon} size={14} />
|
|
@@ -4,7 +4,7 @@ import type { UIStrings } from "../../core/i18n-ui.ts";
|
|
|
4
4
|
import type { NavNode } from "../../core/types.ts";
|
|
5
5
|
import { methodColor } from "../colors.ts";
|
|
6
6
|
import Icon from "../Icon.astro";
|
|
7
|
-
import { withBase } from "../islands/base-path.ts";
|
|
7
|
+
import { withBase, withMountedBase } from "../islands/base-path.ts";
|
|
8
8
|
import Self from "./NavTree.astro";
|
|
9
9
|
import NavTreeCache from "./NavTreeCache.astro";
|
|
10
10
|
import NavTreeScript from "./NavTreeScript.astro";
|
|
@@ -82,6 +82,16 @@ const n = { ...EN_UI.nav, ...strings };
|
|
|
82
82
|
/** The DOM id of a drill-in panel, which its drill button controls. */
|
|
83
83
|
const navPanelId = (id: string): string => `blume-nav-panel-${id}`;
|
|
84
84
|
|
|
85
|
+
/**
|
|
86
|
+
* A page row's href. A row backed by a page links a route Blume generates, so
|
|
87
|
+
* the deployment base always goes on — even over a route that starts with the
|
|
88
|
+
* base's own name. A config `href` link (no backing page) is authored, and
|
|
89
|
+
* keeps a base written by hand. Group rows link their index page the same way
|
|
90
|
+
* a backed page row does.
|
|
91
|
+
*/
|
|
92
|
+
const pageHref = (item: Extract<NavNode, { kind: "page" }>): string =>
|
|
93
|
+
item.pageId ? withMountedBase(item.route) : withBase(item.route);
|
|
94
|
+
|
|
85
95
|
const badgeBase =
|
|
86
96
|
"shrink-0 rounded-full px-1.5 py-0.5 font-medium text-[0.65rem] leading-none";
|
|
87
97
|
// HTTP-method, AsyncAPI-action, and GraphQL operation-kind badges (from a
|
|
@@ -191,7 +201,7 @@ const initialId =
|
|
|
191
201
|
: undefined
|
|
192
202
|
}
|
|
193
203
|
class="flex-1 truncate rounded-[0.65rem] px-1 py-1 font-semibold text-foreground text-sm transition-colors hover:bg-muted"
|
|
194
|
-
href={
|
|
204
|
+
href={withMountedBase(panel.route)}
|
|
195
205
|
>
|
|
196
206
|
{panel.label}
|
|
197
207
|
</a>
|
|
@@ -257,7 +267,7 @@ const initialId =
|
|
|
257
267
|
<a
|
|
258
268
|
aria-current={current}
|
|
259
269
|
class="blume-nav-link truncate"
|
|
260
|
-
href={
|
|
270
|
+
href={pageHref(item)}
|
|
261
271
|
>
|
|
262
272
|
{item.label}
|
|
263
273
|
</a>
|
|
@@ -269,7 +279,7 @@ const initialId =
|
|
|
269
279
|
<a
|
|
270
280
|
aria-current={current}
|
|
271
281
|
class="blume-nav-link"
|
|
272
|
-
href={
|
|
282
|
+
href={pageHref(item)}
|
|
273
283
|
>
|
|
274
284
|
<span class="flex items-center gap-2">
|
|
275
285
|
{item.icon && (
|
|
@@ -348,7 +358,7 @@ const initialId =
|
|
|
348
358
|
: undefined
|
|
349
359
|
}
|
|
350
360
|
class="blume-nav-summary-link"
|
|
351
|
-
href={
|
|
361
|
+
href={withMountedBase(item.route)}
|
|
352
362
|
>
|
|
353
363
|
{item.icon && (
|
|
354
364
|
<Icon
|
|
@@ -432,7 +442,7 @@ const initialId =
|
|
|
432
442
|
isGroupRowCurrent(item, currentRoute) ? "page" : undefined
|
|
433
443
|
}
|
|
434
444
|
class="blume-nav-heading-link"
|
|
435
|
-
href={
|
|
445
|
+
href={withMountedBase(item.route)}
|
|
436
446
|
>
|
|
437
447
|
{item.icon && (
|
|
438
448
|
<Icon
|
|
@@ -262,7 +262,7 @@ const menuRowClass =
|
|
|
262
262
|
<script>
|
|
263
263
|
import { copyDeferredText, copyText, flashLabel } from "../copy-feedback.ts";
|
|
264
264
|
import { installDropdownDismiss } from "../dropdown-dismiss.ts";
|
|
265
|
-
import {
|
|
265
|
+
import { mountBase } from "../islands/base-path.ts";
|
|
266
266
|
import { rafThrottle } from "../raf-throttle.ts";
|
|
267
267
|
|
|
268
268
|
const CHAT_URLS: Record<string, (q: string) => string> = {
|
|
@@ -390,9 +390,10 @@ hr { border: 0; border-top: 1px solid #ddd; margin: 2em 0; }`;
|
|
|
390
390
|
|
|
391
391
|
// `data-md` is the base-less logical route; the raw-markdown endpoint is a
|
|
392
392
|
// generated page route, so it's served under the deployment base like any
|
|
393
|
-
// other page
|
|
393
|
+
// other page, even when it starts with the base's own name. Mount it at
|
|
394
|
+
// emit time (the Search-island pattern).
|
|
394
395
|
const mdRoute = root.getAttribute("data-md") ?? "";
|
|
395
|
-
const md =
|
|
396
|
+
const md = mountBase(import.meta.env.BASE_URL, mdRoute);
|
|
396
397
|
const copiedLabel = root.getAttribute("data-i18n-copied") || "Copied!";
|
|
397
398
|
const copyFailedLabel =
|
|
398
399
|
root.getAttribute("data-i18n-copy-failed") || "Copy failed";
|
|
@@ -1,14 +1,22 @@
|
|
|
1
1
|
---
|
|
2
|
+
import data from "blume:data";
|
|
3
|
+
|
|
2
4
|
import { EN_UI } from "../../core/i18n-ui.ts";
|
|
3
5
|
import type { UIStrings } from "../../core/i18n-ui.ts";
|
|
4
6
|
import Icon from "../Icon.astro";
|
|
7
|
+
import { COMMENT_MAX_LENGTH } from "./page-feedback.ts";
|
|
5
8
|
|
|
6
9
|
interface Props {
|
|
10
|
+
/** Ask for a written comment after the rating (`feedback.comments`). */
|
|
11
|
+
comments?: boolean;
|
|
7
12
|
/** Localized feedback labels. */
|
|
8
13
|
strings?: UIStrings["feedback"];
|
|
9
14
|
}
|
|
10
15
|
|
|
11
|
-
const { strings } = Astro.props;
|
|
16
|
+
const { comments = false, strings } = Astro.props;
|
|
17
|
+
// Answers go through analytics, so under a consent layer the rating waits,
|
|
18
|
+
// hidden, until the reader allows analytics (`page-feedback.ts` shows it).
|
|
19
|
+
const waitsForConsent = data.config.consent !== null;
|
|
12
20
|
// Merge over the English baseline per key (rather than `strings ?? …`) so a
|
|
13
21
|
// partial — or empty `{}` — strings object still resolves every label to a
|
|
14
22
|
// default, matching the pattern PageActions and Search use.
|
|
@@ -20,61 +28,58 @@ const buttonClass =
|
|
|
20
28
|
|
|
21
29
|
<section
|
|
22
30
|
aria-label={f.question}
|
|
23
|
-
class="mx-auto mt-12
|
|
31
|
+
class="mx-auto mt-12 max-w-content border-border border-t pt-6"
|
|
24
32
|
data-blume-page-feedback
|
|
33
|
+
hidden={waitsForConsent}
|
|
25
34
|
>
|
|
26
|
-
<
|
|
27
|
-
|
|
28
|
-
<
|
|
29
|
-
<
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
<
|
|
34
|
-
|
|
35
|
-
|
|
35
|
+
<div class="flex items-center justify-between gap-4">
|
|
36
|
+
<p class="text-muted-foreground text-sm">{f.question}</p>
|
|
37
|
+
<div class="flex items-center gap-2" data-feedback-actions>
|
|
38
|
+
<button class={buttonClass} data-feedback-value="yes" type="button">
|
|
39
|
+
<Icon name="thumbs-up" size={16} />
|
|
40
|
+
{f.yes}
|
|
41
|
+
</button>
|
|
42
|
+
<button class={buttonClass} data-feedback-value="no" type="button">
|
|
43
|
+
<Icon name="thumbs-down" size={16} />
|
|
44
|
+
{f.no}
|
|
45
|
+
</button>
|
|
46
|
+
</div>
|
|
47
|
+
<p
|
|
48
|
+
class="hidden text-muted-foreground text-sm focus:outline-none"
|
|
49
|
+
data-feedback-thanks
|
|
50
|
+
role="status"
|
|
51
|
+
tabindex="-1"
|
|
52
|
+
>
|
|
53
|
+
{f.thanks}
|
|
54
|
+
</p>
|
|
36
55
|
</div>
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
56
|
+
{
|
|
57
|
+
comments && (
|
|
58
|
+
<form class="mt-4 grid gap-2" data-feedback-form hidden>
|
|
59
|
+
<label class="text-muted-foreground text-sm" for="blume-feedback-comment">
|
|
60
|
+
{f.comment}
|
|
61
|
+
</label>
|
|
62
|
+
<textarea
|
|
63
|
+
class="w-full resize-y rounded-blume border border-border bg-background px-3 py-2 text-foreground text-sm outline-none transition-colors focus:border-foreground"
|
|
64
|
+
id="blume-feedback-comment"
|
|
65
|
+
maxlength={COMMENT_MAX_LENGTH}
|
|
66
|
+
name="comment"
|
|
67
|
+
rows="3"
|
|
68
|
+
></textarea>
|
|
69
|
+
<div>
|
|
70
|
+
<button class={buttonClass} type="submit">
|
|
71
|
+
{f.send}
|
|
72
|
+
</button>
|
|
73
|
+
</div>
|
|
74
|
+
</form>
|
|
75
|
+
)
|
|
76
|
+
}
|
|
45
77
|
</section>
|
|
46
78
|
|
|
47
79
|
<script>
|
|
48
|
-
import {
|
|
49
|
-
|
|
50
|
-
// Run on the initial load and again after every client-router swap, which
|
|
51
|
-
// rebuilds the rating widget from server-rendered markup — the handlers
|
|
52
|
-
// below always bind to the freshly swapped-in elements.
|
|
53
|
-
const initFeedback = () => {
|
|
54
|
-
const root = document.querySelector("[data-blume-page-feedback]");
|
|
55
|
-
if (!root) {
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
const actions = root.querySelector("[data-feedback-actions]");
|
|
59
|
-
const thanks = root.querySelector("[data-feedback-thanks]");
|
|
60
|
-
for (const button of root.querySelectorAll("[data-feedback-value]")) {
|
|
61
|
-
button.addEventListener("click", () => {
|
|
62
|
-
track("feedback", {
|
|
63
|
-
helpful: button.getAttribute("data-feedback-value") ?? "",
|
|
64
|
-
path: location.pathname,
|
|
65
|
-
title: document.title,
|
|
66
|
-
});
|
|
67
|
-
actions?.classList.add("hidden");
|
|
68
|
-
thanks?.classList.remove("hidden");
|
|
69
|
-
// The clicked button just disappeared under focus; hand focus to the
|
|
70
|
-
// (live) thanks line so the reader isn't dropped at the top of the page.
|
|
71
|
-
if (thanks instanceof HTMLElement) {
|
|
72
|
-
thanks.focus();
|
|
73
|
-
}
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
};
|
|
80
|
+
import { initFeedback, syncFeedbackVisibility } from "./page-feedback.ts";
|
|
77
81
|
|
|
78
82
|
initFeedback();
|
|
79
83
|
document.addEventListener("astro:after-swap", initFeedback);
|
|
84
|
+
addEventListener("blume:consent", syncFeedbackVisibility);
|
|
80
85
|
</script>
|
|
@@ -5,8 +5,8 @@ import { createIconSprite } from "../icon-sprite.ts";
|
|
|
5
5
|
// page that wants Blume's chrome (document shell, header, theme, fonts) without
|
|
6
6
|
// the docs sidebar + prose + TOC grid that RootLayout hard-codes. It renders the
|
|
7
7
|
// `<head>`, theme/banner pre-paint scripts, banner, and header, then a single
|
|
8
|
-
// full-width `<slot />` for the body
|
|
9
|
-
//
|
|
8
|
+
// full-width `<slot />` for the body, then an optional `footer` slot, or the
|
|
9
|
+
// site footer `footer` configures when the page fills no slot. Import it into a custom page and pull props from `blume:data`:
|
|
10
10
|
//
|
|
11
11
|
// import PageLayout from "blume/components/layout/PageLayout.astro";
|
|
12
12
|
// import data from "blume:data";
|
|
@@ -39,12 +39,19 @@ import {
|
|
|
39
39
|
import { buildStructuredData } from "../../seo/jsonld.ts";
|
|
40
40
|
import { normalizeXHandle } from "../../seo/x-handle.ts";
|
|
41
41
|
import Icon from "../Icon.astro";
|
|
42
|
-
import { stripBase, withBase } from "../islands/base-path.ts";
|
|
42
|
+
import { stripBase, withBase, withMountedBase } from "../islands/base-path.ts";
|
|
43
|
+
import { routeSetFor } from "../../core/locale-links.ts";
|
|
44
|
+
import {
|
|
45
|
+
browserLanguageTargets,
|
|
46
|
+
LOCALE_REDIRECT_SCRIPT,
|
|
47
|
+
} from "./locale-redirect.ts";
|
|
43
48
|
import { pageDirection, pageLocale } from "./page-locale.ts";
|
|
44
49
|
import { searchLocaleFor } from "./search-locale.ts";
|
|
45
50
|
import "blume:theme";
|
|
46
51
|
import { ClientRouter } from "astro:transitions";
|
|
47
52
|
import Analytics from "./Analytics.astro";
|
|
53
|
+
import ConsentBanner from "./ConsentBanner.astro";
|
|
54
|
+
import ConsentHead from "./ConsentHead.astro";
|
|
48
55
|
import Banner from "./Banner.astro";
|
|
49
56
|
import DiscoveryLinks from "./DiscoveryLinks.astro";
|
|
50
57
|
import Favicon from "./Favicon.astro";
|
|
@@ -57,6 +64,9 @@ import {
|
|
|
57
64
|
import Header from "./Header.astro";
|
|
58
65
|
import { currentTabForRoute } from "./nav-utils.ts";
|
|
59
66
|
import NavTabMenu from "./NavTabMenu.astro";
|
|
67
|
+
import DrawerSwitchers from "./DrawerSwitchers.astro";
|
|
68
|
+
import SiteFooter from "./SiteFooter.astro";
|
|
69
|
+
import SiteMetatags from "./SiteMetatags.astro";
|
|
60
70
|
import WebMcp from "./WebMcp.astro";
|
|
61
71
|
|
|
62
72
|
interface Props {
|
|
@@ -195,6 +205,8 @@ const clientDataJson = clientData
|
|
|
195
205
|
: null;
|
|
196
206
|
|
|
197
207
|
const strings = ui ?? EN_UI;
|
|
208
|
+
// The consent adapter (`consent`), site-wide: analytics waits for the reader.
|
|
209
|
+
const consent = data.config.consent;
|
|
198
210
|
// Merge over the English defaults so a label missing from a translation (or
|
|
199
211
|
// from a not-yet-regenerated snapshot) still renders instead of coming out
|
|
200
212
|
// blank — the PageActions pattern.
|
|
@@ -219,7 +231,7 @@ const activeTab = currentTabForRoute(navigation.tabs, route, navigation.root);
|
|
|
219
231
|
// llms.txt index), and the homepage HTTP `Link` header already advertises it,
|
|
220
232
|
// so the head is its HTML counterpart on hosts that can't set that header.
|
|
221
233
|
// Advertising a mirror for any other custom route would 404.
|
|
222
|
-
const markdownMirror = route === "/" ?
|
|
234
|
+
const markdownMirror = route === "/" ? withMountedBase("/index.md") : null;
|
|
223
235
|
|
|
224
236
|
// Derive canonical + og:image from the site URL the same way the catch-all does
|
|
225
237
|
// for content pages, so a custom page gets both for free. The matching OG card
|
|
@@ -230,8 +242,9 @@ const markdownMirror = route === "/" ? withBase("/index.md") : null;
|
|
|
230
242
|
const ogSlug = route === "/" ? "index" : route.slice(1);
|
|
231
243
|
const ogCardGenerated = !Astro.routePattern.includes("[");
|
|
232
244
|
// Absolute URLs carry the deployment base too (`site + base + route`), since the
|
|
233
|
-
// page is served under it
|
|
234
|
-
|
|
245
|
+
// page is served under it — even when the route starts with the base's own
|
|
246
|
+
// name. `withMountedBase` handles a root base as a no-op.
|
|
247
|
+
const basedRoute = withMountedBase(route);
|
|
235
248
|
// The schema accepts a trailing-slash site URL (`https://docs.example.com/`);
|
|
236
249
|
// strip it before joining with the root-relative route so canonical/og URLs
|
|
237
250
|
// don't come out double-slashed — the catch-all strips it the same way.
|
|
@@ -253,7 +266,7 @@ const absolutizeOgImage = (value: string): string =>
|
|
|
253
266
|
const resolvedOgImage = ogImage
|
|
254
267
|
? absolutizeOgImage(ogImage)
|
|
255
268
|
: ogEnabled && ogCardGenerated && siteBase
|
|
256
|
-
? `${siteBase}${encodeURI(
|
|
269
|
+
? `${siteBase}${encodeURI(withMountedBase(`/og/${ogSlug}.png`))}`
|
|
257
270
|
: null;
|
|
258
271
|
// Only the generated card has a known size and format, so its dimensions are
|
|
259
272
|
// declared for crawlers; a user-supplied `ogImage` could be any image.
|
|
@@ -290,6 +303,25 @@ const bannerKey = banner?.dismissible ? banner.key : null;
|
|
|
290
303
|
// Start the page's icon sprite before anything renders an icon (see
|
|
291
304
|
// icon-sprite.ts); <IconSprite /> at the end of the body emits it.
|
|
292
305
|
createIconSprite(Astro.locals);
|
|
306
|
+
|
|
307
|
+
// A visitor landing on the default language's home page goes to their
|
|
308
|
+
// browser's language (`i18n.routeByBrowserLanguage`, see locale-redirect.ts).
|
|
309
|
+
const localeTargets = browserLanguageTargets({
|
|
310
|
+
basePath: data.config.basePath,
|
|
311
|
+
i18n: data.config.i18n,
|
|
312
|
+
route,
|
|
313
|
+
routes: routeSetFor(data.routes),
|
|
314
|
+
});
|
|
315
|
+
const localeRedirect = localeTargets
|
|
316
|
+
? JSON.stringify(
|
|
317
|
+
Object.fromEntries(
|
|
318
|
+
Object.entries(localeTargets).map(([code, path]) => [
|
|
319
|
+
code,
|
|
320
|
+
withMountedBase(path),
|
|
321
|
+
])
|
|
322
|
+
)
|
|
323
|
+
)
|
|
324
|
+
: null;
|
|
293
325
|
---
|
|
294
326
|
|
|
295
327
|
<!doctype html>
|
|
@@ -297,6 +329,16 @@ createIconSprite(Astro.locals);
|
|
|
297
329
|
<head>
|
|
298
330
|
<meta charset="utf-8" />
|
|
299
331
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
332
|
+
{
|
|
333
|
+
localeRedirect && (
|
|
334
|
+
<script
|
|
335
|
+
data-default={data.config.i18n?.defaultLocale}
|
|
336
|
+
data-targets={localeRedirect}
|
|
337
|
+
is:inline
|
|
338
|
+
set:html={LOCALE_REDIRECT_SCRIPT}
|
|
339
|
+
/>
|
|
340
|
+
)
|
|
341
|
+
}
|
|
300
342
|
{/* Client-side navigation, matching RootLayout: same-origin link clicks
|
|
301
343
|
swap the DOM in place instead of tearing the document down, so no
|
|
302
344
|
browser paints a blank frame between pages. */}
|
|
@@ -362,6 +404,7 @@ createIconSprite(Astro.locals);
|
|
|
362
404
|
{description && <meta content={description} name="twitter:description" />}
|
|
363
405
|
{xSite && <meta content={xSite} name="twitter:site" />}
|
|
364
406
|
{xCreator && <meta content={xCreator} name="twitter:creator" />}
|
|
407
|
+
<SiteMetatags tags={data.config.metatags} />
|
|
365
408
|
{/* Agent discovery on every page, so a custom page built on PageLayout is
|
|
366
409
|
covered without passing a prop, the same way the docs pages are. */}
|
|
367
410
|
<DiscoveryLinks discovery={discovery} markdownMirror={markdownMirror} />
|
|
@@ -380,6 +423,7 @@ createIconSprite(Astro.locals);
|
|
|
380
423
|
)
|
|
381
424
|
}
|
|
382
425
|
<script data-mode={themeMode} is:inline set:html={THEME_INIT_SCRIPT} />
|
|
426
|
+
{consent && <ConsentHead consent={consent} />}
|
|
383
427
|
<Analytics analytics={analytics} />
|
|
384
428
|
</head>
|
|
385
429
|
<body class="bg-background font-sans text-foreground antialiased">
|
|
@@ -408,8 +452,27 @@ createIconSprite(Astro.locals);
|
|
|
408
452
|
transparent={transparentHeader}
|
|
409
453
|
/>
|
|
410
454
|
<main id="blume-content"><slot /></main>
|
|
411
|
-
|
|
455
|
+
{
|
|
456
|
+
Astro.slots.has("footer") ? (
|
|
457
|
+
<slot name="footer" />
|
|
458
|
+
) : (
|
|
459
|
+
<SiteFooter
|
|
460
|
+
footer={data.config.footer}
|
|
461
|
+
locale={locale}
|
|
462
|
+
navigation={navigation}
|
|
463
|
+
ui={strings}
|
|
464
|
+
/>
|
|
465
|
+
)
|
|
466
|
+
}
|
|
412
467
|
<WebMcp />
|
|
468
|
+
{
|
|
469
|
+
consent?.kind === "native" && (
|
|
470
|
+
<ConsentBanner
|
|
471
|
+
policy={consent.options.policy}
|
|
472
|
+
strings={strings.consent}
|
|
473
|
+
/>
|
|
474
|
+
)
|
|
475
|
+
}
|
|
413
476
|
{
|
|
414
477
|
// Mobile nav for chrome-only pages: the header's inline tab bar is hidden
|
|
415
478
|
// below `lg` and there's no sidebar drawer, so surface the tabs in a
|
|
@@ -424,6 +487,12 @@ createIconSprite(Astro.locals);
|
|
|
424
487
|
data-blume-nav-drawer
|
|
425
488
|
id="blume-nav-drawer"
|
|
426
489
|
>
|
|
490
|
+
<DrawerSwitchers
|
|
491
|
+
localeSwitch={localeSwitch}
|
|
492
|
+
route={route}
|
|
493
|
+
selectors={navigation.selectors}
|
|
494
|
+
switcherStrings={strings.languageSwitcher}
|
|
495
|
+
/>
|
|
427
496
|
<nav aria-label={navStrings.sections}>
|
|
428
497
|
<ul class="m-0 list-none p-0">
|
|
429
498
|
{navigation.tabs.map((tab) => (
|
|
@@ -439,7 +508,7 @@ createIconSprite(Astro.locals);
|
|
|
439
508
|
<a
|
|
440
509
|
aria-current={tab === activeTab ? "page" : undefined}
|
|
441
510
|
class="flex items-center gap-2 rounded-[0.65rem] px-2.5 py-1.5 font-medium text-muted-foreground text-sm transition-colors hover:bg-muted hover:text-foreground aria-[current=page]:bg-muted aria-[current=page]:text-foreground"
|
|
442
|
-
href={
|
|
511
|
+
href={withMountedBase(tab.href ?? tab.path)}
|
|
443
512
|
>
|
|
444
513
|
{tab.icon && (
|
|
445
514
|
<Icon class="shrink-0" name={tab.icon} size={14} />
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
import {
|
|
2
|
+
import { withMountedBase } from "../islands/base-path.ts";
|
|
3
3
|
import { EN_UI } from "../../core/i18n-ui.ts";
|
|
4
4
|
import type { UIStrings } from "../../core/i18n-ui.ts";
|
|
5
5
|
import type { FlatPage } from "./nav-utils.ts";
|
|
@@ -31,7 +31,7 @@ const s = { ...EN_UI.page, ...strings };
|
|
|
31
31
|
{prev ? (
|
|
32
32
|
<a
|
|
33
33
|
class="flex max-w-[48%] flex-1 items-center gap-2 rounded-blume border border-border px-4 py-3 text-foreground transition-colors hover:border-foreground"
|
|
34
|
-
href={
|
|
34
|
+
href={withMountedBase(prev.route)}
|
|
35
35
|
>
|
|
36
36
|
<Icon class="rtl:-scale-x-100" name="arrow-left" size={16} />
|
|
37
37
|
<span class="min-w-0">
|
|
@@ -47,7 +47,7 @@ const s = { ...EN_UI.page, ...strings };
|
|
|
47
47
|
{next && (
|
|
48
48
|
<a
|
|
49
49
|
class="ms-auto flex max-w-[48%] flex-1 items-center justify-end gap-2 rounded-blume border border-border px-4 py-3 text-end text-foreground transition-colors hover:border-foreground"
|
|
50
|
-
href={
|
|
50
|
+
href={withMountedBase(next.route)}
|
|
51
51
|
>
|
|
52
52
|
<span class="min-w-0">
|
|
53
53
|
<span class="block text-muted-foreground text-xs">
|
|
@@ -4,6 +4,7 @@ import { createIconSprite } from "../icon-sprite.ts";
|
|
|
4
4
|
import "blume:theme";
|
|
5
5
|
import data from "blume:data";
|
|
6
6
|
import type {
|
|
7
|
+
BlumeBanner,
|
|
7
8
|
BlumeDataConfig,
|
|
8
9
|
BlumeFavicon,
|
|
9
10
|
DiscoveryHeadLinks,
|
|
@@ -14,6 +15,8 @@ import { NEW_TAB_HINT_ID } from "../../core/new-tab.ts";
|
|
|
14
15
|
import type { FontHead } from "../../theme/fonts.ts";
|
|
15
16
|
import type { Navigation } from "../../core/types.ts";
|
|
16
17
|
import Analytics from "./Analytics.astro";
|
|
18
|
+
import ConsentBanner from "./ConsentBanner.astro";
|
|
19
|
+
import ConsentHead from "./ConsentHead.astro";
|
|
17
20
|
import WebMcp from "./WebMcp.astro";
|
|
18
21
|
import Banner from "./Banner.astro";
|
|
19
22
|
import DiscoveryLinks from "./DiscoveryLinks.astro";
|
|
@@ -27,6 +30,7 @@ import {
|
|
|
27
30
|
import Header from "./Header.astro";
|
|
28
31
|
import { pageDirection, pageLocale } from "./page-locale.ts";
|
|
29
32
|
import { searchLocaleFor } from "./search-locale.ts";
|
|
33
|
+
import SiteMetatags from "./SiteMetatags.astro";
|
|
30
34
|
|
|
31
35
|
// A minimal shell for the Scalar API/AsyncAPI reference: Blume's banner + navbar
|
|
32
36
|
// on top, then a full-height region the reference mounts into. Unlike RootLayout
|
|
@@ -50,12 +54,7 @@ interface Props {
|
|
|
50
54
|
} | null;
|
|
51
55
|
favicon?: BlumeFavicon | null;
|
|
52
56
|
appleIcon?: BlumeFavicon | null;
|
|
53
|
-
banner?:
|
|
54
|
-
content: string;
|
|
55
|
-
link?: { text: string; href: string };
|
|
56
|
-
dismissible: boolean;
|
|
57
|
-
key: string;
|
|
58
|
-
} | null;
|
|
57
|
+
banner?: BlumeBanner | null;
|
|
59
58
|
analytics?: BlumeDataConfig["analytics"] | null;
|
|
60
59
|
navigation: Navigation;
|
|
61
60
|
route: string;
|
|
@@ -110,6 +109,8 @@ const locale = pageLocale(data.config.i18n, localeProp, Astro.currentLocale);
|
|
|
110
109
|
const dir = dirProp ?? pageDirection(data.config.i18n, locale);
|
|
111
110
|
|
|
112
111
|
const strings = ui ?? EN_UI;
|
|
112
|
+
// The consent adapter (`consent`), site-wide: analytics waits for the reader.
|
|
113
|
+
const consent = data.config.consent;
|
|
113
114
|
const navStrings = { ...EN_UI.nav, ...strings.nav };
|
|
114
115
|
// Scope search to the reference page's language on a multi-locale site.
|
|
115
116
|
const searchLocale = searchLocaleFor(data.config.i18n, locale);
|
|
@@ -128,6 +129,7 @@ createIconSprite(Astro.locals);
|
|
|
128
129
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
129
130
|
{noindex && <meta name="robots" content="noindex" />}
|
|
130
131
|
<title>{pageTitle}</title>
|
|
132
|
+
<SiteMetatags tags={data.config.metatags} />
|
|
131
133
|
<Favicon favicon={favicon} appleIcon={appleIcon} />
|
|
132
134
|
<Fonts cssVars={fontCssVars ?? []} />
|
|
133
135
|
<DiscoveryLinks discovery={discovery} />
|
|
@@ -137,6 +139,7 @@ createIconSprite(Astro.locals);
|
|
|
137
139
|
)
|
|
138
140
|
}
|
|
139
141
|
<script data-mode={themeMode} is:inline set:html={THEME_INIT_SCRIPT} />
|
|
142
|
+
{consent && <ConsentHead consent={consent} />}
|
|
140
143
|
<Analytics analytics={analytics} />
|
|
141
144
|
</head>
|
|
142
145
|
<body class="bg-background font-sans text-foreground antialiased">
|
|
@@ -170,6 +173,14 @@ createIconSprite(Astro.locals);
|
|
|
170
173
|
<script is:inline set:html={SCALAR_THEME_INIT_SCRIPT} />
|
|
171
174
|
</div>
|
|
172
175
|
<WebMcp />
|
|
176
|
+
{
|
|
177
|
+
consent?.kind === "native" && (
|
|
178
|
+
<ConsentBanner
|
|
179
|
+
policy={consent.options.policy}
|
|
180
|
+
strings={strings.consent}
|
|
181
|
+
/>
|
|
182
|
+
)
|
|
183
|
+
}
|
|
173
184
|
<IconSprite />
|
|
174
185
|
</body>
|
|
175
186
|
</html>
|