@docubook/flame 1.5.2 → 1.5.4

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.
@@ -1281,7 +1281,7 @@ function Pagination({
1281
1281
  // .docu/components/Typography.tsx
1282
1282
  import { jsx as jsx3 } from "react/jsx-runtime";
1283
1283
  function Typography({ children }) {
1284
- return /* @__PURE__ */ jsx3("div", { className: "prose prose-zinc dark:prose-invert prose-code:font-code dark:prose-code:bg-stone-900/25 prose-code:bg-stone-50 prose-pre:bg-background max-lg:prose-headings:scroll-mt-54 prose-headings:scroll-mt-4 prose-code:text-sm prose-code:leading-6 dark:prose-code:text-white prose-code:text-stone-800 prose-code:p-1 prose-code:rounded-md prose-code:border prose-img:rounded-md prose-img:border prose-code:before:content-none prose-code:after:content-none prose-code:px-1.5 prose-code:overflow-x-auto prose-img:my-3 prose-h2:my-4 prose-h2:mt-8 w-[85vw] max-w-[500px]! min-w-full! pt-2 sm:mx-auto sm:w-full", children });
1284
+ return /* @__PURE__ */ jsx3("div", { className: "prose prose-zinc dark:prose-invert prose-code:font-code dark:prose-code:bg-stone-900/25 prose-code:bg-stone-50 prose-pre:bg-background max-lg:prose-headings:scroll-mt-54 prose-headings:scroll-mt-4 prose-code:text-sm prose-code:leading-6 dark:prose-code:text-white prose-code:text-stone-800 prose-code:p-1 prose-code:rounded-md prose-code:border prose-img:rounded-md prose-img:border prose-code:before:content-none prose-code:after:content-none prose-code:px-1.5 prose-code:overflow-x-auto prose-img:my-3 prose-h2:my-4 prose-h2:mt-8 max-w-full! w-full pt-2", children });
1285
1285
  }
1286
1286
 
1287
1287
  // .docu/components/EditWith.tsx
@@ -1707,49 +1707,57 @@ function DocsPage({
1707
1707
  "data-repo": repoUrl || ""
1708
1708
  }
1709
1709
  ),
1710
- /* @__PURE__ */ jsxs6("div", { className: "w-full min-w-0 flex-[7] px-4 py-4 lg:px-8 lg:py-8", children: [
1711
- /* @__PURE__ */ jsx9(DocsBreadcrumb, { paths: slug }),
1712
- /* @__PURE__ */ jsxs6(Typography, { children: [
1713
- /* @__PURE__ */ jsx9("h1", { className: "-mt-0.5 text-3xl", children: title }),
1714
- description && /* @__PURE__ */ jsx9("p", { className: "text-muted-foreground -mt-4 text-[16.5px]", children: description }),
1715
- /* @__PURE__ */ jsx9("div", { id: "mdx-content-island", children: content }),
1716
- compiledSource && /* @__PURE__ */ jsx9(
1717
- "script",
1718
- {
1719
- id: "mdx-compiled-source",
1720
- type: "application/json",
1721
- dangerouslySetInnerHTML: {
1722
- __html: JSON.stringify(compiledSource).replace(/<\//g, "\\u003C/")
1723
- }
1724
- }
1725
- ),
1726
- /* @__PURE__ */ jsxs6("div", { className: "border-base-300 my-8 flex items-center border-b-2 border-dashed", children: [
1727
- /* @__PURE__ */ jsx9(EditWith, { className: "text-muted-foreground", filePath }),
1728
- date && /* @__PURE__ */ jsxs6("p", { className: "text-muted-foreground ml-auto text-[13px]", children: [
1729
- "Last updated ",
1730
- formatDate2(date)
1731
- ] })
1732
- ] }),
1733
- /* @__PURE__ */ jsx9(
1734
- Pagination,
1735
- {
1736
- pathname,
1737
- prevIcon: /* @__PURE__ */ jsx9(ChevronLeft, { className: "h-3 w-3" }),
1738
- nextIcon: /* @__PURE__ */ jsx9(ChevronRight, { className: "h-3 w-3" })
1739
- }
1740
- ),
1741
- /* @__PURE__ */ jsx9(Footer, {})
1742
- ] })
1743
- ] }),
1744
- tocs.length > 0 && /* @__PURE__ */ jsx9(
1745
- "div",
1746
- {
1747
- id: "toc-island",
1748
- "data-tocs": tocsJson,
1749
- className: "sticky top-4 hidden h-[calc(100vh-8rem)] min-w-[240px] flex-[3] self-start lg:flex lg:px-4 lg:py-6",
1750
- children: /* @__PURE__ */ jsx9(Toc, { tocs })
1751
- }
1752
- )
1710
+ /* @__PURE__ */ jsxs6("div", { className: "flex w-full flex-col lg:flex-row 2xl:mx-auto 2xl:max-w-[1300px]", children: [
1711
+ /* @__PURE__ */ jsxs6(
1712
+ "div",
1713
+ {
1714
+ className: `w-full min-w-0 ${tocs.length > 0 ? "flex-[7]" : "mx-auto max-w-[820px]"} px-4 py-6 lg:px-12 lg:py-10`,
1715
+ children: [
1716
+ /* @__PURE__ */ jsx9(DocsBreadcrumb, { paths: slug }),
1717
+ /* @__PURE__ */ jsxs6(Typography, { children: [
1718
+ /* @__PURE__ */ jsx9("h1", { className: "-mt-0.5 text-3xl", children: title }),
1719
+ description && /* @__PURE__ */ jsx9("p", { className: "text-muted-foreground -mt-4 text-[16.5px]", children: description }),
1720
+ /* @__PURE__ */ jsx9("div", { id: "mdx-content-island", children: content }),
1721
+ compiledSource && /* @__PURE__ */ jsx9(
1722
+ "script",
1723
+ {
1724
+ id: "mdx-compiled-source",
1725
+ type: "application/json",
1726
+ dangerouslySetInnerHTML: {
1727
+ __html: JSON.stringify(compiledSource).replace(/<\//g, "\\u003C/")
1728
+ }
1729
+ }
1730
+ ),
1731
+ /* @__PURE__ */ jsxs6("div", { className: "border-base-300 my-8 flex items-center border-b-2 border-dashed", children: [
1732
+ /* @__PURE__ */ jsx9(EditWith, { className: "text-muted-foreground", filePath }),
1733
+ date && /* @__PURE__ */ jsxs6("p", { className: "text-muted-foreground ml-auto text-[13px]", children: [
1734
+ "Last updated ",
1735
+ formatDate2(date)
1736
+ ] })
1737
+ ] }),
1738
+ /* @__PURE__ */ jsx9(
1739
+ Pagination,
1740
+ {
1741
+ pathname,
1742
+ prevIcon: /* @__PURE__ */ jsx9(ChevronLeft, { className: "h-3 w-3" }),
1743
+ nextIcon: /* @__PURE__ */ jsx9(ChevronRight, { className: "h-3 w-3" })
1744
+ }
1745
+ ),
1746
+ /* @__PURE__ */ jsx9(Footer, {})
1747
+ ] })
1748
+ ]
1749
+ }
1750
+ ),
1751
+ tocs.length > 0 && /* @__PURE__ */ jsx9(
1752
+ "div",
1753
+ {
1754
+ id: "toc-island",
1755
+ "data-tocs": tocsJson,
1756
+ className: "sticky top-4 hidden h-[calc(100vh-8rem)] min-w-[240px] flex-[3] self-start lg:flex lg:px-4 lg:py-6",
1757
+ children: /* @__PURE__ */ jsx9(Toc, { tocs })
1758
+ }
1759
+ )
1760
+ ] })
1753
1761
  ]
1754
1762
  }
1755
1763
  ) });
@@ -1996,6 +2004,16 @@ function Anchor({
1996
2004
  return /* @__PURE__ */ jsx15("a", { href, className: baseClasses, ...props, children });
1997
2005
  }
1998
2006
 
2007
+ // docu-config-runtime:../../docu.json
2008
+ import { readFileSync as readFileSync2 } from "node:fs";
2009
+ import { join as join4 } from "node:path";
2010
+ var config = JSON.parse(readFileSync2(join4(process.cwd(), "docu.json"), "utf-8"));
2011
+ var docu_default = config;
2012
+
2013
+ // .docu/node/client-routes.ts
2014
+ var routes2 = docu_default.routes || [];
2015
+ var config2 = docu_default;
2016
+
1999
2017
  // .docu/components/Sublink.tsx
2000
2018
  import { jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
2001
2019
  function Sublink({
@@ -2015,7 +2033,7 @@ function Sublink({
2015
2033
  if (!items) return false;
2016
2034
  return currentPathname.startsWith(fullHref) && currentPathname !== fullHref;
2017
2035
  });
2018
- const levelPadding = cn(level === 1 && "pl-2", level === 2 && "pl-4", level >= 3 && "pl-6");
2036
+ const levelPadding = cn(level === 1 && "pl-4", level === 2 && "pl-8", level >= 3 && "pl-12");
2019
2037
  const isActive = currentPathname === fullHref || currentPathname === `${fullHref}.html`;
2020
2038
  const activeRef = useRef2(null);
2021
2039
  useEffect3(() => {
@@ -2035,19 +2053,38 @@ function Sublink({
2035
2053
  children: title
2036
2054
  }
2037
2055
  );
2038
- return /* @__PURE__ */ jsx16(
2039
- "div",
2040
- {
2041
- ref: activeRef,
2042
- className: cn(
2043
- "py-1",
2044
- levelPadding,
2045
- level >= 2 && "border-l-2",
2046
- level >= 2 && (isActive ? "border-primary" : "border-base-300")
2047
- ),
2048
- children: link
2056
+ if (level >= 1) {
2057
+ if (config2.sidebar?.context === "separator") {
2058
+ const sectionOffsets = { 1: 16, 2: 32 };
2059
+ let overlap = 14;
2060
+ for (let l = 1; l < level; l++) {
2061
+ overlap += sectionOffsets[l] ?? 48;
2062
+ }
2063
+ return /* @__PURE__ */ jsx16(
2064
+ "div",
2065
+ {
2066
+ ref: activeRef,
2067
+ className: cn("border-l-2", isActive ? "border-primary" : "border-transparent"),
2068
+ style: { marginLeft: `-${overlap}px` },
2069
+ children: /* @__PURE__ */ jsx16("div", { className: cn("py-1 pl-3", levelPadding), children: link })
2070
+ }
2071
+ );
2049
2072
  }
2050
- );
2073
+ return /* @__PURE__ */ jsx16(
2074
+ "div",
2075
+ {
2076
+ ref: activeRef,
2077
+ className: cn(
2078
+ "py-1",
2079
+ levelPadding,
2080
+ "border-l-2",
2081
+ isActive ? "border-primary" : "border-base-300"
2082
+ ),
2083
+ children: link
2084
+ }
2085
+ );
2086
+ }
2087
+ return /* @__PURE__ */ jsx16("div", { ref: activeRef, className: cn("py-1", levelPadding), children: link });
2051
2088
  }
2052
2089
  return /* @__PURE__ */ jsxs12("div", { ref: isActive ? activeRef : void 0, className: cn("flex flex-col", levelPadding), children: [
2053
2090
  /* @__PURE__ */ jsxs12(
@@ -2107,16 +2144,6 @@ function SidebarGroupHeader({ icon, title }) {
2107
2144
  ] });
2108
2145
  }
2109
2146
 
2110
- // docu-config-runtime:../../docu.json
2111
- import { readFileSync as readFileSync2 } from "node:fs";
2112
- import { join as join4 } from "node:path";
2113
- var config = JSON.parse(readFileSync2(join4(process.cwd(), "docu.json"), "utf-8"));
2114
- var docu_default = config;
2115
-
2116
- // .docu/node/client-routes.ts
2117
- var routes2 = docu_default.routes || [];
2118
- var config2 = docu_default;
2119
-
2120
2147
  // .docu/components/Menu.tsx
2121
2148
  import { jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
2122
2149
  function getCurrentContext(path) {
@@ -2137,91 +2164,64 @@ function Menu({ onNavigate, className = "", pathname, routes: routes3 = [] }) {
2137
2164
  );
2138
2165
  if (!currentPath.startsWith("/docs")) return null;
2139
2166
  const mode = config2.sidebar?.context || "dropdown";
2140
- const isItemActive = (itemHref, parentRouteHref) => {
2141
- const fullHref = `/docs${parentRouteHref}${itemHref}`;
2142
- return currentPath === fullHref || currentPath === `${fullHref}.html`;
2167
+ const navProps = {
2168
+ "aria-label": "Documentation navigation",
2169
+ className: cn("transition-all duration-200", className)
2143
2170
  };
2171
+ const renderBorderItem = (item, parentRouteHref, key) => {
2172
+ const fullHref = `/docs${parentRouteHref}${item.href}`;
2173
+ const isActive = currentPath === fullHref || currentPath === `${fullHref}.html`;
2174
+ return /* @__PURE__ */ jsx18("li", { children: /* @__PURE__ */ jsx18(
2175
+ "div",
2176
+ {
2177
+ className: cn(
2178
+ "-ml-[14px] border-l-2",
2179
+ isActive ? "border-primary" : "border-transparent"
2180
+ ),
2181
+ children: /* @__PURE__ */ jsx18("div", { className: "pl-3", children: /* @__PURE__ */ jsx18(
2182
+ Sublink,
2183
+ {
2184
+ ...item,
2185
+ href: item.href,
2186
+ level: 0,
2187
+ onNavigate,
2188
+ parentHref: `/docs${parentRouteHref}`
2189
+ }
2190
+ ) })
2191
+ }
2192
+ ) }, key);
2193
+ };
2194
+ const sharedUlClasses = "border-base-300 flex flex-col gap-0.5 border-l-2 pb-0.5 pl-3 pt-0.5";
2144
2195
  if (mode === "separator") {
2145
2196
  const contextRoutes = menuRoutes.filter((r) => r.context);
2146
2197
  if (contextRoutes.length === 0) {
2147
- return /* @__PURE__ */ jsx18(
2148
- "nav",
2198
+ return /* @__PURE__ */ jsx18("nav", { ...navProps, children: /* @__PURE__ */ jsx18("ul", { className: sharedUlClasses, children: menuRoutes.map((route) => renderBorderItem(route, "", route.href)) }) });
2199
+ }
2200
+ return /* @__PURE__ */ jsx18("nav", { ...navProps, children: contextRoutes.map((route, i) => /* @__PURE__ */ jsxs14("div", { className: i > 0 ? "mt-6 lg:mt-8" : "", children: [
2201
+ /* @__PURE__ */ jsx18(
2202
+ SidebarGroupHeader,
2149
2203
  {
2150
- "aria-label": "Documentation navigation",
2151
- className: cn("transition-all duration-200", className),
2152
- children: /* @__PURE__ */ jsx18("ul", { className: "flex flex-col gap-0.5 py-4", children: menuRoutes.map((route) => /* @__PURE__ */ jsx18("li", { children: /* @__PURE__ */ jsx18(
2153
- Sublink,
2154
- {
2155
- ...route,
2156
- href: route.href,
2157
- level: 0,
2158
- onNavigate,
2159
- parentHref: "/docs"
2160
- }
2161
- ) }, route.href)) })
2204
+ icon: route.context?.icon,
2205
+ title: route.context?.title || route.title
2162
2206
  }
2163
- );
2164
- }
2165
- return /* @__PURE__ */ jsx18(
2166
- "nav",
2167
- {
2168
- "aria-label": "Documentation navigation",
2169
- className: cn("transition-all duration-200", className),
2170
- children: contextRoutes.map((route, i) => /* @__PURE__ */ jsxs14("div", { className: i > 0 ? "mt-6 lg:mt-8" : "", children: [
2171
- /* @__PURE__ */ jsx18(
2172
- SidebarGroupHeader,
2173
- {
2174
- icon: route.context?.icon,
2175
- title: route.context?.title || route.title
2176
- }
2177
- ),
2178
- /* @__PURE__ */ jsx18("ul", { className: "border-base-300 flex flex-col gap-0.5 border-l-2 pb-0.5 pl-3 pt-0.5", children: route.items?.map((item) => {
2179
- const isActive = isItemActive(item.href, route.href);
2180
- return /* @__PURE__ */ jsx18("li", { children: /* @__PURE__ */ jsx18(
2181
- "div",
2182
- {
2183
- className: cn(
2184
- "-ml-[14px] border-l-2",
2185
- isActive ? "border-primary" : "border-transparent"
2186
- ),
2187
- children: /* @__PURE__ */ jsx18("div", { className: "pl-3", children: /* @__PURE__ */ jsx18(
2188
- Sublink,
2189
- {
2190
- ...item,
2191
- href: item.href,
2192
- level: 0,
2193
- onNavigate,
2194
- parentHref: `/docs${route.href}`
2195
- }
2196
- ) })
2197
- }
2198
- ) }, item.href);
2199
- }) })
2200
- ] }, route.href))
2201
- }
2202
- );
2207
+ ),
2208
+ /* @__PURE__ */ jsx18("ul", { className: sharedUlClasses, children: route.items?.map((item) => renderBorderItem(item, route.href, item.href)) })
2209
+ ] }, route.href)) });
2203
2210
  }
2204
2211
  const isDocsRoot = currentPath === "/docs" || currentPath === "/docs/";
2205
2212
  const currentContext = isDocsRoot ? menuRoutes[0]?.href.replace(/^\/+|\/+$/, "") : getCurrentContext(currentPath);
2206
2213
  const contextRoute = isDocsRoot && menuRoutes[0] ? currentContext ? getContextRoute(currentContext, menuRoutes) : menuRoutes[0] : currentContext ? getContextRoute(currentContext, menuRoutes) : void 0;
2207
2214
  if (!contextRoute) return null;
2208
- return /* @__PURE__ */ jsx18(
2209
- "nav",
2215
+ return /* @__PURE__ */ jsx18("nav", { ...navProps, children: /* @__PURE__ */ jsx18("ul", { className: "flex flex-col gap-0.5 py-4", children: /* @__PURE__ */ jsx18("li", { children: /* @__PURE__ */ jsx18(
2216
+ Sublink,
2210
2217
  {
2211
- "aria-label": "Documentation navigation",
2212
- className: cn("transition-all duration-200", className),
2213
- children: /* @__PURE__ */ jsx18("ul", { className: "flex flex-col gap-0.5 py-4", children: /* @__PURE__ */ jsx18("li", { children: /* @__PURE__ */ jsx18(
2214
- Sublink,
2215
- {
2216
- ...contextRoute,
2217
- href: contextRoute.href,
2218
- level: 0,
2219
- onNavigate,
2220
- parentHref: "/docs"
2221
- }
2222
- ) }, contextRoute.title) })
2218
+ ...contextRoute,
2219
+ href: contextRoute.href,
2220
+ level: 0,
2221
+ onNavigate,
2222
+ parentHref: "/docs"
2223
2223
  }
2224
- );
2224
+ ) }, contextRoute.title) }) });
2225
2225
  }
2226
2226
 
2227
2227
  // .docu/components/DocsLayout.tsx
@@ -2336,6 +2336,23 @@ function htmlShell(opts) {
2336
2336
  const depthPrefix = depth === 0 ? "" : "../".repeat(depth);
2337
2337
  const assetPrefix = depthPrefix + "assets/";
2338
2338
  const resolvePath = (path) => path.startsWith("/") ? depthPrefix + path.slice(1) : path;
2339
+ let seoTags = "";
2340
+ if (opts.seo) {
2341
+ const s = opts.seo;
2342
+ const e = escapeHtml;
2343
+ seoTags = `
2344
+ <meta property="og:title" content="${e(title)}" />
2345
+ <meta property="og:description" content="${e(description)}" />
2346
+ <meta property="og:url" content="${e(s.url)}" />
2347
+ <meta property="og:type" content="website" />
2348
+ <meta property="og:site_name" content="${e(s.siteName)}" />
2349
+ <meta name="twitter:card" content="summary_large_image" />
2350
+ <link rel="canonical" href="${e(s.url)}" />`;
2351
+ if (s.image) {
2352
+ seoTags += `
2353
+ <meta property="og:image" content="${e(s.image)}" />`;
2354
+ }
2355
+ }
2339
2356
  return `<!DOCTYPE html>
2340
2357
  <html lang="en">
2341
2358
  <head>
@@ -2346,6 +2363,7 @@ function htmlShell(opts) {
2346
2363
  ${favicon ? `<link rel="icon" type="image/x-icon" href="${escapeHtml(resolvePath(favicon))}">` : ""}${themeStyle}
2347
2364
  <link rel="stylesheet" href="${escapeHtml(assetPrefix + css)}">
2348
2365
  ${csp ? `<meta http-equiv="Content-Security-Policy" content="${escapeHtml(csp)}">` : ""}
2366
+ ${seoTags}
2349
2367
  <script${nonceAttr}>try{if(localStorage.getItem("theme")==="dark")document.documentElement.classList.add("dark")}catch(e){}</script>${headInjection}
2350
2368
  </head>
2351
2369
  <body>
@@ -5,7 +5,7 @@ import {
5
5
  // package.json
6
6
  var package_default = {
7
7
  name: "@docubook/flame",
8
- version: "1.5.2",
8
+ version: "1.5.4",
9
9
  description: "A blazing-fast React + MDX framework powered by Bun, built for modern documentation experiences.",
10
10
  type: "module",
11
11
  bin: {
@@ -13,14 +13,14 @@ import {
13
13
  htmlShell,
14
14
  initSentry,
15
15
  loadPlugins
16
- } from "./chunk-QGEFJH47.js";
16
+ } from "./chunk-C67LPMQA.js";
17
17
  import {
18
18
  generateNonce,
19
19
  scanMdxFiles
20
20
  } from "./chunk-EOK6KATZ.js";
21
21
  import {
22
22
  logger
23
- } from "./chunk-GLOJMRT4.js";
23
+ } from "./chunk-GXQB4ETN.js";
24
24
  import {
25
25
  ASSETS_DIR,
26
26
  CACHE_FILE,
@@ -38,6 +38,27 @@ import { createHash } from "node:crypto";
38
38
  import { join, dirname } from "node:path";
39
39
  import React from "react";
40
40
  import { renderToString } from "react-dom/server";
41
+
42
+ // .docu/node/seo.ts
43
+ function buildSeoMeta(config, frontmatter, slug) {
44
+ const baseURL = config.meta?.baseURL?.replace(/\/+$/, "") || "";
45
+ const url = slug ? `${baseURL}/docs/${slug}` : `${baseURL}/`;
46
+ const result = {
47
+ url,
48
+ siteName: config.meta?.title || ""
49
+ };
50
+ const image = typeof frontmatter.image === "string" && frontmatter.image || config.meta?.ogImage;
51
+ if (image) {
52
+ try {
53
+ result.image = new URL(image, image.startsWith("/") ? baseURL : `${baseURL}/docs/`).href;
54
+ } catch {
55
+ result.image = image;
56
+ }
57
+ }
58
+ return result;
59
+ }
60
+
61
+ // .docu/node/build.impl.ts
41
62
  function parseArgs() {
42
63
  const args = process.argv.slice(2);
43
64
  return {
@@ -123,11 +144,13 @@ ${msg}`, { cause: err });
123
144
  const bodyExtra = builder?.collectBody(ctx);
124
145
  const depth = slug ? slug.split("/").length : 1;
125
146
  const favicon = docuConfig.meta?.favicon || "/docs/assets/images/favicon.ico";
147
+ const seo = buildSeoMeta(docuConfig, frontmatter, slug || "");
126
148
  let html = htmlShell({
127
149
  title,
128
150
  description,
129
151
  body,
130
152
  favicon,
153
+ seo,
131
154
  css: assetManifest.css,
132
155
  js: assetManifest.js,
133
156
  nonce,
@@ -298,11 +321,13 @@ async function runBuild() {
298
321
  }
299
322
  const landingPage = React.createElement(IndexPage);
300
323
  const landingFavicon = docuConfig.meta?.favicon || "/docs/assets/images/favicon.ico";
324
+ const landingSeo = buildSeoMeta(docuConfig, docuConfig.meta, "");
301
325
  const landingHtml = htmlShell({
302
326
  title: docuConfig.meta?.title || "DocuBook",
303
327
  description: docuConfig.meta?.description || "",
304
328
  body: renderToString(landingPage),
305
329
  favicon: landingFavicon,
330
+ seo: landingSeo,
306
331
  css: assetManifest.css,
307
332
  js: assetManifest.js,
308
333
  nonce: generateNonce(),
@@ -320,6 +345,7 @@ async function runBuild() {
320
345
  description: "",
321
346
  body: renderToString(notFoundPage),
322
347
  favicon: notFoundFavicon,
348
+ headExtra: ['<meta name="robots" content="noindex,follow">'],
323
349
  css: assetManifest.css,
324
350
  js: assetManifest.js,
325
351
  nonce: generateNonce(),
@@ -12,7 +12,7 @@ var WORKFLOW_FILE = join(WORKFLOW_DIR, "deploy.yml");
12
12
  async function runDeploy() {
13
13
  console.log("\u{1F4E6} Building for production...\n");
14
14
  process.env.NODE_ENV = "production";
15
- const { runBuildCli } = await import("./build.impl-FA57P3VC.js");
15
+ const { runBuildCli } = await import("./build.impl-CPFOQ7JW.js");
16
16
  await runBuildCli();
17
17
  await writeFile(join(DIST_DIR, ".nojekyll"), "");
18
18
  if (!existsSync(WORKFLOW_FILE)) {
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-EOK6KATZ.js";
8
8
  import {
9
9
  logger
10
- } from "./chunk-GLOJMRT4.js";
10
+ } from "./chunk-GXQB4ETN.js";
11
11
  import {
12
12
  DIST_DIR
13
13
  } from "./chunk-J5NMYSBJ.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  logger
3
- } from "./chunk-GLOJMRT4.js";
3
+ } from "./chunk-GXQB4ETN.js";
4
4
  import "./chunk-J5NMYSBJ.js";
5
5
 
6
6
  // .docu/node/clean.ts
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  runDeploy
3
- } from "./chunk-NXO2BF64.js";
3
+ } from "./chunk-VKMZLLG5.js";
4
4
  import "./chunk-J5NMYSBJ.js";
5
5
 
6
6
  // .docu/node/deploy.deno.ts
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  runDeploy
3
- } from "./chunk-NXO2BF64.js";
3
+ } from "./chunk-VKMZLLG5.js";
4
4
  import "./chunk-J5NMYSBJ.js";
5
5
 
6
6
  // .docu/node/deploy.node.ts
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  runPreview
3
- } from "./chunk-Q3AXTF2V.js";
3
+ } from "./chunk-XLH7Z4QO.js";
4
4
  import "./chunk-EOK6KATZ.js";
5
- import "./chunk-GLOJMRT4.js";
5
+ import "./chunk-GXQB4ETN.js";
6
6
  import "./chunk-J5NMYSBJ.js";
7
7
 
8
8
  // .docu/node/preview.deno.ts
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  runPreview
3
- } from "./chunk-Q3AXTF2V.js";
3
+ } from "./chunk-XLH7Z4QO.js";
4
4
  import "./chunk-EOK6KATZ.js";
5
- import "./chunk-GLOJMRT4.js";
5
+ import "./chunk-GXQB4ETN.js";
6
6
  import "./chunk-J5NMYSBJ.js";
7
7
 
8
8
  // .docu/node/preview.node.ts
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  runServer
3
- } from "./chunk-TEXSBNMR.js";
4
- import "./chunk-QGEFJH47.js";
3
+ } from "./chunk-BDWN6AHQ.js";
4
+ import "./chunk-C67LPMQA.js";
5
5
  import "./chunk-EOK6KATZ.js";
6
- import "./chunk-GLOJMRT4.js";
6
+ import "./chunk-GXQB4ETN.js";
7
7
  import "./chunk-J5NMYSBJ.js";
8
8
 
9
9
  // .docu/node/server.deno.ts
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  runServer
3
- } from "./chunk-TEXSBNMR.js";
4
- import "./chunk-QGEFJH47.js";
3
+ } from "./chunk-BDWN6AHQ.js";
4
+ import "./chunk-C67LPMQA.js";
5
5
  import "./chunk-EOK6KATZ.js";
6
- import "./chunk-GLOJMRT4.js";
6
+ import "./chunk-GXQB4ETN.js";
7
7
  import "./chunk-J5NMYSBJ.js";
8
8
 
9
9
  // .docu/node/server.node.ts
@@ -33,6 +33,7 @@ import { scanMdxFiles } from "./utils";
33
33
  import type { BuildCache, CliArgs } from "./types";
34
34
  import { generateNonce } from "./security";
35
35
  import type { PageMeta, PageContext } from "./plugin";
36
+ import { buildSeoMeta } from "./seo";
36
37
  import DocsPage from "../pages/docs/[[...slug]]";
37
38
  import IndexPage from "../pages/index";
38
39
  import NotFoundPage from "../pages/404";
@@ -147,11 +148,13 @@ async function renderDocsPage(
147
148
 
148
149
  const depth = slug ? slug.split("/").length : 1;
149
150
  const favicon = docuConfig.meta?.favicon || "/docs/assets/images/favicon.ico";
151
+ const seo = buildSeoMeta(docuConfig, frontmatter, slug || "");
150
152
  let html = htmlShell({
151
153
  title,
152
154
  description,
153
155
  body,
154
156
  favicon,
157
+ seo,
155
158
  css: assetManifest.css,
156
159
  js: assetManifest.js,
157
160
  nonce,
@@ -345,11 +348,13 @@ export async function runBuild(): Promise<void> {
345
348
 
346
349
  const landingPage = React.createElement(IndexPage);
347
350
  const landingFavicon = docuConfig.meta?.favicon || "/docs/assets/images/favicon.ico";
351
+ const landingSeo = buildSeoMeta(docuConfig, docuConfig.meta as Record<string, unknown>, "");
348
352
  const landingHtml = htmlShell({
349
353
  title: docuConfig.meta?.title || "DocuBook",
350
354
  description: docuConfig.meta?.description || "",
351
355
  body: renderToString(landingPage),
352
356
  favicon: landingFavicon,
357
+ seo: landingSeo,
353
358
  css: assetManifest.css,
354
359
  js: assetManifest.js,
355
360
  nonce: generateNonce(),
@@ -368,6 +373,7 @@ export async function runBuild(): Promise<void> {
368
373
  description: "",
369
374
  body: renderToString(notFoundPage),
370
375
  favicon: notFoundFavicon,
376
+ headExtra: ['<meta name="robots" content="noindex,follow">'],
371
377
  css: assetManifest.css,
372
378
  js: assetManifest.js,
373
379
  nonce: generateNonce(),
@@ -25,6 +25,7 @@ import { scanMdxFiles } from "./utils";
25
25
  import type { BuildCache, CliArgs } from "./types";
26
26
  import { generateNonce } from "./security";
27
27
  import type { PageMeta, PageContext } from "./plugin";
28
+ import { buildSeoMeta } from "./seo";
28
29
  import DocsPage from "../pages/docs/[[...slug]]";
29
30
  import IndexPage from "../pages/index";
30
31
  import NotFoundPage from "../pages/404";
@@ -140,11 +141,13 @@ async function renderDocsPage(
140
141
 
141
142
  const depth = slug ? slug.split("/").length : 1;
142
143
  const favicon = docuConfig.meta?.favicon || "/docs/assets/images/favicon.ico";
144
+ const seo = buildSeoMeta(docuConfig, frontmatter, slug || "");
143
145
  let html = htmlShell({
144
146
  title,
145
147
  description,
146
148
  body,
147
149
  favicon,
150
+ seo,
148
151
  css: assetManifest.css,
149
152
  js: assetManifest.js,
150
153
  nonce,
@@ -335,11 +338,13 @@ async function build() {
335
338
 
336
339
  const landingPage = React.createElement(IndexPage);
337
340
  const landingFavicon = docuConfig.meta?.favicon || "/docs/assets/images/favicon.ico";
341
+ const landingSeo = buildSeoMeta(docuConfig, {}, "");
338
342
  const landingHtml = htmlShell({
339
343
  title: docuConfig.meta?.title || "DocuBook",
340
344
  description: docuConfig.meta?.description || "",
341
345
  body: renderToString(landingPage),
342
346
  favicon: landingFavicon,
347
+ seo: landingSeo,
343
348
  css: assetManifest.css,
344
349
  js: assetManifest.js,
345
350
  nonce: generateNonce(),
@@ -358,6 +363,7 @@ async function build() {
358
363
  description: "",
359
364
  body: renderToString(notFoundPage),
360
365
  favicon: notFoundFavicon,
366
+ headExtra: ['<meta name="robots" content="noindex,follow">'],
361
367
  css: assetManifest.css,
362
368
  js: assetManifest.js,
363
369
  nonce: generateNonce(),