boltdocs 1.6.0 → 1.7.1

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 (57) hide show
  1. package/dist/{SearchDialog-J3KNRGNO.mjs → SearchDialog-6Z7CUAYJ.mjs} +8 -1
  2. package/dist/{SearchDialog-3QICRMWF.css → SearchDialog-GOZ6X53X.css} +385 -113
  3. package/dist/{chunk-HSPDIRTW.mjs → chunk-SFVOGJ2W.mjs} +955 -737
  4. package/dist/client/index.css +385 -113
  5. package/dist/client/index.d.mts +19 -7
  6. package/dist/client/index.d.ts +19 -7
  7. package/dist/client/index.js +964 -577
  8. package/dist/client/index.mjs +118 -1
  9. package/dist/client/ssr.css +385 -113
  10. package/dist/client/ssr.d.mts +3 -1
  11. package/dist/client/ssr.d.ts +3 -1
  12. package/dist/client/ssr.js +743 -474
  13. package/dist/client/ssr.mjs +3 -2
  14. package/dist/{config-DkZg5aCf.d.ts → config-D68h41CA.d.mts} +21 -2
  15. package/dist/{config-DkZg5aCf.d.mts → config-D68h41CA.d.ts} +21 -2
  16. package/dist/node/index.d.mts +12 -2
  17. package/dist/node/index.d.ts +12 -2
  18. package/dist/node/index.js +48 -21
  19. package/dist/node/index.mjs +48 -21
  20. package/dist/{types-DGIo1VKD.d.mts → types-BbceAHA0.d.mts} +15 -0
  21. package/dist/{types-DGIo1VKD.d.ts → types-BbceAHA0.d.ts} +15 -0
  22. package/package.json +1 -1
  23. package/src/client/app/index.tsx +16 -11
  24. package/src/client/index.ts +2 -0
  25. package/src/client/ssr.tsx +4 -1
  26. package/src/client/theme/components/mdx/Table.tsx +151 -0
  27. package/src/client/theme/components/mdx/index.ts +3 -0
  28. package/src/client/theme/components/mdx/mdx-components.css +128 -0
  29. package/src/client/theme/styles/markdown.css +8 -3
  30. package/src/client/theme/styles/variables.css +34 -9
  31. package/src/client/theme/ui/ErrorBoundary/ErrorBoundary.tsx +46 -0
  32. package/src/client/theme/ui/ErrorBoundary/index.ts +1 -0
  33. package/src/client/theme/ui/Layout/Layout.tsx +10 -11
  34. package/src/client/theme/ui/Layout/base.css +15 -3
  35. package/src/client/theme/ui/Link/Link.tsx +2 -2
  36. package/src/client/theme/ui/Link/LinkPreview.tsx +9 -14
  37. package/src/client/theme/ui/Link/link-preview.css +30 -27
  38. package/src/client/theme/ui/Navbar/Navbar.tsx +65 -17
  39. package/src/client/theme/ui/Navbar/Tabs.tsx +99 -0
  40. package/src/client/theme/ui/Navbar/navbar.css +119 -5
  41. package/src/client/theme/ui/OnThisPage/OnThisPage.tsx +66 -57
  42. package/src/client/theme/ui/OnThisPage/toc.css +30 -10
  43. package/src/client/theme/ui/ProgressBar/ProgressBar.css +17 -0
  44. package/src/client/theme/ui/ProgressBar/ProgressBar.tsx +51 -0
  45. package/src/client/theme/ui/ProgressBar/index.ts +1 -0
  46. package/src/client/theme/ui/SearchDialog/SearchDialog.tsx +11 -1
  47. package/src/client/theme/ui/Sidebar/Sidebar.tsx +97 -57
  48. package/src/client/theme/ui/Sidebar/sidebar.css +61 -67
  49. package/src/client/types.ts +12 -0
  50. package/src/node/config.ts +19 -1
  51. package/src/node/plugin/entry.ts +5 -1
  52. package/src/node/plugin/index.ts +2 -1
  53. package/src/node/routes/index.ts +13 -1
  54. package/src/node/routes/parser.ts +32 -7
  55. package/src/node/routes/types.ts +11 -1
  56. package/src/node/ssg/index.ts +2 -1
  57. package/src/node/ssg/options.ts +2 -0
@@ -8,72 +8,44 @@
8
8
  backdrop-filter: blur(var(--ld-sidebar-blur));
9
9
  -webkit-backdrop-filter: blur(var(--ld-sidebar-blur));
10
10
  border-right: 1px solid var(--ld-border-subtle);
11
- padding: 1rem 0.6rem;
11
+ padding: 1.5rem 0.6rem;
12
12
  overflow-y: auto;
13
- position: sticky;
14
- top: var(--ld-navbar-height);
15
- height: calc(100vh - var(--ld-navbar-height));
16
- scrollbar-width: thin;
17
- scrollbar-color: var(--ld-bg-mute) transparent;
13
+ height: 100%;
14
+ scrollbar-width: none;
18
15
  display: flex;
19
16
  flex-direction: column;
20
- transition:
21
- width 0.3s cubic-bezier(0.16, 1, 0.3, 1),
22
- padding 0.3s cubic-bezier(0.16, 1, 0.3, 1),
23
- opacity 0.2s ease;
17
+ /* Hardware acceleration */
18
+ transform: translate3d(0, 0, 0);
19
+ backface-visibility: hidden;
24
20
  }
25
21
 
26
- .boltdocs-sidebar > nav {
27
- flex: 1;
28
- }
29
-
30
- /* ─── Collapsible Sidebar ────────────────────────────────── */
31
- .boltdocs-main-container.sidebar-collapsed .boltdocs-sidebar {
32
- width: 54px;
33
- padding: 1rem 0;
34
- border-right: 1px solid var(--ld-border-subtle);
35
- opacity: 1;
36
- pointer-events: auto;
37
- overflow: hidden;
38
- }
39
-
40
- .sidebar-collapse {
41
- width: 100%;
22
+ .sidebar-icon {
23
+ flex-shrink: 0;
42
24
  display: flex;
43
25
  align-items: center;
44
- justify-content: flex-end;
45
- padding: 0 0.75rem 1rem;
46
- transition: justify-content 0.3s ease;
47
- }
48
-
49
- .boltdocs-main-container.sidebar-collapsed .sidebar-collapse {
50
26
  justify-content: center;
51
- padding: 0 0 1rem;
52
27
  }
53
28
 
54
- .sidebar-collapse-btn {
29
+ .sidebar-icon.lucide-icon,
30
+ .sidebar-icon.svg-icon svg {
55
31
  color: var(--ld-text-muted);
56
- border: none;
57
- box-shadow: none;
58
- background-color: transparent;
59
- cursor: pointer;
60
- display: flex;
61
- align-items: center;
62
- justify-content: center;
63
- width: 32px;
64
- height: 32px;
65
- border-radius: var(--ld-radius-md);
66
- transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1);
32
+ width: 18px;
33
+ height: 18px;
34
+ stroke-width: 2px;
35
+ transition: color 0.2s ease;
67
36
  }
68
37
 
69
- .sidebar-collapse-btn:hover {
70
- background-color: var(--ld-bg-mute);
71
- color: var(--ld-text-main);
72
- transform: scale(1.05);
38
+ .sidebar-link:hover .sidebar-icon.lucide-icon,
39
+ .sidebar-link.active .sidebar-icon.lucide-icon {
40
+ color: var(--ld-color-primary);
41
+ }
42
+
43
+ .boltdocs-sidebar > nav {
44
+ flex: 1;
73
45
  }
74
46
 
75
47
  .boltdocs-sidebar::-webkit-scrollbar {
76
- width: 4px;
48
+ display: none;
77
49
  }
78
50
 
79
51
  .boltdocs-sidebar::-webkit-scrollbar-track {
@@ -92,23 +64,29 @@
92
64
  }
93
65
 
94
66
  .sidebar-list li {
95
- margin-bottom: 1px;
67
+ margin-bottom: 2px;
96
68
  }
97
69
 
98
70
  .sidebar-link {
99
71
  display: flex;
100
72
  align-items: center;
101
73
  justify-content: space-between;
102
- padding: 0.45rem 0.75rem;
74
+ padding: 0.5rem 0.75rem;
103
75
  color: var(--ld-text-muted);
104
76
  text-decoration: none;
105
- border-radius: var(--ld-radius-md);
77
+ border-radius: 0.75rem; /* Large rounded corners */
106
78
  font-size: 0.875rem;
107
79
  font-weight: 500;
108
80
  transition: all 0.2s ease;
109
81
  margin: 0.15rem 0;
110
82
  }
111
83
 
84
+ .sidebar-link-title-container {
85
+ display: flex;
86
+ align-items: center;
87
+ gap: 0.75rem;
88
+ }
89
+
112
90
  .sidebar-link-content {
113
91
  display: flex;
114
92
  align-items: center;
@@ -117,7 +95,7 @@
117
95
  gap: 0.5rem;
118
96
  }
119
97
 
120
- .sidebar-link-content > span:first-child {
98
+ .sidebar-link-content > span:last-child {
121
99
  flex: 1;
122
100
  word-wrap: break-word;
123
101
  }
@@ -162,11 +140,13 @@
162
140
 
163
141
  .sidebar-link:hover {
164
142
  color: var(--ld-color-primary-hover);
143
+ background-color: var(--ld-bg-soft);
165
144
  }
166
145
 
167
146
  .sidebar-link.active {
168
147
  color: var(--ld-color-primary);
169
148
  font-weight: 600;
149
+ background-color: var(--ld-bg-soft);
170
150
  }
171
151
 
172
152
  /* ─── Sidebar Groups ─────────────────────────────────────── */
@@ -183,29 +163,32 @@
183
163
  align-items: center;
184
164
  justify-content: space-between;
185
165
  width: 100%;
186
- padding: 0.35rem 0.75rem;
166
+ padding: 0.5rem 0.75rem;
187
167
  background: none;
188
168
  border: none;
189
169
  border-radius: var(--ld-radius-md);
190
- color: var(--ld-text-dim);
170
+ color: var(--ld-text-muted);
191
171
  font-family: var(--ld-font-sans);
192
- font-size: 0.6875rem;
193
- font-weight: 700;
194
- text-transform: uppercase;
195
- letter-spacing: 0.08em;
172
+ font-size: 0.8125rem;
173
+ font-weight: 600;
196
174
  cursor: pointer;
197
175
  transition:
198
176
  color 0.2s,
199
177
  background-color 0.2s;
200
178
  }
201
179
 
180
+ .sidebar-group-header-content {
181
+ display: flex;
182
+ align-items: center;
183
+ gap: 0.75rem;
184
+ }
185
+
202
186
  .sidebar-group-header:hover {
203
- color: var(--ld-text-muted);
204
- background-color: rgba(255, 255, 255, 0.03);
187
+ color: var(--ld-text-main);
205
188
  }
206
189
 
207
190
  .sidebar-group-header.active {
208
- color: var(--ld-color-primary);
191
+ color: var(--ld-text-main);
209
192
  }
210
193
 
211
194
  .sidebar-group-chevron {
@@ -223,14 +206,25 @@
223
206
  .sidebar-group-list {
224
207
  list-style: none;
225
208
  padding: 0;
226
- margin: 0.35rem 0 0;
227
- overflow: hidden;
209
+ margin: 0.35rem 0 0.5rem 0;
210
+ position: relative;
228
211
  }
229
212
 
230
213
  .sidebar-group-list li {
231
- margin-bottom: 1px;
214
+ margin-bottom: 2px;
232
215
  }
233
216
 
234
217
  .sidebar-link-nested {
235
- padding-left: 1.25rem;
218
+ padding-left: 0.75rem;
219
+ }
220
+
221
+ .sidebar-group-list {
222
+ list-style: none;
223
+ padding: 0;
224
+ margin: 0.35rem 0 0.5rem 0;
225
+ position: relative;
226
+ }
227
+
228
+ .sidebar-group-list li {
229
+ margin-bottom: 2px;
236
230
  }
@@ -29,6 +29,16 @@ export interface ComponentRoute {
29
29
  locale?: string;
30
30
  /** The version this route belongs to, if versioning is configured */
31
31
  version?: string;
32
+ /** Optional icon to display (Lucide icon name or raw SVG) */
33
+ icon?: string;
34
+ /** The tab this route belongs to, if tabs are configured */
35
+ tab?: string;
36
+ /** Optional badge to display next to the sidebar item */
37
+ badge?: string | { text: string; expires?: string };
38
+ /** Optional icon for the route's group */
39
+ groupIcon?: string;
40
+ /** The extracted plain-text content of the page for search indexing */
41
+ _content?: string;
32
42
  }
33
43
 
34
44
  /**
@@ -39,6 +49,8 @@ export interface CreateBoltdocsAppOptions {
39
49
  target: string;
40
50
  /** Initial routes generated by the Vite plugin (`virtual:boltdocs-routes`) */
41
51
  routes: ComponentRoute[];
52
+ /** The name of the documentation directory (e.g. 'docs') */
53
+ docsDirName: string;
42
54
  /** Site configuration (`virtual:boltdocs-config`) */
43
55
  config: any;
44
56
  /** Dynamic import mapping from `import.meta.glob` for the documentation pages */
@@ -32,7 +32,20 @@ export interface BoltdocsThemeConfig {
32
32
  /** URL path to the site logo */
33
33
  logo?: string;
34
34
  /** Items to display in the top navigation bar */
35
- navbar?: Array<{ text: string; link: string }>;
35
+ navbar?: Array<{
36
+ /** Text to display (alias for text) */
37
+ label?: string;
38
+ /** Text to display */
39
+ text?: string;
40
+ /** URL path or external link (alias for link) */
41
+ to?: string;
42
+ /** URL path or external link (alias for link) */
43
+ href?: string;
44
+ /** URL path or external link */
45
+ link?: string;
46
+ /** Alignment of the item in the navbar */
47
+ position?: "left" | "right";
48
+ }>;
36
49
  /** Items to display in the sidebar, organized optionally by group URLs */
37
50
  sidebar?: Record<string, Array<{ text: string; link: string }>>;
38
51
  /** Social links to display in the navigation bar */
@@ -66,6 +79,11 @@ export interface BoltdocsThemeConfig {
66
79
  className?: string;
67
80
  style?: any;
68
81
  };
82
+ /**
83
+ * Top-level tabs for organizing documentation groups.
84
+ * Tab discovery uses the (tab-id) directory syntax.
85
+ */
86
+ tabs?: Array<{ id: string; text: string; icon?: string }>;
69
87
  /**
70
88
  * The syntax highlighting theme for code blocks.
71
89
  * Supports any Shiki theme name (e.g., 'github-dark', 'one-dark-pro', 'aurora-x').
@@ -1,6 +1,7 @@
1
1
  import { normalizePath } from "../utils";
2
2
  import type { BoltdocsConfig } from "../config";
3
3
  import type { BoltdocsPluginOptions } from "./types";
4
+ import path from "path";
4
5
 
5
6
  /**
6
7
  * Generates the raw source code for the virtual entry file (`\0virtual:boltdocs-entry`).
@@ -36,6 +37,8 @@ const ${name} = _comp_${name}.default || _comp_${name}['${name}'] || _comp_${nam
36
37
  .join("\n");
37
38
  const componentMap = pluginComponents.map(([name]) => name).join(", ");
38
39
 
40
+ const docsDirName = path.basename(options.docsDir || "docs");
41
+
39
42
  return `
40
43
  import { createBoltdocsApp as _createApp } from 'boltdocs/client';
41
44
  import 'boltdocs/style.css';
@@ -48,8 +51,9 @@ ${componentImports}
48
51
  _createApp({
49
52
  target: '#root',
50
53
  routes: _routes,
54
+ docsDirName: '${docsDirName}',
51
55
  config: _config,
52
- modules: import.meta.glob('/docs/**/*.{md,mdx}'),
56
+ modules: import.meta.glob('/${docsDirName}/**/*.{md,mdx}'),
53
57
  hot: import.meta.hot,
54
58
  ${homeOption}
55
59
  components: { ${componentMap} },
@@ -165,7 +165,8 @@ export function boltdocsPlugin(
165
165
  ? path.resolve(viteConfig.root, viteConfig.build.outDir)
166
166
  : path.resolve(process.cwd(), "dist");
167
167
 
168
- await generateStaticPages({ docsDir, outDir, config });
168
+ const docsDirName = path.basename(docsDir || "docs");
169
+ await generateStaticPages({ docsDir, docsDirName, outDir, config });
169
170
 
170
171
  const { flushCache } = await import("../cache");
171
172
  await flushCache();
@@ -29,6 +29,7 @@ export async function generateRoutes(
29
29
  ): Promise<RouteMeta[]> {
30
30
  // Load persistent cache on first call
31
31
  docCache.load();
32
+ docCache.invalidateAll(); // FORCE RE-PARSE to pick up new _content field
32
33
 
33
34
  const files = await fastGlob(["**/*.md", "**/*.mdx"], {
34
35
  cwd: docsDir,
@@ -69,13 +70,17 @@ export async function generateRoutes(
69
70
  docCache.save();
70
71
 
71
72
  // Collect group metadata from directory names and index files
72
- const groupMeta = new Map<string, { title: string; position?: number }>();
73
+ const groupMeta = new Map<
74
+ string,
75
+ { title: string; position?: number; icon?: string }
76
+ >();
73
77
  for (const p of parsed) {
74
78
  if (p.relativeDir) {
75
79
  if (!groupMeta.has(p.relativeDir)) {
76
80
  groupMeta.set(p.relativeDir, {
77
81
  title: capitalize(p.relativeDir),
78
82
  position: p.inferredGroupPosition,
83
+ icon: p.route.icon,
79
84
  });
80
85
  } else {
81
86
  const entry = groupMeta.get(p.relativeDir)!;
@@ -85,6 +90,9 @@ export async function generateRoutes(
85
90
  ) {
86
91
  entry.position = p.inferredGroupPosition;
87
92
  }
93
+ if (!entry.icon && p.route.icon) {
94
+ entry.icon = p.route.icon;
95
+ }
88
96
  }
89
97
  }
90
98
 
@@ -94,6 +102,9 @@ export async function generateRoutes(
94
102
  if (p.groupMeta.position !== undefined) {
95
103
  entry.position = p.groupMeta.position;
96
104
  }
105
+ if (p.groupMeta.icon) {
106
+ entry.icon = p.groupMeta.icon;
107
+ }
97
108
  }
98
109
  }
99
110
 
@@ -107,6 +118,7 @@ export async function generateRoutes(
107
118
  group: dir,
108
119
  groupTitle: meta?.title || (dir ? capitalize(dir) : undefined),
109
120
  groupPosition: meta?.position,
121
+ groupIcon: meta?.icon,
110
122
  };
111
123
  });
112
124
 
@@ -69,6 +69,16 @@ export function parseDocFile(
69
69
  }
70
70
  }
71
71
 
72
+ // Level 3: Check for Tab hierarchy (name)
73
+ let inferredTab: string | undefined;
74
+ if (parts.length > 0) {
75
+ const tabMatch = parts[0].match(/^\((.+)\)$/);
76
+ if (tabMatch) {
77
+ inferredTab = tabMatch[1].toLowerCase();
78
+ parts = parts.slice(1);
79
+ }
80
+ }
81
+
72
82
  const cleanRelativePath = parts.join("/");
73
83
 
74
84
  let cleanRoutePath: string;
@@ -118,12 +128,12 @@ export function parseDocFile(
118
128
  .trim();
119
129
  const id = slugger.slug(text);
120
130
  // Security: Sanitize heading text for XSS
121
- headings.push({ level, text: escapeHtml(text), id });
131
+ headings.push({ level, text, id });
122
132
  }
123
133
 
124
- const sanitizedTitle = data.title ? escapeHtml(data.title) : inferredTitle;
134
+ const sanitizedTitle = data.title ? data.title : inferredTitle;
125
135
  let sanitizedDescription = data.description
126
- ? escapeHtml(data.description)
136
+ ? data.description
127
137
  : "";
128
138
 
129
139
  // If no description is provided, extract a summary from the content
@@ -135,10 +145,21 @@ export function parseDocFile(
135
145
  .replace(/\n+/g, " ") // Normalize whitespace
136
146
  .trim()
137
147
  .slice(0, 160);
138
- sanitizedDescription = escapeHtml(summary);
148
+ sanitizedDescription = summary;
139
149
  }
140
150
 
141
- const sanitizedBadge = data.badge ? escapeHtml(data.badge) : undefined;
151
+ const sanitizedBadge = data.badge ? data.badge : undefined;
152
+ const icon = data.icon ? String(data.icon) : undefined;
153
+
154
+ // Extract full content as plain text for search indexing
155
+ const plainText = content
156
+ .replace(/^#+.*$/gm, "") // Remove headers
157
+ .replace(/\[([^\]]+)\]\([^\)]+\)/g, "$1") // Simplify links
158
+ .replace(/<[^>]+>/g, "") // Remove HTML/JSX tags
159
+ .replace(/\{[^\}]+\}/g, "") // Remove JS expressions/curly braces
160
+ .replace(/[_*`]/g, "") // Remove formatting
161
+ .replace(/\n+/g, " ") // Normalize whitespace
162
+ .trim();
142
163
 
143
164
  return {
144
165
  route: {
@@ -152,20 +173,24 @@ export function parseDocFile(
152
173
  locale,
153
174
  version,
154
175
  badge: sanitizedBadge,
176
+ icon,
177
+ tab: inferredTab,
178
+ _content: plainText,
155
179
  },
156
180
  relativeDir: cleanDirName,
157
181
  isGroupIndex,
182
+ inferredTab,
158
183
  groupMeta: isGroupIndex
159
184
  ? {
160
- title: escapeHtml(
185
+ title:
161
186
  data.groupTitle ||
162
187
  data.title ||
163
188
  (cleanDirName ? capitalize(cleanDirName) : ""),
164
- ),
165
189
  position:
166
190
  data.groupPosition ??
167
191
  data.sidebarPosition ??
168
192
  (rawDirName ? extractNumberPrefix(rawDirName) : undefined),
193
+ icon,
169
194
  }
170
195
  : undefined,
171
196
  inferredGroupPosition: rawDirName
@@ -21,6 +21,8 @@ export interface RouteMeta {
21
21
  groupTitle?: string;
22
22
  /** Optional explicit position for ordering the group itself */
23
23
  groupPosition?: number;
24
+ /** Optional icon for the route's group */
25
+ groupIcon?: string;
24
26
  /** Extracted markdown headings for search indexing */
25
27
  headings?: { level: number; text: string; id: string }[];
26
28
  /** The locale this route belongs to, if i18n is configured */
@@ -29,6 +31,12 @@ export interface RouteMeta {
29
31
  version?: string;
30
32
  /** Optional badge to display next to the sidebar item (e.g., 'New', 'Experimental') */
31
33
  badge?: string | { text: string; expires?: string };
34
+ /** Optional icon to display (Lucide icon name or raw SVG) */
35
+ icon?: string;
36
+ /** The tab this route belongs to, if tabs are configured */
37
+ tab?: string;
38
+ /** The extracted plain-text content of the page for search indexing */
39
+ _content?: string;
32
40
  }
33
41
 
34
42
  /**
@@ -43,7 +51,9 @@ export interface ParsedDocFile {
43
51
  /** Whether this file is the index file for its directory group */
44
52
  isGroupIndex: boolean;
45
53
  /** If this is a group index, any specific frontmatter metadata dictating the group's title and position */
46
- groupMeta?: { title: string; position?: number };
54
+ groupMeta?: { title: string; position?: number; icon?: string };
47
55
  /** Extracted group position from the directory name if it has a numeric prefix */
48
56
  inferredGroupPosition?: number;
57
+ /** Extracted tab name from the directory name if it follows the (tab-name) syntax */
58
+ inferredTab?: string;
49
59
  }
@@ -24,7 +24,7 @@ const _require = createRequire(import.meta.url);
24
24
  * @param options - Configuration for paths and site metadata
25
25
  */
26
26
  export async function generateStaticPages(options: SSGOptions): Promise<void> {
27
- const { docsDir, outDir, config } = options;
27
+ const { docsDir, docsDirName, outDir, config } = options;
28
28
  const routes = await generateRoutes(docsDir, config);
29
29
  const siteTitle = config?.themeConfig?.title || "Boltdocs";
30
30
  const siteDescription = config?.themeConfig?.description || "";
@@ -64,6 +64,7 @@ export async function generateStaticPages(options: SSGOptions): Promise<void> {
64
64
  path: route.path,
65
65
  routes: routes,
66
66
  config: config || {},
67
+ docsDirName: docsDirName,
67
68
  modules: fakeModules,
68
69
  homePage: undefined, // No custom home page for now
69
70
  });
@@ -6,6 +6,8 @@ import { BoltdocsConfig } from "../config";
6
6
  export interface SSGOptions {
7
7
  /** The root directory containing markdown documentation files */
8
8
  docsDir: string;
9
+ /** The name of the documentation directory (e.g. 'docs') */
10
+ docsDirName: string;
9
11
  /** The output directory where Vite placed the compiled `index.html` and assets */
10
12
  outDir: string;
11
13
  /** Pre-resolved config (avoids re-resolving during the SSG phase) */