fumadocs-core 15.1.0 → 15.1.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.
@@ -2,7 +2,7 @@ import {
2
2
  _highlight,
3
3
  _renderHighlight,
4
4
  highlight
5
- } from "./chunk-E7AASGCN.js";
5
+ } from "./chunk-BUCUQ3WX.js";
6
6
 
7
7
  // src/highlight/client.tsx
8
8
  import {
@@ -19,9 +19,8 @@ var defaultThemes = {
19
19
  light: "github-light",
20
20
  dark: "github-dark"
21
21
  };
22
- var defaultEngine;
22
+ var highlighters = /* @__PURE__ */ new Map();
23
23
  async function _highlight(code, options) {
24
- const { getSingletonHighlighter } = await import("shiki");
25
24
  const { lang, components: _, engine, ...rest } = options;
26
25
  let themes = { themes: defaultThemes };
27
26
  if ("theme" in options && options.theme) {
@@ -29,11 +28,9 @@ async function _highlight(code, options) {
29
28
  } else if ("themes" in options && options.themes) {
30
29
  themes = { themes: options.themes };
31
30
  }
32
- const highlighter = await getSingletonHighlighter({
31
+ const highlighter = await getHighlighter("custom", {
32
+ engine,
33
33
  langs: [lang],
34
- engine: engine ?? (defaultEngine ??= await import("shiki/engine/oniguruma").then(
35
- (res) => res.createOnigurumaEngine(import("shiki/wasm"))
36
- )),
37
34
  themes: "theme" in themes ? [themes.theme] : Object.values(themes.themes).filter((v) => v !== void 0)
38
35
  });
39
36
  return highlighter.codeToHast(code, {
@@ -53,6 +50,38 @@ function _renderHighlight(hast, options) {
53
50
  Fragment
54
51
  });
55
52
  }
53
+ async function getHighlighter(engineType, options) {
54
+ const { createHighlighter } = await import("shiki");
55
+ let highlighter = highlighters.get(engineType);
56
+ if (!highlighter) {
57
+ let engine = options.engine;
58
+ if (engineType === "js") {
59
+ engine = import("shiki/engine/javascript").then(
60
+ (res) => res.createJavaScriptRegexEngine()
61
+ );
62
+ }
63
+ if (engineType === "oniguruma" || !engine) {
64
+ engine = import("shiki/engine/oniguruma").then(
65
+ (res) => res.createOnigurumaEngine(import("shiki/wasm"))
66
+ );
67
+ }
68
+ highlighter = createHighlighter({
69
+ ...options,
70
+ engine
71
+ });
72
+ highlighters.set(engineType, highlighter);
73
+ return highlighter;
74
+ }
75
+ return highlighter.then(async (instance) => {
76
+ await Promise.all([
77
+ // @ts-expect-error unknown
78
+ instance.loadLanguage(...options.langs),
79
+ // @ts-expect-error unknown
80
+ instance.loadTheme(...options.themes)
81
+ ]);
82
+ return instance;
83
+ });
84
+ }
56
85
  async function highlight(code, options) {
57
86
  return _renderHighlight(await _highlight(code, options), options);
58
87
  }
@@ -62,5 +91,6 @@ export {
62
91
  defaultThemes,
63
92
  _highlight,
64
93
  _renderHighlight,
94
+ getHighlighter,
65
95
  highlight
66
96
  };
@@ -2,7 +2,7 @@
2
2
  function splitPath(path) {
3
3
  return path.split("/").filter((p) => p.length > 0);
4
4
  }
5
- function resolvePath(from, join) {
5
+ function joinPath(from, join) {
6
6
  const v1 = splitPath(from), v2 = splitPath(join);
7
7
  while (v2.length > 0) {
8
8
  switch (v2[0]) {
@@ -28,6 +28,6 @@ function slash(path) {
28
28
 
29
29
  export {
30
30
  splitPath,
31
- resolvePath,
31
+ joinPath,
32
32
  slash
33
33
  };
@@ -1,8 +1,8 @@
1
1
  "use client";
2
2
  import {
3
3
  useShiki
4
- } from "../chunk-Q73QZKHO.js";
5
- import "../chunk-E7AASGCN.js";
4
+ } from "../chunk-62S4EN7J.js";
5
+ import "../chunk-BUCUQ3WX.js";
6
6
  import "../chunk-MLKGABMK.js";
7
7
  export {
8
8
  useShiki
@@ -2,7 +2,7 @@ import "../chunk-WQMD6AUR.js";
2
2
  import {
3
3
  createStyleTransformer,
4
4
  highlight
5
- } from "../chunk-E7AASGCN.js";
5
+ } from "../chunk-BUCUQ3WX.js";
6
6
  import "../chunk-MLKGABMK.js";
7
7
  export {
8
8
  createStyleTransformer,
@@ -3,13 +3,14 @@ import {
3
3
  remarkHeading
4
4
  } from "../chunk-IYQ35KI2.js";
5
5
  import {
6
- resolvePath,
6
+ joinPath,
7
7
  slash
8
- } from "../chunk-SHGL6VBO.js";
8
+ } from "../chunk-QTVCCXFT.js";
9
9
  import {
10
10
  createStyleTransformer,
11
- defaultThemes
12
- } from "../chunk-E7AASGCN.js";
11
+ defaultThemes,
12
+ getHighlighter
13
+ } from "../chunk-BUCUQ3WX.js";
13
14
  import "../chunk-MLKGABMK.js";
14
15
 
15
16
  // src/mdx-plugins/index.ts
@@ -25,11 +26,8 @@ import {
25
26
  transformerNotationWordHighlight
26
27
  } from "@shikijs/transformers";
27
28
  import {
28
- getSingletonHighlighter,
29
29
  bundledLanguages
30
30
  } from "shiki";
31
- import { createOnigurumaEngine } from "shiki/engine/oniguruma";
32
- import { createJavaScriptRegexEngine } from "shiki/engine/javascript";
33
31
 
34
32
  // src/mdx-plugins/transformer-icon.ts
35
33
  var defaultShortcuts = {
@@ -248,13 +246,15 @@ function rehypeCode(_options = {}) {
248
246
  if (options.tab !== false) {
249
247
  transformers.push(transformerTab());
250
248
  }
251
- const highlighter = getSingletonHighlighter({
252
- engine: options.experimentalJSEngine ? createJavaScriptRegexEngine() : createOnigurumaEngine(() => import("shiki/wasm")),
253
- themes: "themes" in options ? Object.values(options.themes).filter(Boolean) : [options.theme],
254
- langs: options.langs ?? (options.lazy ? void 0 : Object.keys(bundledLanguages))
255
- });
249
+ const highlighter = getHighlighter(
250
+ options.experimentalJSEngine ? "js" : "oniguruma",
251
+ {
252
+ themes: "themes" in options ? Object.values(options.themes).filter(Boolean) : [options.theme],
253
+ langs: options.langs ?? (options.lazy ? [] : Object.keys(bundledLanguages))
254
+ }
255
+ );
256
256
  const transformer = highlighter.then(
257
- (instance) => rehypeShikiFromHighlighter(instance, {
257
+ (loaded) => rehypeShikiFromHighlighter(loaded, {
258
258
  ...options,
259
259
  transformers
260
260
  })
@@ -430,7 +430,7 @@ async function getImageSize(src, dir) {
430
430
  url = src;
431
431
  } else if (EXTERNAL_URL_REGEX.test(dir) && isRelative) {
432
432
  const base = new URL(dir);
433
- base.pathname = resolvePath(base.pathname, src);
433
+ base.pathname = joinPath(base.pathname, src);
434
434
  url = base.toString();
435
435
  } else {
436
436
  return imageSizeFromFile(isRelative ? path.join(dir, src) : src);
@@ -1,5 +1,4 @@
1
1
  import { TypedDocument, Orama, Language, RawData, create, SearchParams } from '@orama/orama';
2
- import { NextRequest } from 'next/server';
3
2
  import { S as StructuredData } from '../remark-structure-1kvQbrfH.js';
4
3
  import { S as SortedResult } from '../types-Ch8gnVgO.js';
5
4
  import { I as I18nConfig } from '../config-inq6kP6y.js';
@@ -70,7 +69,7 @@ interface SearchServer {
70
69
  export: () => Promise<ExportedData>;
71
70
  }
72
71
  interface SearchAPI extends SearchServer {
73
- GET: (request: NextRequest) => Promise<Response>;
72
+ GET: (request: Request) => Promise<Response>;
74
73
  /**
75
74
  * `GET` route handler that exports search indexes for static search.
76
75
  */
@@ -19,12 +19,13 @@ function createEndpoint(server) {
19
19
  return Response.json(await server.export());
20
20
  },
21
21
  async GET(request) {
22
- const query = request.nextUrl.searchParams.get("query");
22
+ const url = new URL(request.url);
23
+ const query = url.searchParams.get("query");
23
24
  if (!query) return Response.json([]);
24
25
  return Response.json(
25
26
  await search(query, {
26
- tag: request.nextUrl.searchParams.get("tag") ?? void 0,
27
- locale: request.nextUrl.searchParams.get("locale") ?? void 0
27
+ tag: url.searchParams.get("tag") ?? void 0,
28
+ locale: url.searchParams.get("locale") ?? void 0
28
29
  })
29
30
  );
30
31
  }
@@ -5,7 +5,7 @@ import "../chunk-WQMD6AUR.js";
5
5
  import {
6
6
  createStyleTransformer,
7
7
  highlight
8
- } from "../chunk-E7AASGCN.js";
8
+ } from "../chunk-BUCUQ3WX.js";
9
9
  import "../chunk-MLKGABMK.js";
10
10
 
11
11
  // src/server/get-toc.ts
@@ -4,25 +4,46 @@ import { R as Root, I as Item, F as Folder$1, S as Separator } from '../page-tre
4
4
 
5
5
  interface FileInfo {
6
6
  /**
7
- * The locale extension of file
7
+ * locale extension from the last second `.`, like `.en`
8
+ *
9
+ * empty string if no locale
10
+ */
11
+ locale: string;
12
+ /**
13
+ * File path without extension
14
+ *
15
+ * @deprecated obtain it with `join(dirname, name)`
8
16
  */
9
- locale?: string;
17
+ flattenedPath: string;
10
18
  /**
11
19
  * Original path of file
12
20
  */
13
21
  path: string;
14
22
  /**
15
- * File path without extension
23
+ * File name without locale and extension
16
24
  */
17
- flattenedPath: string;
25
+ name: string;
18
26
  /**
19
- * File name without locale and extension
27
+ * file extension from the last `.`, like `.md`
28
+ *
29
+ * empty string if no file extension
30
+ */
31
+ ext: string;
32
+ dirname: string;
33
+ }
34
+ interface FolderInfo {
35
+ /**
36
+ * Original path of folder
37
+ */
38
+ path: string;
39
+ /**
40
+ * folder name
20
41
  */
21
42
  name: string;
22
43
  dirname: string;
23
44
  }
24
45
  declare function parseFilePath(path: string): FileInfo;
25
- declare function parseFolderPath(path: string): FileInfo;
46
+ declare function parseFolderPath(path: string): FolderInfo;
26
47
 
27
48
  interface LoadOptions {
28
49
  transformers?: Transformer[];
@@ -105,7 +126,7 @@ interface LoaderOutput<Config extends LoaderConfig> {
105
126
  getPageTree: (locale?: string) => Root;
106
127
  getPageByHref: (href: string, options?: {
107
128
  /**
108
- * resolve relative file paths in `href` from specified directory
129
+ * resolve relative file paths in `href` from specified dirname, must be a virtual path.
109
130
  */
110
131
  dir?: string;
111
132
  }) => {
@@ -174,7 +195,7 @@ interface PageFile {
174
195
  }
175
196
  type File = MetaFile | PageFile;
176
197
  interface Folder {
177
- file: FileInfo;
198
+ file: FolderInfo;
178
199
  children: (File | Folder)[];
179
200
  }
180
201
  /**
@@ -239,4 +260,4 @@ interface PageTreeBuilder {
239
260
  }
240
261
  declare function createPageTreeBuilder(): PageTreeBuilder;
241
262
 
242
- export { type BuildPageTreeOptions, type BuildPageTreeOptionsWithI18n, type FileInfo, fileSystem as FileSystem, type InferMetaType, type InferPageType, type LanguageEntry, type LoadOptions, type LoaderConfig, type LoaderOptions, type LoaderOutput, type Meta, type MetaData, type Page, type PageData, type PageTreeBuilder, type Source, type SourceConfig, type Transformer, type UrlFn, type VirtualFile, createGetUrl, createPageTreeBuilder, getSlugs, loadFiles, loader, parseFilePath, parseFolderPath };
263
+ export { type BuildPageTreeOptions, type BuildPageTreeOptionsWithI18n, type FileInfo, fileSystem as FileSystem, type FolderInfo, type InferMetaType, type InferPageType, type LanguageEntry, type LoadOptions, type LoaderConfig, type LoaderOptions, type LoaderOutput, type Meta, type MetaData, type Page, type PageData, type PageTreeBuilder, type Source, type SourceConfig, type Transformer, type UrlFn, type VirtualFile, createGetUrl, createPageTreeBuilder, getSlugs, loadFiles, loader, parseFilePath, parseFolderPath };
@@ -1,8 +1,8 @@
1
1
  import {
2
- resolvePath,
2
+ joinPath,
3
3
  slash,
4
4
  splitPath
5
- } from "../chunk-SHGL6VBO.js";
5
+ } from "../chunk-QTVCCXFT.js";
6
6
  import {
7
7
  __export
8
8
  } from "../chunk-MLKGABMK.js";
@@ -24,8 +24,14 @@ function buildAll(nodes, ctx, skipIndex) {
24
24
  for (const node of [...nodes].sort(
25
25
  (a, b) => a.file.name.localeCompare(b.file.name)
26
26
  )) {
27
- if (isPageFile(node) && !node.file.locale) {
28
- const treeNode = buildFileNode(node, ctx);
27
+ if (isPageFile(node)) {
28
+ if (node.file.locale.length > 0 && node.file.locale.slice(1) !== ctx.defaultLanguage)
29
+ continue;
30
+ const localized = ctx.storage.read(
31
+ joinPath(node.file.dirname, `${node.file.name}.${ctx.lang}`),
32
+ "page"
33
+ );
34
+ const treeNode = buildFileNode(localized ?? node, ctx);
29
35
  if (node.file.name === "index") {
30
36
  if (!skipIndex) output.unshift(treeNode);
31
37
  continue;
@@ -33,10 +39,11 @@ function buildAll(nodes, ctx, skipIndex) {
33
39
  output.push(treeNode);
34
40
  }
35
41
  if ("children" in node) {
36
- if (node.children.length === 1 && node.children[0].file.name === "index" && isPageFile(node.children[0])) {
37
- output.push(buildFileNode(node.children[0], ctx));
42
+ const folder = buildFolderNode(node, false, ctx);
43
+ if (folder.children.length === 0 && folder.index) {
44
+ output.push(folder.index);
38
45
  } else {
39
- folders.push(buildFolderNode(node, false, ctx));
46
+ folders.push(folder);
40
47
  }
41
48
  }
42
49
  }
@@ -75,8 +82,11 @@ function resolveFolderItem(folder, item, ctx, idx, addedNodePaths) {
75
82
  } else if (isExtract) {
76
83
  filename = item.slice(extractPrefix.length);
77
84
  }
78
- const path2 = resolvePath(folder.file.path, filename);
79
- const itemNode = ctx.storage.readDir(path2) ?? ctx.storage.read(path2, "page");
85
+ const path = joinPath(folder.file.path, filename);
86
+ let itemNode = ctx.storage.readDir(path);
87
+ if (!itemNode) {
88
+ itemNode = (ctx.lang ? ctx.storage.read(`${path}.${ctx.lang}`, "page") : null) ?? ctx.storage.read(`${path}.${ctx.defaultLanguage}`, "page") ?? ctx.storage.read(path, "page");
89
+ }
80
90
  if (!itemNode) return [];
81
91
  addedNodePaths.add(itemNode.file.path);
82
92
  if (isExcept) return [];
@@ -87,10 +97,10 @@ function resolveFolderItem(folder, item, ctx, idx, addedNodePaths) {
87
97
  return [buildFileNode(itemNode, ctx)];
88
98
  }
89
99
  function buildFolderNode(folder, isGlobalRoot, ctx) {
90
- const metaPath = resolvePath(folder.file.path, "meta");
91
- const meta = findLocalizedFile(metaPath, "meta", ctx) ?? ctx.storage.read(metaPath, "meta");
100
+ const metaPath = joinPath(folder.file.path, "meta");
101
+ const meta = ctx.storage.read(`${metaPath}.${ctx.lang}`, "meta") ?? ctx.storage.read(`${metaPath}.${ctx.defaultLanguage}`, "meta") ?? ctx.storage.read(metaPath, "meta");
92
102
  const indexFile = ctx.storage.read(
93
- resolvePath(folder.file.flattenedPath, "index"),
103
+ joinPath(folder.file.path, "index"),
94
104
  "page"
95
105
  );
96
106
  const metadata = meta?.data;
@@ -137,16 +147,15 @@ function buildFolderNode(folder, isGlobalRoot, ctx) {
137
147
  return ctx.options.attachFolder?.(node, folder, meta) ?? node;
138
148
  }
139
149
  function buildFileNode(file, ctx) {
140
- const localized = findLocalizedFile(file.file.flattenedPath, "page", ctx) ?? file;
141
150
  const item = {
142
- $id: localized.file.path,
151
+ $id: file.file.path,
143
152
  type: "page",
144
- name: localized.data.data.title ?? pathToName(localized.file.name),
145
- description: localized.data.data.description,
146
- icon: ctx.options.resolveIcon?.(localized.data.data.icon),
147
- url: ctx.options.getUrl(localized.data.slugs, ctx.lang),
153
+ name: file.data.data.title ?? pathToName(file.file.name),
154
+ description: file.data.data.description,
155
+ icon: ctx.options.resolveIcon?.(file.data.data.icon),
156
+ url: ctx.options.getUrl(file.data.slugs, ctx.lang),
148
157
  $ref: !ctx.options.noRef ? {
149
- file: localized.file.path
158
+ file: file.file.path
150
159
  } : void 0
151
160
  };
152
161
  return ctx.options.attachFile?.(item, file) ?? item;
@@ -175,7 +184,7 @@ function createPageTreeBuilder() {
175
184
  options,
176
185
  builder: this,
177
186
  storage: options.storage,
178
- i18n
187
+ defaultLanguage: i18n.defaultLanguage
179
188
  });
180
189
  return [lang, tree];
181
190
  });
@@ -183,10 +192,6 @@ function createPageTreeBuilder() {
183
192
  }
184
193
  };
185
194
  }
186
- function findLocalizedFile(path2, format, ctx) {
187
- if (!ctx.lang) return;
188
- return ctx.storage.read(`${path2}.${ctx.lang}`, format);
189
- }
190
195
  function pathToName(name) {
191
196
  const result = [];
192
197
  for (const c of name) {
@@ -198,44 +203,45 @@ function pathToName(name) {
198
203
  }
199
204
 
200
205
  // src/source/path.ts
201
- function parseFilePath(path2) {
202
- const segments = splitPath(slash(path2));
206
+ function parseFilePath(path) {
207
+ const segments = splitPath(slash(path));
203
208
  const dirname = segments.slice(0, -1).join("/");
204
- const base = segments.at(-1) ?? "";
205
- const dotIdx = base.lastIndexOf(".");
206
- const nameWithLocale = dotIdx !== -1 ? base.slice(0, dotIdx) : base;
207
- const flattenedPath = [dirname, nameWithLocale].filter((p) => p.length > 0).join("/");
208
- const [name, locale] = getLocale(nameWithLocale);
209
+ let name = segments.at(-1) ?? "";
210
+ let ext = "";
211
+ let locale = "";
212
+ let dotIdx = name.lastIndexOf(".");
213
+ if (dotIdx !== -1) {
214
+ ext = name.substring(dotIdx);
215
+ name = name.substring(0, dotIdx);
216
+ }
217
+ dotIdx = name.lastIndexOf(".");
218
+ if (dotIdx !== -1 && isLocale(name.substring(dotIdx))) {
219
+ locale = name.substring(dotIdx);
220
+ name = name.substring(0, dotIdx);
221
+ }
209
222
  return {
210
223
  dirname,
211
224
  name,
212
- flattenedPath,
213
225
  locale,
214
- path: segments.join("/")
226
+ path: segments.join("/"),
227
+ ext,
228
+ flattenedPath: [dirname, `${name}${locale}`].filter((p) => p.length > 0).join("/")
215
229
  };
216
230
  }
217
- function parseFolderPath(path2) {
218
- const segments = splitPath(slash(path2));
231
+ function isLocale(code) {
232
+ return code.length > 0 && !/\d+/.test(code);
233
+ }
234
+ function parseFolderPath(path) {
235
+ const segments = splitPath(slash(path));
219
236
  const base = segments.at(-1) ?? "";
220
- const [name, locale] = getLocale(base);
221
- const flattenedPath = segments.join("/");
222
237
  return {
223
238
  dirname: segments.slice(0, -1).join("/"),
224
- name,
225
- flattenedPath,
226
- locale,
227
- path: flattenedPath
239
+ name: base,
240
+ path: segments.join("/")
228
241
  };
229
242
  }
230
- function getLocale(name) {
231
- const sep = name.lastIndexOf(".");
232
- if (sep === -1) return [name];
233
- const locale = name.slice(sep + 1);
234
- if (/\d+/.exec(locale)) return [name];
235
- return [name.slice(0, sep), locale];
236
- }
237
- function normalizePath(path2) {
238
- const segments = splitPath(slash(path2));
243
+ function normalizePath(path) {
244
+ const segments = splitPath(slash(path));
239
245
  if (segments[0] === "." || segments[0] === "..")
240
246
  throw new Error("It must not start with './' or '../'");
241
247
  return segments.join("/");
@@ -260,30 +266,36 @@ var Storage = class {
260
266
  * @param path - flattened path
261
267
  * @param format - file format
262
268
  */
263
- read(path2, format) {
264
- return this.files.get(`${path2}.${format}`);
269
+ read(path, format) {
270
+ return this.files.get(`${path}.${format}`);
265
271
  }
266
- readDir(path2) {
267
- return this.folders.get(path2);
272
+ readDir(path) {
273
+ return this.folders.get(path);
268
274
  }
269
275
  root() {
270
276
  return this.rootFolder;
271
277
  }
272
- write(path2, format, data) {
278
+ write(path, format, data) {
273
279
  const node = {
274
280
  format,
275
- file: parseFilePath(path2),
281
+ file: parseFilePath(path),
276
282
  data
277
283
  };
278
284
  this.makeDir(node.file.dirname);
279
285
  this.readDir(node.file.dirname)?.children.push(node);
280
- this.files.set(`${node.file.flattenedPath}.${node.format}`, node);
286
+ this.files.set(
287
+ joinPath(
288
+ node.file.dirname,
289
+ `${node.file.name}${node.file.locale}.${node.format}`
290
+ ),
291
+ node
292
+ );
281
293
  }
282
294
  list() {
283
295
  return [...this.files.values()];
284
296
  }
285
- makeDir(path2) {
286
- const segments = splitPath(path2);
297
+ makeDir(path) {
298
+ const segments = splitPath(path);
287
299
  for (let i = 0; i < segments.length; i++) {
288
300
  const segment = segments.slice(0, i + 1).join("/");
289
301
  if (this.folders.has(segment)) continue;
@@ -327,7 +339,6 @@ function loadFiles(files, options) {
327
339
  }
328
340
 
329
341
  // src/source/loader.ts
330
- import * as path from "node:path";
331
342
  function indexPages(storage, getUrl, i18n) {
332
343
  const defaultLanguage = i18n?.defaultLanguage ?? "";
333
344
  const map = /* @__PURE__ */ new Map();
@@ -336,17 +347,20 @@ function indexPages(storage, getUrl, i18n) {
336
347
  if (item.format === "meta")
337
348
  pathToFile.set(item.file.path, fileToMeta(item));
338
349
  if (item.format === "page") {
339
- const page = fileToPage(item, getUrl, item.file.locale);
350
+ if (item.file.locale.length > 0 && item.file.locale.slice(1) !== defaultLanguage)
351
+ continue;
352
+ const page = fileToPage(item, getUrl, defaultLanguage);
340
353
  pathToFile.set(item.file.path, page);
341
- if (item.file.locale) continue;
342
354
  map.set(`${defaultLanguage}.${page.slugs.join("/")}`, page);
343
355
  if (!i18n) continue;
356
+ const basePath = joinPath(item.file.dirname, item.file.name);
344
357
  for (const lang of i18n.languages) {
345
- const localized = storage.read(
346
- `${item.file.flattenedPath}.${lang}`,
347
- "page"
358
+ if (lang === defaultLanguage) continue;
359
+ const localizedPage = fileToPage(
360
+ storage.read(`${basePath}.${lang}`, "page") ?? item,
361
+ getUrl,
362
+ lang
348
363
  );
349
- const localizedPage = fileToPage(localized ?? item, getUrl, lang);
350
364
  map.set(`${lang}.${localizedPage.slugs.join("/")}`, localizedPage);
351
365
  }
352
366
  }
@@ -428,7 +442,7 @@ function createOutput(options) {
428
442
  const pages = Array.from(walker.pages.values());
429
443
  const [value, hash] = href.split("#", 2);
430
444
  if (value.startsWith(".") && (value.endsWith(".md") || value.endsWith(".mdx"))) {
431
- const hrefPath = path.join(dir, value);
445
+ const hrefPath = joinPath(dir, value);
432
446
  const target2 = pages.find((item) => item.file.path === hrefPath);
433
447
  if (target2)
434
448
  return {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  useShiki
3
- } from "../chunk-Q73QZKHO.js";
4
- import "../chunk-E7AASGCN.js";
3
+ } from "../chunk-62S4EN7J.js";
4
+ import "../chunk-BUCUQ3WX.js";
5
5
  import "../chunk-MLKGABMK.js";
6
6
  export {
7
7
  useShiki
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fumadocs-core",
3
- "version": "15.1.0",
3
+ "version": "15.1.1",
4
4
  "description": "The library for building a documentation website in Next.js",
5
5
  "keywords": [
6
6
  "NextJs",
@@ -114,12 +114,12 @@
114
114
  "@types/mdast": "^4.0.3",
115
115
  "@types/negotiator": "^0.6.3",
116
116
  "@types/node": "22.13.10",
117
- "@types/react": "^19.0.10",
117
+ "@types/react": "^19.0.11",
118
118
  "@types/react-dom": "^19.0.4",
119
119
  "algoliasearch": "4.24.0",
120
120
  "mdast-util-mdx-jsx": "^3.2.0",
121
121
  "mdast-util-mdxjs-esm": "^2.0.1",
122
- "next": "^15.2.2",
122
+ "next": "^15.2.3",
123
123
  "remark-mdx": "^3.1.0",
124
124
  "remark-rehype": "^11.1.1",
125
125
  "typescript": "^5.8.2",