@dogsbay/docs-layout 0.2.0-beta.2 → 0.2.0-beta.20
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/package.json +3 -3
- package/src/DocsLayout.astro +43 -0
- package/src/TaxonomyTerm.astro +15 -4
- package/src/version-redirect.ts +23 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dogsbay/docs-layout",
|
|
3
|
-
"version": "0.2.0-beta.
|
|
3
|
+
"version": "0.2.0-beta.20",
|
|
4
4
|
"description": "Standard documentation layout components for Dogsbay",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
"./json-ld": "./src/json-ld.ts"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@dogsbay/ui": "0.2.0-beta.
|
|
33
|
-
"@dogsbay/primitives": "0.2.0-beta.
|
|
32
|
+
"@dogsbay/ui": "0.2.0-beta.20",
|
|
33
|
+
"@dogsbay/primitives": "0.2.0-beta.20"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"vitest": "^3.0.0"
|
package/src/DocsLayout.astro
CHANGED
|
@@ -256,6 +256,23 @@ interface Props {
|
|
|
256
256
|
* elements in `<body>`.
|
|
257
257
|
*/
|
|
258
258
|
category?: string[];
|
|
259
|
+
/**
|
|
260
|
+
* Custom-taxonomy values from `meta.taxonomies` — anything declared
|
|
261
|
+
* in `taxonomies:` config that isn't one of the five hardcoded
|
|
262
|
+
* built-ins (`tags`, `category`, `audience`, `type`, `status`).
|
|
263
|
+
*
|
|
264
|
+
* Each entry becomes one `<div data-pagefind-filter="<name>:<value>">`
|
|
265
|
+
* inside the indexed body, so the search dialog grows a checkbox
|
|
266
|
+
* group for every custom taxonomy automatically. No extra config
|
|
267
|
+
* needed beyond declaring the taxonomy in `dogsbay.config.yml` —
|
|
268
|
+
* the search dialog discovers facets at index time and renders
|
|
269
|
+
* whatever Pagefind reports.
|
|
270
|
+
*
|
|
271
|
+
* Display labels for the checkboxes flow through
|
|
272
|
+
* `taxonomyDisplay[<name>]` (same prefix/label config that drives
|
|
273
|
+
* chip rendering elsewhere). When unset, raw slugs are shown.
|
|
274
|
+
*/
|
|
275
|
+
taxonomies?: Record<string, string[]>;
|
|
259
276
|
/**
|
|
260
277
|
* Map of taxonomy name → index path for declared taxonomies.
|
|
261
278
|
* Used to wire links from built-in field badges (TypeBadge,
|
|
@@ -398,6 +415,7 @@ const {
|
|
|
398
415
|
pageType,
|
|
399
416
|
audience,
|
|
400
417
|
category,
|
|
418
|
+
taxonomies,
|
|
401
419
|
taxonomyIndexPaths,
|
|
402
420
|
taxonomyDisplay,
|
|
403
421
|
autoH1,
|
|
@@ -428,6 +446,16 @@ const showLlmActionsInline =
|
|
|
428
446
|
llmActionsEnabled
|
|
429
447
|
&& (llmActionsPlacement === "inline" || llmActionsPlacement === "both");
|
|
430
448
|
const llmFooterLink = !!llmActions && llmActions.footerLink !== false;
|
|
449
|
+
// Per-mount llms.txt URL — Dogsbay emits `<basePath>/llms.txt`
|
|
450
|
+
// (sitemap-index pattern), so the footer link must be basePath-
|
|
451
|
+
// prefixed too. Falls back to `/llms.txt` when basePath is empty
|
|
452
|
+
// or unset, matching the platform's host-root single-site case.
|
|
453
|
+
const llmsLinkHrefResolved = (() => {
|
|
454
|
+
const bp = (basePath ?? "").replace(/\/+$/, "");
|
|
455
|
+
if (!bp) return "/llms.txt";
|
|
456
|
+
const prefix = bp.startsWith("/") ? bp : `/${bp}`;
|
|
457
|
+
return `${prefix}/llms.txt`;
|
|
458
|
+
})();
|
|
431
459
|
|
|
432
460
|
// Compute href targets for the type / status badges. A field is
|
|
433
461
|
// linkable only when (a) the user declared a `taxonomies.<field>`
|
|
@@ -720,6 +748,20 @@ const siteIcon = '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"
|
|
|
720
748
|
))}
|
|
721
749
|
{status && <div hidden data-pagefind-filter={`status:${status}`}></div>}
|
|
722
750
|
{pageType && <div hidden data-pagefind-filter={`type:${pageType}`}></div>}
|
|
751
|
+
{/*
|
|
752
|
+
Custom-taxonomy filters. Any taxonomy declared in
|
|
753
|
+
`dogsbay.config.yml` that isn't one of the five built-ins
|
|
754
|
+
flows through here, so `difficulty: intermediate` (etc.)
|
|
755
|
+
becomes a real Pagefind facet checkbox automatically.
|
|
756
|
+
See plans/beta-launch-followups.md for context.
|
|
757
|
+
*/}
|
|
758
|
+
{taxonomies && Object.entries(taxonomies).flatMap(([name, values]) =>
|
|
759
|
+
Array.isArray(values)
|
|
760
|
+
? values.map((value) => (
|
|
761
|
+
<div hidden data-pagefind-filter={`${name}:${value}`}></div>
|
|
762
|
+
))
|
|
763
|
+
: []
|
|
764
|
+
)}
|
|
723
765
|
|
|
724
766
|
<div class:list={["mx-auto", wideLayout ? "max-w-7xl" : "max-w-3xl"]}>
|
|
725
767
|
{/*
|
|
@@ -802,6 +844,7 @@ const siteIcon = '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"
|
|
|
802
844
|
next={next}
|
|
803
845
|
copyright={copyright}
|
|
804
846
|
llmsLink={llmFooterLink}
|
|
847
|
+
llmsLinkHref={llmsLinkHrefResolved}
|
|
805
848
|
/>
|
|
806
849
|
</div>
|
|
807
850
|
</main>
|
package/src/TaxonomyTerm.astro
CHANGED
|
@@ -93,15 +93,22 @@ function segmentLabel(depth: number): string {
|
|
|
93
93
|
|
|
94
94
|
const titleSegments = term.fullPath.map((_, i) => segmentLabel(i));
|
|
95
95
|
|
|
96
|
-
// Breadcrumb segments —
|
|
96
|
+
// Breadcrumb segments — only link to prefixes that have their own
|
|
97
|
+
// term page. When a taxonomy is non-hierarchical, only full-path
|
|
98
|
+
// terms exist in `data.terms`; linking to `/tags/<prefix>/` for an
|
|
99
|
+
// intermediate segment would 404. Render those as plain text instead.
|
|
97
100
|
function breadcrumbs() {
|
|
98
|
-
const
|
|
101
|
+
const termKeys = new Set(data.terms.map((t) => t.fullPath.join("/")));
|
|
102
|
+
const out: { label: string; href?: string }[] = [
|
|
99
103
|
{ label: displayName, href: `${data.indexPath}/` },
|
|
100
104
|
];
|
|
101
105
|
for (let i = 0; i < term.fullPath.length - 1; i++) {
|
|
106
|
+
const prefix = term.fullPath.slice(0, i + 1).join("/");
|
|
102
107
|
out.push({
|
|
103
108
|
label: segmentLabel(i),
|
|
104
|
-
href:
|
|
109
|
+
href: termKeys.has(prefix)
|
|
110
|
+
? `${data.indexPath}/${prefix}/`
|
|
111
|
+
: undefined,
|
|
105
112
|
});
|
|
106
113
|
}
|
|
107
114
|
return out;
|
|
@@ -120,7 +127,11 @@ const crumbs = breadcrumbs();
|
|
|
120
127
|
<nav class="mb-3 text-sm text-muted-foreground" aria-label="Breadcrumbs">
|
|
121
128
|
{crumbs.map((c, i) => (
|
|
122
129
|
<span>
|
|
123
|
-
|
|
130
|
+
{c.href ? (
|
|
131
|
+
<a href={c.href} class="hover:text-foreground hover:underline">{c.label}</a>
|
|
132
|
+
) : (
|
|
133
|
+
<span>{c.label}</span>
|
|
134
|
+
)}
|
|
124
135
|
{i < crumbs.length - 1 && <span class="mx-1.5">/</span>}
|
|
125
136
|
</span>
|
|
126
137
|
))}
|
package/src/version-redirect.ts
CHANGED
|
@@ -35,6 +35,20 @@ export interface AxisRedirectConfig {
|
|
|
35
35
|
defaultLocale?: string;
|
|
36
36
|
/** Full set of declared locale ids. Empty/undefined → axis inactive. */
|
|
37
37
|
knownLocales?: string[];
|
|
38
|
+
/**
|
|
39
|
+
* First-segment names that aren't locale/version-axis-prefixable
|
|
40
|
+
* — e.g. taxonomy index paths like `tags`, `by-type`, `by-status`.
|
|
41
|
+
* Taxonomy routes emit a single global namespace shared across
|
|
42
|
+
* all locales / versions (one `/tags/` for the whole site, not
|
|
43
|
+
* one per locale), so the axis-redirect helper must skip them.
|
|
44
|
+
* Without this skip, chip hrefs to `/<basePath>/tags/...` would
|
|
45
|
+
* 302 to `/<basePath>/<defaultLocale>/tags/...` which 404s.
|
|
46
|
+
*
|
|
47
|
+
* Each entry is the first URL segment after basePath
|
|
48
|
+
* (no leading slash). Sourced from declared
|
|
49
|
+
* `taxonomies.<name>.indexPath` in `dogsbay.config.yml`.
|
|
50
|
+
*/
|
|
51
|
+
globalPrefixes?: string[];
|
|
38
52
|
}
|
|
39
53
|
|
|
40
54
|
/**
|
|
@@ -88,6 +102,15 @@ export function shouldRedirectToDefaultVersion(
|
|
|
88
102
|
// Skip Astro / Pagefind asset paths.
|
|
89
103
|
if (segments[0].startsWith("_") || segments[0] === "pagefind") return null;
|
|
90
104
|
|
|
105
|
+
// Skip global-namespace prefixes (taxonomy index paths and similar
|
|
106
|
+
// routes that don't live under per-locale / per-version trees).
|
|
107
|
+
// Without this, chip hrefs to `/docs/tags/concept/rag/` get
|
|
108
|
+
// redirected to `/docs/<defaultLocale>/tags/concept/rag/` which
|
|
109
|
+
// 404s — the taxonomy routes are emitted once at the unprefixed
|
|
110
|
+
// path. See plans/beta-launch-followups.md.
|
|
111
|
+
const globalPrefixes = config.globalPrefixes ?? [];
|
|
112
|
+
if (globalPrefixes.includes(segments[0])) return null;
|
|
113
|
+
|
|
91
114
|
// Greedy axis detection — locale outermost, version next.
|
|
92
115
|
const knownLocales = new Set(config.knownLocales ?? []);
|
|
93
116
|
const knownVersions = new Set(config.knownVersions ?? []);
|