@farming-labs/theme 0.1.84 → 0.1.86
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/dist/docs-api.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import { getNextAppDir } from "./get-app-dir.mjs";
|
|
|
3
3
|
import fs from "node:fs";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import matter from "gray-matter";
|
|
6
|
-
import { buildDocsAskAIContext, createDocsAgentTraceContext, createDocsAgentTraceId, createDocsSitemapResponse, emitDocsAgentTraceEvent, emitDocsAnalyticsEvent, formatDocsAskAIPackageHints, getDocsMarkdownVaryHeader, hasDocsMarkdownSignatureAgent, normalizeDocsRelated, performDocsSearch, renderDocsMarkdownNotFound, renderDocsRelatedMarkdownLines, resolveAskAISearchRequestConfig, resolveChangelogConfig, resolveDocsI18n, resolveDocsLocale, resolveDocsSitemapConfig, resolvePageSidebarFolderIndexBehavior, resolveSearchRequestConfig } from "@farming-labs/docs";
|
|
6
|
+
import { buildDocsAskAIContext, createDocsAgentTraceContext, createDocsAgentTraceId, createDocsSitemapResponse, emitDocsAgentTraceEvent, emitDocsAnalyticsEvent, formatDocsAskAIPackageHints, getDocsMarkdownVaryHeader, hasDocsMarkdownSignatureAgent, normalizeDocsRelated, performDocsSearch, renderDocsMarkdownNotFound, renderDocsRelatedMarkdownLines, resolveAskAISearchRequestConfig, resolveChangelogConfig, resolveDocsI18n, resolveDocsLocale, resolveDocsSitemapConfig, resolvePageSidebarFolderIndexBehavior, resolveSearchRequestConfig, toDocsMarkdownUrl } from "@farming-labs/docs";
|
|
7
7
|
import { createDocsMcpHttpHandler, createFilesystemDocsMcpSource, readDocsSitemapManifest, resolveDocsMcpConfig } from "@farming-labs/docs/server";
|
|
8
8
|
|
|
9
9
|
//#region src/docs-api.ts
|
|
@@ -211,6 +211,7 @@ function buildAgentSpec({ origin, entry, i18n, search, mcp, feedback, llms, site
|
|
|
211
211
|
search: searchEnabled,
|
|
212
212
|
sitemap: sitemapConfig.enabled,
|
|
213
213
|
robots: robotsEnabled,
|
|
214
|
+
structuredData: true,
|
|
214
215
|
agentFeedback: feedback.enabled,
|
|
215
216
|
locales: localesEnabled
|
|
216
217
|
},
|
|
@@ -265,6 +266,20 @@ function buildAgentSpec({ origin, entry, i18n, search, mcp, feedback, llms, site
|
|
|
265
266
|
route: DEFAULT_ROBOTS_TXT_ROUTE,
|
|
266
267
|
defaultRoute: DEFAULT_ROBOTS_TXT_ROUTE
|
|
267
268
|
},
|
|
269
|
+
structuredData: {
|
|
270
|
+
enabled: true,
|
|
271
|
+
format: "application/ld+json",
|
|
272
|
+
schema: "https://schema.org/TechArticle",
|
|
273
|
+
fields: [
|
|
274
|
+
"headline",
|
|
275
|
+
"description",
|
|
276
|
+
"url",
|
|
277
|
+
"dateModified",
|
|
278
|
+
"breadcrumb"
|
|
279
|
+
],
|
|
280
|
+
canonicalUrlField: "url",
|
|
281
|
+
breadcrumbType: "BreadcrumbList"
|
|
282
|
+
},
|
|
268
283
|
search: {
|
|
269
284
|
enabled: searchEnabled,
|
|
270
285
|
endpoint: `${DEFAULT_DOCS_API_ROUTE}?query={query}`,
|
|
@@ -1554,7 +1569,7 @@ function generateLlmsTxt(indexes, options) {
|
|
|
1554
1569
|
if (siteDescription) llmsTxt += `> ${siteDescription}\n\n`;
|
|
1555
1570
|
llmsTxt += `## Pages\n\n`;
|
|
1556
1571
|
for (const page of indexes) {
|
|
1557
|
-
llmsTxt += `- [${page.title}](${baseUrl}${page.url})`;
|
|
1572
|
+
llmsTxt += `- [${page.title}](${baseUrl}${toDocsMarkdownUrl(page.url)})`;
|
|
1558
1573
|
if (page.description) llmsTxt += `: ${page.description}`;
|
|
1559
1574
|
llmsTxt += `\n`;
|
|
1560
1575
|
}
|
package/dist/docs-layout.mjs
CHANGED
|
@@ -11,7 +11,7 @@ import path from "node:path";
|
|
|
11
11
|
import matter from "gray-matter";
|
|
12
12
|
import { DocsLayout } from "fumadocs-ui/layouts/docs";
|
|
13
13
|
import { Suspense } from "react";
|
|
14
|
-
import { applySidebarFolderIndexBehavior, buildPageOpenGraph, buildPageTwitter, resolveChangelogConfig, resolveDocsAgentMdxContent, resolveDocsAnalyticsConfig, resolvePageSidebarFolderIndexBehavior, toDocsMarkdownUrl } from "@farming-labs/docs";
|
|
14
|
+
import { applySidebarFolderIndexBehavior, buildPageOpenGraph, buildPageTwitter, renderDocsPageStructuredDataJson, resolveChangelogConfig, resolveDocsAgentMdxContent, resolveDocsAnalyticsConfig, resolveDocsMetadataBaseUrl, resolvePageSidebarFolderIndexBehavior, toDocsMarkdownUrl } from "@farming-labs/docs";
|
|
15
15
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
16
16
|
|
|
17
17
|
//#region src/docs-layout.tsx
|
|
@@ -380,6 +380,41 @@ function buildReadingTimeMap(config, ctx, options) {
|
|
|
380
380
|
scan(docsDir, []);
|
|
381
381
|
return map;
|
|
382
382
|
}
|
|
383
|
+
function findDocsPageFile(dir) {
|
|
384
|
+
return ["page.mdx", "page.md"].map((fileName) => path.join(dir, fileName)).find(fs.existsSync);
|
|
385
|
+
}
|
|
386
|
+
function buildStructuredDataMap(config, ctx) {
|
|
387
|
+
const docsDir = ctx.docsDir;
|
|
388
|
+
const map = {};
|
|
389
|
+
const excludedDirs = getExcludedDocsDirs(config, ctx);
|
|
390
|
+
const baseUrl = resolveDocsMetadataBaseUrl(config);
|
|
391
|
+
function scan(dir, slugParts) {
|
|
392
|
+
if (!fs.existsSync(dir)) return;
|
|
393
|
+
if (isExcludedDir(dir, excludedDirs)) return;
|
|
394
|
+
const pagePath = findDocsPageFile(dir);
|
|
395
|
+
if (pagePath) {
|
|
396
|
+
const { data } = matter(fs.readFileSync(pagePath, "utf-8"));
|
|
397
|
+
const route = slugParts.length === 0 ? `/${ctx.entryPath}` : `/${ctx.entryPath}/${slugParts.join("/")}`;
|
|
398
|
+
const title = typeof data.title === "string" ? data.title : slugParts.at(-1)?.replace(/-/g, " ") || "Documentation";
|
|
399
|
+
const description = typeof data.description === "string" ? data.description : void 0;
|
|
400
|
+
const stat = fs.statSync(pagePath);
|
|
401
|
+
map[route] = renderDocsPageStructuredDataJson({
|
|
402
|
+
title,
|
|
403
|
+
description,
|
|
404
|
+
url: withLangInUrl(route, ctx.locale),
|
|
405
|
+
baseUrl,
|
|
406
|
+
entry: ctx.entryPath,
|
|
407
|
+
dateModified: stat.mtime.toISOString()
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
for (const name of fs.readdirSync(dir)) {
|
|
411
|
+
const full = path.join(dir, name);
|
|
412
|
+
if (fs.statSync(full).isDirectory()) scan(full, [...slugParts, name]);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
scan(docsDir, []);
|
|
416
|
+
return map;
|
|
417
|
+
}
|
|
383
418
|
/**
|
|
384
419
|
* Build a Next.js Metadata object from the docs config.
|
|
385
420
|
*
|
|
@@ -638,6 +673,7 @@ function createDocsLayout(config, options) {
|
|
|
638
673
|
enabledByDefault: readingTimeEnabledByDefault,
|
|
639
674
|
wordsPerMinute: readingTimeWordsPerMinute
|
|
640
675
|
});
|
|
676
|
+
const structuredDataMap = buildStructuredDataMap(config, localeContext);
|
|
641
677
|
const readingTimeEnabled = readingTimeEnabledByDefault || Object.keys(readingTimeMap).length > 0;
|
|
642
678
|
return function DocsLayoutWrapper({ children }) {
|
|
643
679
|
const tree = applySidebarFolderIndexBehavior(buildTree(config, localeContext, !!sidebarFlat), {
|
|
@@ -736,6 +772,7 @@ function createDocsLayout(config, options) {
|
|
|
736
772
|
lastUpdatedPosition,
|
|
737
773
|
readingTimeEnabled,
|
|
738
774
|
readingTimeMap,
|
|
775
|
+
structuredDataMap,
|
|
739
776
|
llmsTxtEnabled,
|
|
740
777
|
descriptionMap,
|
|
741
778
|
feedbackEnabled: feedbackConfig.enabled,
|
|
@@ -43,6 +43,10 @@ interface DocsPageClientProps {
|
|
|
43
43
|
readingTimeMap?: Record<string, number>;
|
|
44
44
|
/** Direct reading-time override for the current page. */
|
|
45
45
|
readingTime?: number | null;
|
|
46
|
+
/** Map of pathname → serialized Schema.org JSON-LD. */
|
|
47
|
+
structuredDataMap?: Record<string, string>;
|
|
48
|
+
/** Direct serialized Schema.org JSON-LD override for the current page. */
|
|
49
|
+
structuredData?: string;
|
|
46
50
|
/**
|
|
47
51
|
* Whether path-based reading time values should render by default.
|
|
48
52
|
* Explicit `readingTime` overrides can still render when this is false.
|
|
@@ -90,6 +94,8 @@ declare function DocsPageClient({
|
|
|
90
94
|
lastModified: lastModifiedProp,
|
|
91
95
|
readingTimeMap,
|
|
92
96
|
readingTime: readingTimeProp,
|
|
97
|
+
structuredDataMap,
|
|
98
|
+
structuredData: structuredDataProp,
|
|
93
99
|
readingTimeEnabled,
|
|
94
100
|
lastUpdatedEnabled,
|
|
95
101
|
lastUpdatedPosition,
|
|
@@ -5,6 +5,7 @@ import { PageActions } from "./page-actions.mjs";
|
|
|
5
5
|
import { useWindowSearchParams } from "./client-location.mjs";
|
|
6
6
|
import { DocsFeedback } from "./docs-feedback.mjs";
|
|
7
7
|
import { resolveClientLocale, withLangInUrl } from "./i18n.mjs";
|
|
8
|
+
import { escapeJsonLdForScript } from "./json-ld.mjs";
|
|
8
9
|
import { Children, Fragment, cloneElement, isValidElement, useEffect, useState } from "react";
|
|
9
10
|
import { DocsBody, DocsPage, EditOnGitHub } from "fumadocs-ui/layouts/docs/page";
|
|
10
11
|
import { createPortal } from "react-dom";
|
|
@@ -163,7 +164,7 @@ function TitleDecorations({ description, belowTitle }) {
|
|
|
163
164
|
if (!description && !belowTitle) return null;
|
|
164
165
|
return /* @__PURE__ */ jsx(Fragment$1, { children: Children.toArray([description, belowTitle].filter(Boolean)) });
|
|
165
166
|
}
|
|
166
|
-
function DocsPageClient({ tocEnabled, tocStyle = "default", breadcrumbEnabled = true, changelogBasePath, entry = "docs", locale, copyMarkdown = false, openDocs = false, openDocsProviders, pageActionsPosition = "below-title", pageActionsAlignment = "left", githubUrl, contentDir, githubBranch = "main", githubDirectory, editOnGithubUrl, lastModifiedMap, lastModified: lastModifiedProp, readingTimeMap, readingTime: readingTimeProp, readingTimeEnabled = false, lastUpdatedEnabled = true, lastUpdatedPosition = "footer", llmsTxtEnabled = false, descriptionMap, description, feedbackEnabled = false, feedbackQuestion, feedbackPlaceholder, feedbackPositiveLabel, feedbackNegativeLabel, feedbackSubmitLabel, feedbackOnFeedback, analytics = false, children }) {
|
|
167
|
+
function DocsPageClient({ tocEnabled, tocStyle = "default", breadcrumbEnabled = true, changelogBasePath, entry = "docs", locale, copyMarkdown = false, openDocs = false, openDocsProviders, pageActionsPosition = "below-title", pageActionsAlignment = "left", githubUrl, contentDir, githubBranch = "main", githubDirectory, editOnGithubUrl, lastModifiedMap, lastModified: lastModifiedProp, readingTimeMap, readingTime: readingTimeProp, structuredDataMap, structuredData: structuredDataProp, readingTimeEnabled = false, lastUpdatedEnabled = true, lastUpdatedPosition = "footer", llmsTxtEnabled = false, descriptionMap, description, feedbackEnabled = false, feedbackQuestion, feedbackPlaceholder, feedbackPositiveLabel, feedbackNegativeLabel, feedbackSubmitLabel, feedbackOnFeedback, analytics = false, children }) {
|
|
167
168
|
const fdTocStyle = tocStyle === "directional" ? "clerk" : void 0;
|
|
168
169
|
const [toc, setToc] = useState([]);
|
|
169
170
|
const [titlePortalHost, setTitlePortalHost] = useState(null);
|
|
@@ -175,6 +176,7 @@ function DocsPageClient({ tocEnabled, tocStyle = "default", breadcrumbEnabled =
|
|
|
175
176
|
const normalizedPath = (browserPath ?? pathname).replace(/\/$/, "") || "/";
|
|
176
177
|
const isChangelogRoute = !!(changelogBasePath && (normalizedPath === changelogBasePath || normalizedPath.startsWith(`${changelogBasePath}/`)));
|
|
177
178
|
const matchedReadingTime = readingTimeMap?.[normalizedPath];
|
|
179
|
+
const structuredDataJson = !isChangelogRoute ? structuredDataProp ?? structuredDataMap?.[normalizedPath] : void 0;
|
|
178
180
|
useEffect(() => {
|
|
179
181
|
if (!analytics) return;
|
|
180
182
|
emitClientAnalyticsEvent({
|
|
@@ -341,7 +343,10 @@ function DocsPageClient({ tocEnabled, tocStyle = "default", breadcrumbEnabled =
|
|
|
341
343
|
belowTitle: belowTitleBlock
|
|
342
344
|
}), titlePortalHost) : null;
|
|
343
345
|
const renderedChildren = Children.toArray(decoratedChildren);
|
|
344
|
-
return /* @__PURE__ */ jsxs(
|
|
346
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [structuredDataJson && /* @__PURE__ */ jsx("script", {
|
|
347
|
+
type: "application/ld+json",
|
|
348
|
+
dangerouslySetInnerHTML: { __html: escapeJsonLdForScript(structuredDataJson) }
|
|
349
|
+
}), /* @__PURE__ */ jsxs(DocsPage, {
|
|
345
350
|
full: false,
|
|
346
351
|
toc,
|
|
347
352
|
tableOfContent: {
|
|
@@ -428,7 +433,7 @@ function DocsPageClient({ tocEnabled, tocStyle = "default", breadcrumbEnabled =
|
|
|
428
433
|
]
|
|
429
434
|
})
|
|
430
435
|
]
|
|
431
|
-
});
|
|
436
|
+
})] });
|
|
432
437
|
}
|
|
433
438
|
|
|
434
439
|
//#endregion
|
package/dist/json-ld.mjs
ADDED
|
@@ -31,6 +31,7 @@ interface TanstackDocsLayoutProps {
|
|
|
31
31
|
description?: string;
|
|
32
32
|
readingTime?: number | null;
|
|
33
33
|
lastModified?: string;
|
|
34
|
+
structuredData?: string;
|
|
34
35
|
editOnGithubUrl?: string;
|
|
35
36
|
children: ReactNode;
|
|
36
37
|
}
|
|
@@ -41,6 +42,7 @@ declare function TanstackDocsLayout({
|
|
|
41
42
|
description,
|
|
42
43
|
readingTime,
|
|
43
44
|
lastModified,
|
|
45
|
+
structuredData,
|
|
44
46
|
editOnGithubUrl,
|
|
45
47
|
children
|
|
46
48
|
}: TanstackDocsLayoutProps): react_jsx_runtime0.JSX.Element;
|
package/dist/tanstack-layout.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { withLangInUrl } from "./i18n.mjs";
|
|
2
|
+
import { escapeJsonLdForScript } from "./json-ld.mjs";
|
|
2
3
|
import { DocsPageClient } from "./docs-page-client.mjs";
|
|
3
4
|
import { DocsAIFeatures } from "./docs-ai-features.mjs";
|
|
4
5
|
import { DocsCommandSearch } from "./docs-command-search.mjs";
|
|
@@ -8,7 +9,7 @@ import { LocaleThemeControl } from "./locale-theme-control.mjs";
|
|
|
8
9
|
import { DocsLayout } from "fumadocs-ui/layouts/docs";
|
|
9
10
|
import { Suspense } from "react";
|
|
10
11
|
import { applySidebarFolderIndexBehavior, resolveDocsAnalyticsConfig } from "@farming-labs/docs";
|
|
11
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
12
|
+
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
12
13
|
|
|
13
14
|
//#region src/tanstack-layout.tsx
|
|
14
15
|
function resolveTreeIcon(icon, registry) {
|
|
@@ -207,7 +208,7 @@ function resolveFeedbackConfig(feedback) {
|
|
|
207
208
|
function ForcedThemeScript({ theme }) {
|
|
208
209
|
return /* @__PURE__ */ jsx("script", { dangerouslySetInnerHTML: { __html: `document.documentElement.classList.remove('light','dark');document.documentElement.classList.add('${theme === "light" || theme === "dark" ? theme : "light"}');` } });
|
|
209
210
|
}
|
|
210
|
-
function TanstackDocsLayout({ config, tree, locale, description, readingTime, lastModified, editOnGithubUrl, children }) {
|
|
211
|
+
function TanstackDocsLayout({ config, tree, locale, description, readingTime, lastModified, structuredData, editOnGithubUrl, children }) {
|
|
211
212
|
const tocConfig = config.theme?.ui?.layout?.toc;
|
|
212
213
|
const tocEnabled = tocConfig?.enabled !== false;
|
|
213
214
|
const tocStyle = tocConfig?.style;
|
|
@@ -290,7 +291,7 @@ function TanstackDocsLayout({ config, tree, locale, description, readingTime, la
|
|
|
290
291
|
collapsible: sidebarProps.collapsible !== false,
|
|
291
292
|
flat: !!sidebarFlat
|
|
292
293
|
});
|
|
293
|
-
|
|
294
|
+
const layout = /* @__PURE__ */ jsxs(DocsLayout, {
|
|
294
295
|
tree: resolvedTree,
|
|
295
296
|
nav: {
|
|
296
297
|
title: navTitle,
|
|
@@ -364,6 +365,11 @@ function TanstackDocsLayout({ config, tree, locale, description, readingTime, la
|
|
|
364
365
|
})
|
|
365
366
|
]
|
|
366
367
|
});
|
|
368
|
+
if (!structuredData) return layout;
|
|
369
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("script", {
|
|
370
|
+
type: "application/ld+json",
|
|
371
|
+
dangerouslySetInnerHTML: { __html: escapeJsonLdForScript(structuredData) }
|
|
372
|
+
}), layout] });
|
|
367
373
|
}
|
|
368
374
|
|
|
369
375
|
//#endregion
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@farming-labs/theme",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.86",
|
|
4
4
|
"description": "Theme package for @farming-labs/docs — layout, provider, MDX components, and styles",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"docs",
|
|
@@ -139,7 +139,7 @@
|
|
|
139
139
|
"tsdown": "^0.20.3",
|
|
140
140
|
"typescript": "^5.9.3",
|
|
141
141
|
"vitest": "^3.2.4",
|
|
142
|
-
"@farming-labs/docs": "0.1.
|
|
142
|
+
"@farming-labs/docs": "0.1.86"
|
|
143
143
|
},
|
|
144
144
|
"peerDependencies": {
|
|
145
145
|
"@farming-labs/docs": ">=0.0.1",
|