boltdocs 2.9.2 → 3.0.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.
Files changed (108) hide show
  1. package/bin/boltdocs.js +2 -1
  2. package/dist/{adapters-uGz-UKQa.cjs → adapters-C5AWWGfb.cjs} +1 -1
  3. package/dist/{adapters-HVuXENAe.mjs → adapters-DEXNIv3x.mjs} +1 -1
  4. package/dist/{banner-D2NddBfF.d.ts → banner-CfdalYLL.d.ts} +1 -1
  5. package/dist/{banner-C_xkGxzI.d.cts → banner-DNSkgUsO.d.cts} +1 -1
  6. package/dist/{cache-B19MLTpN.cjs → cache-DETwlACe.cjs} +1 -1
  7. package/dist/{cache-CfhOTR3Q.mjs → cache-SF59enb3.mjs} +1 -1
  8. package/dist/client/index.cjs +260 -147
  9. package/dist/client/index.d.cts +4 -3
  10. package/dist/client/index.d.ts +4 -3
  11. package/dist/client/index.js +259 -147
  12. package/dist/client/mdx.cjs +1 -1
  13. package/dist/client/mdx.js +1 -1
  14. package/dist/client/primitives.cjs +2 -2
  15. package/dist/client/primitives.d.cts +10 -8
  16. package/dist/client/primitives.d.ts +10 -8
  17. package/dist/client/primitives.js +2 -2
  18. package/dist/config-B5uVv5q4.cjs +7 -0
  19. package/dist/config-D3_zDkHh.mjs +7 -0
  20. package/dist/{config-CnmfjOE4.cjs → config-JGkMJoJQ.cjs} +1 -1
  21. package/dist/csp-gaZ51xzq.mjs +6 -0
  22. package/dist/doctor-3MheVMwd.mjs +7 -0
  23. package/dist/{parser-CHsNUEhU.cjs → doctor-BR1B2Mkz.cjs} +1 -1
  24. package/dist/doctor-DQxLM202.cjs +7 -0
  25. package/dist/handler-Btd4t_67.mjs +28 -0
  26. package/dist/{headers-DuCAOgYX.cjs → headers-BXKxiPUv.cjs} +1 -1
  27. package/dist/headers-CXyf0auY.mjs +6 -0
  28. package/dist/{image-BCDyLHyD.js → image-C9md50h2.js} +14 -6
  29. package/dist/{image-DWdmichO.cjs → image-CR6UlaI5.cjs} +14 -6
  30. package/dist/{mdx-9QJoSITt.cjs → mdx-DJBg5DuL.cjs} +10 -23
  31. package/dist/{mdx-DFbspTP9.js → mdx-DhyMkc35.js} +10 -23
  32. package/dist/node/cli-entry.cjs +3 -3
  33. package/dist/node/cli-entry.mjs +3 -3
  34. package/dist/node/index.cjs +1 -1
  35. package/dist/node/index.d.cts +40 -19
  36. package/dist/node/index.d.mts +41 -20
  37. package/dist/node/index.mjs +1 -1
  38. package/dist/node-BUAMwxuS.cjs +105 -0
  39. package/dist/node-Clh72alT.mjs +105 -0
  40. package/dist/{package-D6O7a8qA.mjs → package-1GvyLw7z.mjs} +1 -1
  41. package/dist/{package-CVw_u5VT.cjs → package-3jQEMIvy.cjs} +1 -1
  42. package/dist/pages-external-BYa4JSda.mjs +6 -0
  43. package/dist/pages-external-CX2uyW95.cjs +6 -0
  44. package/dist/parser-CNIPHx4s.cjs +8 -0
  45. package/dist/parser-D0QHIQsi.mjs +8 -0
  46. package/dist/plugin-D9gURy-9.mjs +68 -0
  47. package/dist/plugin-N3zGyZXw.cjs +68 -0
  48. package/dist/rolldown-runtime-fkIsjY3S.mjs +6 -0
  49. package/dist/routes-BajCwrvX.cjs +6 -0
  50. package/dist/routes-CyrnmVuG.mjs +6 -0
  51. package/dist/routes-D6Tuu7Fs.cjs +6 -0
  52. package/dist/{search-dialog-DRNJsxOv.js → search-dialog-CQneRo8T.js} +1 -1
  53. package/dist/{search-dialog-BsAiQgnx.cjs → search-dialog-CwNh8lIN.cjs} +27 -30
  54. package/dist/{search-dialog-BhXg05Ri.cjs → search-dialog-D4rplZMv.cjs} +1 -0
  55. package/dist/{search-dialog-DaR66wl0.js → search-dialog-DaeSPvEo.js} +1 -0
  56. package/dist/{search-dialog-CaOO1Q4i.js → search-dialog-DoGobmuG.js} +28 -31
  57. package/dist/{search-dialog-CzwvKoLW.cjs → search-dialog-cHJoKjts.cjs} +1 -1
  58. package/dist/server/index.cjs +1 -1
  59. package/dist/server/index.d.mts +1 -1
  60. package/dist/server/index.mjs +1 -1
  61. package/dist/{shiki-adapter-BB71nVsG.cjs → shiki-adapter-CGTmrR6S.cjs} +1 -1
  62. package/dist/shiki-adapter-CXEGRnjr.mjs +6 -0
  63. package/dist/{doctor-BL6c8x2Q.cjs → shiki-adapter-Mr8_oT_9.cjs} +1 -1
  64. package/dist/{sidebar-BtJyWHy4.d.cts → sidebar-7gIifpBX.d.cts} +21 -4
  65. package/dist/{sidebar-C4fuRYYS.d.ts → sidebar-BAKgJ-Er.d.ts} +21 -4
  66. package/dist/types-generator-DVOnRVKU.mjs +26 -0
  67. package/dist/{utils-DexBrwiP.mjs → utils-B3xYMrpK.mjs} +1 -1
  68. package/dist/{utils-BWy_8ASj.cjs → utils-Bz1tG9Dg.cjs} +1 -1
  69. package/package.json +2 -1
  70. package/src/shared/types.ts +22 -3
  71. package/dist/config-BCqkPkjC.mjs +0 -7
  72. package/dist/config-BPWGa2W3.mjs +0 -6
  73. package/dist/config-D7ERJhqe.cjs +0 -7
  74. package/dist/csp-CUAEgrxR.mjs +0 -6
  75. package/dist/doctor-A17UhTRn.cjs +0 -7
  76. package/dist/doctor-hKOBLhBF.mjs +0 -7
  77. package/dist/handler-CyIBbZdb.mjs +0 -28
  78. package/dist/handler-eNNcucnf.mjs +0 -6
  79. package/dist/headers-DBzZ9yC6.mjs +0 -6
  80. package/dist/node/routes/worker.cjs +0 -6
  81. package/dist/node/routes/worker.d.cts +0 -2
  82. package/dist/node/routes/worker.d.mts +0 -2
  83. package/dist/node/routes/worker.mjs +0 -6
  84. package/dist/node-B-I15rGR.cjs +0 -105
  85. package/dist/node-FkxzriO7.mjs +0 -105
  86. package/dist/parser-8u0xHVc7.mjs +0 -6
  87. package/dist/parser-CLtGv_XH.cjs +0 -6
  88. package/dist/plugin-CHa0IT49.mjs +0 -61
  89. package/dist/plugin-Dqj9plKB.cjs +0 -61
  90. package/dist/routes-B2joDAlC.cjs +0 -6
  91. package/dist/routes-BTx0ngdX.mjs +0 -6
  92. package/dist/routes-Bm0CQvyL.mjs +0 -6
  93. package/dist/routes-CyKj3dzf.cjs +0 -6
  94. package/dist/shiki-adapter-CL-IQwKI.cjs +0 -6
  95. package/dist/shiki-adapter-CxTLkjew.mjs +0 -6
  96. package/dist/shiki-adapter-rQ087Lx3.mjs +0 -6
  97. package/dist/types-generator-BRyf4o9F.mjs +0 -26
  98. package/dist/types-generator-Cu2jQP-V.mjs +0 -6
  99. package/dist/worker-pool-CgOMozUz.cjs +0 -6
  100. package/dist/worker-pool-v6tW2MDQ.mjs +0 -6
  101. /package/dist/{csp-DbbF3R9Q.cjs → csp-CBysWlAf.cjs} +0 -0
  102. /package/dist/{generator-BaSvGlxR.mjs → generator-CcOBN5vI.mjs} +0 -0
  103. /package/dist/{generator-DsajVrDx.cjs → generator-DtUU3Cfk.cjs} +0 -0
  104. /package/dist/{handler-1LRMYeI4.cjs → handler-Dzf4dSnV.cjs} +0 -0
  105. /package/dist/{index-ZqgZUvwp.d.mts → index-CdJv4ocW.d.mts} +0 -0
  106. /package/dist/{meta-loader-CD3Yptr5.mjs → meta-loader-C4Hu9RN9.mjs} +0 -0
  107. /package/dist/{meta-loader-CjphwtS7.cjs → meta-loader-C9MKjAs0.cjs} +0 -0
  108. /package/dist/{types-generator-BqNKCbrx.cjs → types-generator-CYcHkDzZ.cjs} +0 -0
@@ -5,11 +5,11 @@
5
5
  */
6
6
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
7
7
  const require_icons_dev = require('../icons-dev-BryEFkJu.cjs');
8
- const require_image = require('../image-DWdmichO.cjs');
9
- const require_mdx = require('../mdx-9QJoSITt.cjs');
8
+ const require_image = require('../image-CR6UlaI5.cjs');
9
+ const require_mdx = require('../mdx-DJBg5DuL.cjs');
10
10
  const require_docs_layout = require('../docs-layout-3TpAt6MB.cjs');
11
- const require_search_dialog = require('../search-dialog-BhXg05Ri.cjs');
12
- const require_search_dialog$1 = require('../search-dialog-BsAiQgnx.cjs');
11
+ const require_search_dialog = require('../search-dialog-D4rplZMv.cjs');
12
+ const require_search_dialog$1 = require('../search-dialog-CwNh8lIN.cjs');
13
13
  let react = require("react");
14
14
  let react_router_dom = require("react-router-dom");
15
15
  let react_jsx_runtime = require("react/jsx-runtime");
@@ -20,6 +20,8 @@ let virtual_boltdocs_mdx_components = require("virtual:boltdocs-mdx-components")
20
20
  virtual_boltdocs_mdx_components = require_icons_dev.__toESM(virtual_boltdocs_mdx_components);
21
21
  let virtual_boltdocs_icons = require("virtual:boltdocs-icons");
22
22
  virtual_boltdocs_icons = require_icons_dev.__toESM(virtual_boltdocs_icons);
23
+ let isomorphic_dompurify = require("isomorphic-dompurify");
24
+ isomorphic_dompurify = require_icons_dev.__toESM(isomorphic_dompurify);
23
25
  let virtual_boltdocs_layout = require("virtual:boltdocs-layout");
24
26
  virtual_boltdocs_layout = require_icons_dev.__toESM(virtual_boltdocs_layout);
25
27
  let _bdocs_ssg = require("@bdocs/ssg");
@@ -159,6 +161,152 @@ const mdxComponentsDefault = {
159
161
  "404": NotFound
160
162
  };
161
163
 
164
+ //#endregion
165
+ //#region src/client/utils/i18n.ts
166
+ /**
167
+ * Retrieves the correct translation from a value that can be either
168
+ * a simple string or a map of locale-specific strings.
169
+ *
170
+ * @param value - The text to translate
171
+ * @param locale - The current active locale (e.g., 'en', 'es')
172
+ * @returns The translated string
173
+ */
174
+ function getTranslated(value, locale) {
175
+ if (!value) return "";
176
+ if (typeof value === "string") return value;
177
+ if (locale && value[locale]) return value[locale];
178
+ return Object.values(value)[0] || "";
179
+ }
180
+
181
+ //#endregion
182
+ //#region src/client/app/head.tsx
183
+ function Head({ siteTitle, siteDescription, routes }) {
184
+ const location = (0, react_router_dom.useLocation)();
185
+ const config = require_icons_dev.useConfig();
186
+ const { currentLocale, currentRoute } = require_icons_dev.useRoutes();
187
+ const route = (0, react.useMemo)(() => {
188
+ if (currentRoute) return currentRoute;
189
+ const normalizedPath = location.pathname.endsWith("/") && location.pathname.length > 1 ? location.pathname.slice(0, -1) : location.pathname;
190
+ return routes?.find?.((r) => {
191
+ return (r.path.endsWith("/") && r.path.length > 1 ? r.path.slice(0, -1) : r.path) === normalizedPath;
192
+ });
193
+ }, [
194
+ routes,
195
+ location.pathname,
196
+ currentRoute
197
+ ]);
198
+ const pageTitle = route?.title;
199
+ const translatedSiteDescription = getTranslated(siteDescription, currentLocale);
200
+ const pageDescription = route?.description || translatedSiteDescription || "";
201
+ const translatedSiteTitle = getTranslated(siteTitle, currentLocale);
202
+ const finalTitle = pageTitle ? `${pageTitle} | ${translatedSiteTitle}` : translatedSiteTitle;
203
+ const seo = route?.seo || {};
204
+ const canonicalUrl = seo.canonical || (config?.siteUrl && route?.path ? `${config.siteUrl.replace(/\/$/, "")}${route.path}` : void 0);
205
+ const ogUrl = seo["og:url"] || canonicalUrl || (typeof window !== "undefined" ? window.location.href : void 0);
206
+ const globalMetatags = config?.seo?.metatags || {};
207
+ const defaultOgImage = config?.seo?.thumbnails?.background;
208
+ let ogImage = seo["og:image"] || route?.coverImage || defaultOgImage;
209
+ if (ogImage && config?.siteUrl && !/^https?:\/\/|^\/\//.test(ogImage)) ogImage = `${config.siteUrl.endsWith("/") ? config.siteUrl.slice(0, -1) : config.siteUrl}${ogImage.startsWith("/") ? ogImage : `/${ogImage}`}`;
210
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Helmet, { children: [
211
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("title", { children: finalTitle }),
212
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("meta", {
213
+ name: "description",
214
+ content: pageDescription
215
+ }),
216
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("meta", {
217
+ property: "og:title",
218
+ content: finalTitle
219
+ }),
220
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("meta", {
221
+ property: "og:description",
222
+ content: pageDescription
223
+ }),
224
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("meta", {
225
+ property: "og:type",
226
+ content: "article"
227
+ }),
228
+ canonicalUrl && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("link", {
229
+ rel: "canonical",
230
+ href: canonicalUrl
231
+ }),
232
+ ogUrl && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("meta", {
233
+ property: "og:url",
234
+ content: ogUrl
235
+ }),
236
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("meta", {
237
+ name: "twitter:card",
238
+ content: ogImage ? "summary_large_image" : "summary"
239
+ }),
240
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("meta", {
241
+ name: "twitter:title",
242
+ content: finalTitle
243
+ }),
244
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("meta", {
245
+ name: "twitter:description",
246
+ content: pageDescription
247
+ }),
248
+ ogImage && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("meta", {
249
+ name: "twitter:image",
250
+ content: ogImage
251
+ }),
252
+ ogImage && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("meta", {
253
+ property: "og:image",
254
+ content: ogImage
255
+ }),
256
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("meta", {
257
+ name: "generator",
258
+ content: "Boltdocs"
259
+ }),
260
+ config?.seo?.verification?.google && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("meta", {
261
+ name: "google-site-verification",
262
+ content: config.seo.verification.google
263
+ }),
264
+ config?.seo?.verification?.bing && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("meta", {
265
+ name: "msvalidate.01",
266
+ content: config.seo.verification.bing
267
+ }),
268
+ config?.seo?.verification?.yandex && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("meta", {
269
+ name: "yandex-verification",
270
+ content: config.seo.verification.yandex
271
+ }),
272
+ config?.seo?.verification?.pinterest && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("meta", {
273
+ name: "p:domain_verify",
274
+ content: config.seo.verification.pinterest
275
+ }),
276
+ config?.seo?.verification?.facebook && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("meta", {
277
+ name: "facebook-domain-verification",
278
+ content: config.seo.verification.facebook
279
+ }),
280
+ Object.entries(globalMetatags).map(([key, value]) => {
281
+ return key.startsWith("og:") || key.startsWith("music:") || key.startsWith("video:") || key.startsWith("article:") || key.startsWith("book:") || key.startsWith("profile:") ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("meta", {
282
+ property: key,
283
+ content: value
284
+ }, key) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("meta", {
285
+ name: key,
286
+ content: value
287
+ }, key);
288
+ }),
289
+ Object.entries(seo).map(([key, value]) => {
290
+ if (key === "noindex" && value === true) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("meta", {
291
+ name: "robots",
292
+ content: "noindex"
293
+ }, "noindex");
294
+ if (key === "robots") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("meta", {
295
+ name: "robots",
296
+ content: value
297
+ }, "robots");
298
+ if (key === "canonical" || key === "og:url" || key === "og:image" || key === "twitter:image") return null;
299
+ return key.startsWith("og:") || key.startsWith("music:") || key.startsWith("video:") || key.startsWith("article:") || key.startsWith("book:") || key.startsWith("profile:") ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("meta", {
300
+ property: key,
301
+ content: value
302
+ }, key) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("meta", {
303
+ name: key,
304
+ content: value
305
+ }, key);
306
+ })
307
+ ] });
308
+ }
309
+
162
310
  //#endregion
163
311
  //#region src/client/collections/collections-context.tsx
164
312
  const CollectionsContext = (0, react.createContext)({});
@@ -251,6 +399,11 @@ function BoltdocsShell({ config, routes, components = {}, collectionsData }) {
251
399
  routeMap
252
400
  }),
253
401
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(I18nUpdater, { config }),
402
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Head, {
403
+ siteTitle: config.theme?.title,
404
+ siteDescription: config.theme?.description,
405
+ routes
406
+ }),
254
407
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_search_dialog$1.InternalErrorBoundary, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_router_dom.Outlet, {}) })
255
408
  ]
256
409
  })]
@@ -523,23 +676,6 @@ function GithubStars({ repo }) {
523
676
  });
524
677
  }
525
678
 
526
- //#endregion
527
- //#region src/client/utils/i18n.ts
528
- /**
529
- * Retrieves the correct translation from a value that can be either
530
- * a simple string or a map of locale-specific strings.
531
- *
532
- * @param value - The text to translate
533
- * @param locale - The current active locale (e.g., 'en', 'es')
534
- * @returns The translated string
535
- */
536
- function getTranslated(value, locale) {
537
- if (!value) return "";
538
- if (typeof value === "string") return value;
539
- if (locale && value[locale]) return value[locale];
540
- return Object.values(value)[0] || "";
541
- }
542
-
543
679
  //#endregion
544
680
  //#region src/client/hooks/use-navbar.ts
545
681
  function useNavbar() {
@@ -763,7 +899,7 @@ function Tabs({ tabs, routes }) {
763
899
  if (!iconName) return null;
764
900
  if (iconName.trim().startsWith("<svg")) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
765
901
  className: "h-4 w-4",
766
- dangerouslySetInnerHTML: { __html: iconName }
902
+ dangerouslySetInnerHTML: { __html: isomorphic_dompurify.default.sanitize(iconName, { USE_PROFILES: { svg: true } }) }
767
903
  });
768
904
  const icons = {
769
905
  ...require_icons_dev.icons_exports,
@@ -1026,7 +1162,7 @@ function createGtagAnalytics(config) {
1026
1162
  window.gtag?.("event", "page_view", {
1027
1163
  page_path: path,
1028
1164
  page_title: title || document.title,
1029
- send_to: config?.ga4?.measurementId
1165
+ send_to: config?.analytics?.ga4?.measurementId
1030
1166
  });
1031
1167
  },
1032
1168
  trackEvent: ({ action, category, label, value, params }) => {
@@ -1034,7 +1170,7 @@ function createGtagAnalytics(config) {
1034
1170
  event_category: category,
1035
1171
  event_label: label,
1036
1172
  value,
1037
- send_to: config?.ga4?.measurementId,
1173
+ send_to: config?.analytics?.ga4?.measurementId,
1038
1174
  ...params
1039
1175
  });
1040
1176
  },
@@ -1042,20 +1178,20 @@ function createGtagAnalytics(config) {
1042
1178
  window.gtag?.("event", "search", {
1043
1179
  search_term: query,
1044
1180
  results_count: resultsCount,
1045
- send_to: config?.ga4?.measurementId
1181
+ send_to: config?.analytics?.ga4?.measurementId
1046
1182
  });
1047
1183
  },
1048
1184
  trackDownload: (file, type) => {
1049
1185
  window.gtag?.("event", "file_download", {
1050
1186
  file_name: file,
1051
1187
  file_type: type || file.split(".").pop(),
1052
- send_to: config?.ga4?.measurementId
1188
+ send_to: config?.analytics?.ga4?.measurementId
1053
1189
  });
1054
1190
  },
1055
1191
  trackExternalLink: (url) => {
1056
1192
  window.gtag?.("event", "external_link", {
1057
1193
  link_url: url,
1058
- send_to: config?.ga4?.measurementId
1194
+ send_to: config?.analytics?.ga4?.measurementId
1059
1195
  });
1060
1196
  },
1061
1197
  isEnabled: true
@@ -1068,7 +1204,7 @@ function createDataLayerAnalytics(config) {
1068
1204
  event: "page_view",
1069
1205
  page_path: path,
1070
1206
  page_title: title || document.title,
1071
- send_to: config?.gtm?.tagId
1207
+ send_to: config?.analytics?.gtm?.tagId
1072
1208
  });
1073
1209
  },
1074
1210
  trackEvent: ({ action, category, label, value, params }) => {
@@ -1077,7 +1213,7 @@ function createDataLayerAnalytics(config) {
1077
1213
  event_category: category,
1078
1214
  event_label: label,
1079
1215
  value,
1080
- send_to: config?.gtm?.tagId,
1216
+ send_to: config?.analytics?.gtm?.tagId,
1081
1217
  ...params
1082
1218
  });
1083
1219
  },
@@ -1086,7 +1222,7 @@ function createDataLayerAnalytics(config) {
1086
1222
  event: "search",
1087
1223
  search_term: query,
1088
1224
  results_count: resultsCount,
1089
- send_to: config?.gtm?.tagId
1225
+ send_to: config?.analytics?.gtm?.tagId
1090
1226
  });
1091
1227
  },
1092
1228
  trackDownload: (file, type) => {
@@ -1094,14 +1230,14 @@ function createDataLayerAnalytics(config) {
1094
1230
  event: "file_download",
1095
1231
  file_name: file,
1096
1232
  file_type: type || file.split(".").pop(),
1097
- send_to: config?.gtm?.tagId
1233
+ send_to: config?.analytics?.gtm?.tagId
1098
1234
  });
1099
1235
  },
1100
1236
  trackExternalLink: (url) => {
1101
1237
  window.dataLayer?.push({
1102
1238
  event: "external_link",
1103
1239
  link_url: url,
1104
- send_to: config?.gtm?.tagId
1240
+ send_to: config?.analytics?.gtm?.tagId
1105
1241
  });
1106
1242
  },
1107
1243
  isEnabled: true
@@ -1303,13 +1439,13 @@ function I18nSelector({ className }) {
1303
1439
 
1304
1440
  //#endregion
1305
1441
  //#region src/client/components/ui-base/navbar.tsx
1306
- const SearchDialog$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("../search-dialog-CzwvKoLW.cjs")).then((m) => ({ default: m.SearchDialog })));
1442
+ const SearchDialog$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("../search-dialog-cHJoKjts.cjs")).then((m) => ({ default: m.SearchDialog })));
1307
1443
  function Navbar() {
1308
1444
  const { links, title, logo, logoProps, github, social, config } = useNavbar();
1309
1445
  const { routes, currentRoute, isCollectionPage, currentVersion, currentLocale } = require_icons_dev.useRoutes();
1310
1446
  const { isSidebarOpen, toggleSidebar } = require_docs_layout.useUI();
1311
1447
  const [isMobileMenuOpen, setIsMobileMenuOpen] = (0, react.useState)(false);
1312
- const themeConfig = config.theme || {};
1448
+ const themeConfig = config.theme;
1313
1449
  const isDocs = !!currentRoute?.filePath && !isCollectionPage;
1314
1450
  const hasTabs = themeConfig?.tabs && themeConfig.tabs.length > 0;
1315
1451
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_search_dialog.Navbar.Root, {
@@ -1339,15 +1475,18 @@ function Navbar() {
1339
1475
  children: config.versions && currentVersion && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(VersionSelector, {})
1340
1476
  })
1341
1477
  ] }),
1342
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_search_dialog.Navbar.Center, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Suspense, {
1343
- fallback: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "h-9 w-32 animate-pulse rounded-md bg-surface" }),
1344
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SearchDialog$1, { routes: routes || [] })
1478
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_search_dialog.Navbar.Center, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1479
+ className: "flex items-center gap-2",
1480
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Suspense, {
1481
+ fallback: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "h-9 w-32 animate-pulse rounded-md bg-surface" }),
1482
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SearchDialog$1, { routes: routes || [] })
1483
+ })
1345
1484
  }) }),
1346
1485
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_search_dialog.Navbar.Right, { children: [
1347
1486
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Suspense, {
1348
1487
  fallback: null,
1349
1488
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1350
- className: "lg:hidden",
1489
+ className: "lg:hidden flex items-center gap-1",
1351
1490
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SearchDialog$1, { routes: routes || [] })
1352
1491
  })
1353
1492
  }),
@@ -1698,6 +1837,69 @@ function Feedback({ className }) {
1698
1837
  });
1699
1838
  }
1700
1839
 
1840
+ //#endregion
1841
+ //#region src/client/components/ui-base/giscus.tsx
1842
+ function Giscus({ className }) {
1843
+ const config = require_icons_dev.useConfig();
1844
+ const { resolvedTheme } = require_image.useTheme();
1845
+ const ref = (0, react.useRef)(null);
1846
+ const initializedRef = (0, react.useRef)(false);
1847
+ const giscusConfig = config.integrations?.feedback?.giscus;
1848
+ (0, react.useEffect)(() => {
1849
+ if (!giscusConfig) return;
1850
+ const theme = giscusConfig.theme || (resolvedTheme === "dark" ? "dark" : "light");
1851
+ const session = {
1852
+ repo: giscusConfig.repo,
1853
+ "repo-id": giscusConfig.repoId,
1854
+ category: giscusConfig.category,
1855
+ "category-id": giscusConfig.categoryId,
1856
+ mapping: giscusConfig.mapping || "pathname",
1857
+ strict: String(giscusConfig.strict ?? "0"),
1858
+ "reactions-enabled": String(giscusConfig.reactionsEnabled ?? "1"),
1859
+ "emit-metadata": String(giscusConfig.emitMetadata ?? "0"),
1860
+ "input-position": giscusConfig.inputPosition || "bottom",
1861
+ lang: giscusConfig.lang || "en",
1862
+ loading: giscusConfig.loading || "lazy"
1863
+ };
1864
+ if (!initializedRef.current) {
1865
+ initializedRef.current = true;
1866
+ const script = document.createElement("script");
1867
+ script.src = "https://giscus.app/client.js";
1868
+ script.setAttribute("data-repo", session.repo);
1869
+ script.setAttribute("data-repo-id", session["repo-id"]);
1870
+ if (session.category) script.setAttribute("data-category", session.category);
1871
+ if (session["category-id"]) script.setAttribute("data-category-id", session["category-id"]);
1872
+ script.setAttribute("data-mapping", session.mapping);
1873
+ script.setAttribute("data-strict", session.strict);
1874
+ script.setAttribute("data-reactions-enabled", session["reactions-enabled"]);
1875
+ script.setAttribute("data-emit-metadata", session["emit-metadata"]);
1876
+ script.setAttribute("data-input-position", session["input-position"]);
1877
+ script.setAttribute("data-lang", session.lang);
1878
+ script.setAttribute("data-loading", session.loading);
1879
+ script.setAttribute("data-theme", theme);
1880
+ script.setAttribute("crossorigin", "anonymous");
1881
+ script.async = true;
1882
+ if (ref.current) ref.current.appendChild(script);
1883
+ return () => {
1884
+ initializedRef.current = false;
1885
+ if (script.parentNode) script.parentNode.removeChild(script);
1886
+ (ref.current?.querySelectorAll("iframe"))?.forEach((iframe) => iframe.remove());
1887
+ };
1888
+ }
1889
+ }, [giscusConfig]);
1890
+ (0, react.useEffect)(() => {
1891
+ if (!giscusConfig || !initializedRef.current) return;
1892
+ const theme = giscusConfig.theme || (resolvedTheme === "dark" ? "dark" : "light");
1893
+ const iframe = ref.current?.querySelector("iframe.giscus-frame");
1894
+ if (iframe) iframe.contentWindow?.postMessage({ giscus: { setConfig: { theme } } }, "https://giscus.app");
1895
+ }, [resolvedTheme, giscusConfig]);
1896
+ if (!giscusConfig) return null;
1897
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1898
+ ref,
1899
+ className: require_icons_dev.cn("w-full max-w-2xl mt-12 mb-6", className)
1900
+ });
1901
+ }
1902
+
1701
1903
  //#endregion
1702
1904
  //#region src/client/ssg/mdx-elements.tsx
1703
1905
  const Loading = () => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -1736,117 +1938,14 @@ const NotFoundWrapper = () => {
1736
1938
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(components.NotFound || components["404"] || NotFound, {});
1737
1939
  };
1738
1940
 
1739
- //#endregion
1740
- //#region src/client/app/head.tsx
1741
- function Head({ siteTitle, siteDescription, routes }) {
1742
- const location = (0, react_router_dom.useLocation)();
1743
- const config = require_icons_dev.useConfig();
1744
- const { currentLocale } = require_icons_dev.useRoutes();
1745
- const currentRoute = (0, react.useMemo)(() => routes?.find?.((r) => r.path === location.pathname), [routes, location.pathname]);
1746
- const pageTitle = currentRoute?.title;
1747
- const translatedSiteDescription = getTranslated(siteDescription, currentLocale);
1748
- const pageDescription = currentRoute?.description || translatedSiteDescription || "";
1749
- const translatedSiteTitle = getTranslated(siteTitle, currentLocale);
1750
- const finalTitle = pageTitle ? `${pageTitle} | ${translatedSiteTitle}` : translatedSiteTitle;
1751
- const seo = currentRoute?.seo || {};
1752
- const canonicalUrl = seo.canonical || (config?.siteUrl && currentRoute?.path ? `${config.siteUrl.replace(/\/$/, "")}${currentRoute.path}` : void 0);
1753
- const ogUrl = seo["og:url"] || canonicalUrl || (typeof window !== "undefined" ? window.location.href : void 0);
1754
- const globalMetatags = config?.seo?.metatags || {};
1755
- const defaultOgImage = config?.seo?.thumbnails?.background;
1756
- const ogImage = seo["og:image"] || defaultOgImage;
1757
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Helmet, { children: [
1758
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("title", { children: finalTitle }),
1759
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("meta", {
1760
- name: "description",
1761
- content: pageDescription
1762
- }),
1763
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("meta", {
1764
- property: "og:title",
1765
- content: finalTitle
1766
- }),
1767
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("meta", {
1768
- property: "og:description",
1769
- content: pageDescription
1770
- }),
1771
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("meta", {
1772
- property: "og:type",
1773
- content: "article"
1774
- }),
1775
- canonicalUrl && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("link", {
1776
- rel: "canonical",
1777
- href: canonicalUrl
1778
- }),
1779
- ogUrl && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("meta", {
1780
- property: "og:url",
1781
- content: ogUrl
1782
- }),
1783
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("meta", {
1784
- name: "twitter:card",
1785
- content: "summary"
1786
- }),
1787
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("meta", {
1788
- name: "twitter:title",
1789
- content: finalTitle
1790
- }),
1791
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("meta", {
1792
- name: "twitter:description",
1793
- content: pageDescription
1794
- }),
1795
- ogImage && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("meta", {
1796
- name: "twitter:image",
1797
- content: ogImage
1798
- }),
1799
- ogImage && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("meta", {
1800
- property: "og:image",
1801
- content: ogImage
1802
- }),
1803
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("meta", {
1804
- name: "generator",
1805
- content: "Boltdocs"
1806
- }),
1807
- Object.entries(globalMetatags).map(([key, value]) => {
1808
- return key.startsWith("og:") || key.startsWith("music:") || key.startsWith("video:") || key.startsWith("article:") || key.startsWith("book:") || key.startsWith("profile:") ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("meta", {
1809
- property: key,
1810
- content: value
1811
- }, key) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("meta", {
1812
- name: key,
1813
- content: value
1814
- }, key);
1815
- }),
1816
- Object.entries(seo).map(([key, value]) => {
1817
- if (key === "noindex" && value === true) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("meta", {
1818
- name: "robots",
1819
- content: "noindex"
1820
- }, "noindex");
1821
- if (key === "robots") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("meta", {
1822
- name: "robots",
1823
- content: value
1824
- }, "robots");
1825
- if (key === "canonical" || key === "og:url") return null;
1826
- return key.startsWith("og:") || key.startsWith("music:") || key.startsWith("video:") || key.startsWith("article:") || key.startsWith("book:") || key.startsWith("profile:") ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("meta", {
1827
- property: key,
1828
- content: value
1829
- }, key) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("meta", {
1830
- name: key,
1831
- content: value
1832
- }, key);
1833
- })
1834
- ] });
1835
- }
1836
-
1837
1941
  //#endregion
1838
1942
  //#region src/client/app/docs-layout.tsx
1839
1943
  function DocsLayout({ collectionsData }) {
1840
- const config = require_icons_dev.useConfig();
1841
- const { currentRoute, allRoutes } = require_icons_dev.useRoutes();
1842
- const content = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Head, {
1843
- siteTitle: config.theme?.title,
1844
- siteDescription: config.theme?.description,
1845
- routes: allRoutes || []
1846
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_search_dialog$1.InternalErrorBoundary, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(virtual_boltdocs_layout.default, {
1944
+ const { currentRoute } = require_icons_dev.useRoutes();
1945
+ const content = /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_search_dialog$1.InternalErrorBoundary, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(virtual_boltdocs_layout.default, {
1847
1946
  route: currentRoute,
1848
1947
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_router_dom.Outlet, {})
1849
- }) })] });
1948
+ }) });
1850
1949
  if (collectionsData) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CollectionsContext.Provider, {
1851
1950
  value: collectionsData,
1852
1951
  children: content
@@ -2323,6 +2422,18 @@ function createRoutes(options) {
2323
2422
  function DocsLayoutComponent({ children }) {
2324
2423
  const { routes: filteredRoutes, currentRoute, isCollectionPage } = require_icons_dev.useRoutes();
2325
2424
  const config = require_icons_dev.useConfig();
2425
+ const AskAiDialog = useMergedComponents().AskAiDialog;
2426
+ const [isAskAiOpen, setIsAskAiOpen] = (0, react.useState)(false);
2427
+ (0, react.useEffect)(() => {
2428
+ const handleOpen = () => setIsAskAiOpen(true);
2429
+ const handleClose = () => setIsAskAiOpen(false);
2430
+ window.addEventListener("boltdocs:ask-ai:open", handleOpen);
2431
+ window.addEventListener("boltdocs:ask-ai:close", handleClose);
2432
+ return () => {
2433
+ window.removeEventListener("boltdocs:ask-ai:open", handleOpen);
2434
+ window.removeEventListener("boltdocs:ask-ai:close", handleClose);
2435
+ };
2436
+ }, []);
2326
2437
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_docs_layout.DocsLayout, {
2327
2438
  className: "selection:bg-primary-500/10 selection:text-primary-500",
2328
2439
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Navbar, {}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_docs_layout.DocsLayout.Body, {
@@ -2359,15 +2470,17 @@ function DocsLayoutComponent({ children }) {
2359
2470
  children
2360
2471
  }) }),
2361
2472
  !isCollectionPage && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Feedback, {}),
2473
+ !isCollectionPage && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Giscus, {}),
2362
2474
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_docs_layout.DocsLayout.Footer, { children: !isCollectionPage && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PageNav, {}) })
2363
2475
  ]
2364
2476
  })
2365
2477
  }),
2366
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(OnThisPage, {
2478
+ AskAiDialog && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AskAiDialog, {}),
2479
+ !isCollectionPage && !isAskAiOpen && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(OnThisPage, {
2367
2480
  headings: currentRoute?.headings,
2368
- editLink: config.theme?.editLink,
2481
+ filePath: currentRoute?.filePath,
2369
2482
  communityHelp: config.theme?.communityHelp,
2370
- filePath: currentRoute?.filePath
2483
+ editLink: config.theme?.editLink
2371
2484
  })
2372
2485
  ]
2373
2486
  })]
@@ -1,6 +1,6 @@
1
1
 
2
- import { A as BoltdocsRoutePathWithFallback, C as SiteConfig, D as BoltdocsLocale, E as BoltdocsIntegrationsConfig, M as BoltdocsTypes, N as BoltdocsVersion, O as BoltdocsMdxComponents, S as SidebarProps, T as BoltdocsConfig, _ as CollectionPostLoaderData, b as NavbarLink, g as CollectionListLoaderData, h as BoltdocsTab, j as BoltdocsSocialLink, k as BoltdocsRoutePath, v as ComponentRoute, w as TabsProps, x as OnThisPageProps, y as LayoutProps } from "../sidebar-BtJyWHy4.cjs";
3
- import { a as ErrorBoundary, c as OnThisPage, i as CopyMarkdown, l as Sidebar, n as NotFound, o as PageNav, r as SearchDialog, s as Breadcrumbs, t as Banner, u as Navbar } from "../banner-C_xkGxzI.cjs";
2
+ import { A as BoltdocsRoutePathWithFallback, C as SiteConfig, D as BoltdocsLocale, E as BoltdocsIntegrationsConfig, M as BoltdocsTypes, N as BoltdocsVersion, O as BoltdocsMdxComponents, S as SidebarProps, T as BoltdocsConfig, _ as CollectionPostLoaderData, b as NavbarLink, g as CollectionListLoaderData, h as BoltdocsTab, j as BoltdocsSocialLink, k as BoltdocsRoutePath, v as ComponentRoute, w as TabsProps, x as OnThisPageProps, y as LayoutProps } from "../sidebar-7gIifpBX.cjs";
3
+ import { a as ErrorBoundary, c as OnThisPage, i as CopyMarkdown, l as Sidebar, n as NotFound, o as PageNav, r as SearchDialog, s as Breadcrumbs, t as Banner, u as Navbar } from "../banner-DNSkgUsO.cjs";
4
4
  import * as _$react from "react";
5
5
  import React$1, { ComponentType, JSXElementConstructor, ReactNode } from "react";
6
6
  import { RouteRecord, ViteReactSSG } from "@bdocs/ssg";
@@ -140,6 +140,7 @@ declare function useSearch(routes: ComponentRoute[]): {
140
140
  query: string;
141
141
  setQuery: _$react.Dispatch<_$react.SetStateAction<string>>;
142
142
  list: any[];
143
+ handleSelect: (key: React.Key) => void;
143
144
  input: {
144
145
  value: string;
145
146
  onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
@@ -234,7 +235,7 @@ declare function useRoutes(): {
234
235
  * Hook to automatically localize a path based on the current version and locale context.
235
236
  * It ensures that navigation preserves the active version and language across the entire site.
236
237
  */
237
- declare function useLocalizedTo(to: string): string;
238
+ declare function useLocalizedTo(to: BoltdocsRoutePathWithFallback): string;
238
239
  declare function useLocalizedTo(to: LinkProps['to']): LinkProps['to'];
239
240
  //#endregion
240
241
  //#region src/client/hooks/use-location.d.ts
@@ -1,6 +1,6 @@
1
1
 
2
- import { A as BoltdocsRoutePathWithFallback, C as SiteConfig, D as BoltdocsLocale, E as BoltdocsIntegrationsConfig, M as BoltdocsTypes, N as BoltdocsVersion, O as BoltdocsMdxComponents, S as SidebarProps, T as BoltdocsConfig, _ as CollectionPostLoaderData, b as NavbarLink, g as CollectionListLoaderData, h as BoltdocsTab, j as BoltdocsSocialLink, k as BoltdocsRoutePath, v as ComponentRoute, w as TabsProps, x as OnThisPageProps, y as LayoutProps } from "../sidebar-C4fuRYYS.js";
3
- import { a as ErrorBoundary, c as OnThisPage, i as CopyMarkdown, l as Sidebar, n as NotFound, o as PageNav, r as SearchDialog, s as Breadcrumbs, t as Banner, u as Navbar } from "../banner-D2NddBfF.js";
2
+ import { A as BoltdocsRoutePathWithFallback, C as SiteConfig, D as BoltdocsLocale, E as BoltdocsIntegrationsConfig, M as BoltdocsTypes, N as BoltdocsVersion, O as BoltdocsMdxComponents, S as SidebarProps, T as BoltdocsConfig, _ as CollectionPostLoaderData, b as NavbarLink, g as CollectionListLoaderData, h as BoltdocsTab, j as BoltdocsSocialLink, k as BoltdocsRoutePath, v as ComponentRoute, w as TabsProps, x as OnThisPageProps, y as LayoutProps } from "../sidebar-BAKgJ-Er.js";
3
+ import { a as ErrorBoundary, c as OnThisPage, i as CopyMarkdown, l as Sidebar, n as NotFound, o as PageNav, r as SearchDialog, s as Breadcrumbs, t as Banner, u as Navbar } from "../banner-CfdalYLL.js";
4
4
  import { RouteRecord, ViteReactSSG } from "@bdocs/ssg";
5
5
  import * as _$react from "react";
6
6
  import React$1, { ComponentType, JSXElementConstructor, ReactNode } from "react";
@@ -140,6 +140,7 @@ declare function useSearch(routes: ComponentRoute[]): {
140
140
  query: string;
141
141
  setQuery: _$react.Dispatch<_$react.SetStateAction<string>>;
142
142
  list: any[];
143
+ handleSelect: (key: React.Key) => void;
143
144
  input: {
144
145
  value: string;
145
146
  onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
@@ -234,7 +235,7 @@ declare function useRoutes(): {
234
235
  * Hook to automatically localize a path based on the current version and locale context.
235
236
  * It ensures that navigation preserves the active version and language across the entire site.
236
237
  */
237
- declare function useLocalizedTo(to: string): string;
238
+ declare function useLocalizedTo(to: BoltdocsRoutePathWithFallback): string;
238
239
  declare function useLocalizedTo(to: LinkProps['to']): LinkProps['to'];
239
240
  //#endregion
240
241
  //#region src/client/hooks/use-location.d.ts