Expanding an include that is its own ancestor recursed forever.
Track the ancestor chain and leave such includes unexpanded; the
same file can still be included repeatedly as a sibling.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Resolve includes through replaceAsync and fs/promises so include
files are read without blocking the event loop while pages render
concurrently.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Drop the existsSync pre-check in favor of catching ENOENT from the
read itself, and skip indexing when a page renders to nothing (file
gone or excluded via search: false) instead of feeding empty html to
the section splitter.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Split the block parser and fence renderer into factories, extract
region extraction, and type the snippet token instead of ts-ignoring
its src field.
Reading the file now handles ENOENT/EISDIR explicitly: a missing
snippet previously threw from statSync before the 'path not found'
message could render, so that branch was unreachable.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
It is internal and its only caller passes every argument; apply the
fallbacks at the call site instead of hiding them in the signature
after the required siteConfig parameter.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Read the 404 page with fs/promises, replace the trimChar helper with
a regex, and flatten the if/else around listen.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Swap the remaining sync fs calls in renderPage for fs/promises,
switch head-script minification to the async minify API, and make
resolvePageImports async for the realpath call. Pages render under
buildConcurrency, so blocking calls here stall the whole batch.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
createContentLoader already maps files with bounded concurrency, but
the sync stat/read calls serialized the actual I/O.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A fixed ui-custom name still gives adblock filter lists a stable
string to match on. Emit the Carbon/BuySellAds chunks with just the
content hash instead. Changes the emitted filenames for those chunks
and, transitively, the hashes of chunks that import them.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Now that dev updates actually reach the index, any changed markdown
file was being ingested — including srcExclude'd include partials and
dynamic route templates, which are not pages and produced dead search
results. Mirror the initial scan and only index files present in
siteConfig.pages.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
createContentLoader called md.renderAsync without a MarkdownEnv, so
the internal link plugin fell back to defaults and always emitted
.html links in rendered content and excerpts even with cleanUrls
enabled, and plugins reading env.path/relativePath broke. Build the
same env as a normal page render and forward it to both calls.
fixes#4331closes#5299
Co-authored-by: TowyTowy <towy@airreps.link>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Re-indexing only invalidated the bare @localSearchIndex module; the
per-locale modules that carry the data were still served from the
transform cache, and the browser module cache pinned them too. Version
the locale import in dev so every index update loads fresh data.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Rewrites were computed from the locally globbed pages only, so pages
injected via the config were present in siteConfig.pages but never
entered the rewrites map.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
importerMap values were srcDir-relative paths computed with
path.posix.relative, which garbles on Windows drive-letter case
mismatches, and the delete cleanup used a relative key against the
absolute-keyed map so it never removed anything. Store module ids
instead, derive the cache key with a win32-aware relative, and prune
both the include entry and page references after invalidating.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The dead link check compares resolved links against source-space page
paths, so a link to the original location of a rewritten page passed
the check but 404s in the built site.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Discovered config files are keyed by their source directory, but the
lookup walked the rewrite-applied relativePath, so directories covered
by rewrites silently lost their additional config. Resolve against
pageData.filePath on both server and client, which also makes dynamic
route pages inherit configs from their route template's directory.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
URLs were derived from the source path only, so loader-generated links
pointed at the pre-rewrite location and 404ed for rewritten pages.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
indexFile expects a srcDir-relative page and joins it with srcDir, but
hotUpdate passed the absolute path, producing a doubled path that
failed the existence check — so edits never updated the local search
index. Regression from #3374.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The markdownToVue compile cache is keyed by the rewrite-applied
relativePath, but include-triggered invalidation passed the source
path, so pages with rewrites served stale content in dev when an
included file changed.
closes#5035
Co-authored-by: yyznm <yyz_nm@163.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A markdown or Vue file whose path contains the word "docsearch" was
intercepted by the @docsearch/css transform and never compiled,
failing the build. Check page extensions first.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Equivalent to re-applying the rewrite map manually, but hardened
against drive-letter case mismatches on Windows.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Previously generateSitemap re-read and re-parsed every source file to
compute lastmod, reconstructing source paths from URLs. The transform
hook now records the already-computed pageData.lastUpdated per page,
keyed by its rewrite-applied relativePath. Dynamic route pages now get
a lastmod too (from their route template), which the old file lookup
could not resolve.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Standardizes the tone across the file and documents all previously
undocumented types and members.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
dist/web-types.json is generated at build time so its version stays in
sync with the package.
closes#5157
Co-authored-by: Joaquín Sánchez <userquin@gmail.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Since #5156 the vue GlobalComponents augmentation exists in both
src/client/index.ts and dist/client/index.d.ts. The unit tests type
check included both copies (vitepress mapped to source, theme.d.ts
hardcoding ./dist/client/index.js), failing with TS2717. A bare
'vitepress' import resolves to the same dist types for consumers but
respects paths in repo tsconfigs, keeping the test program all-source.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
`markdown.codeCopyButton` now holds both the button tooltip
(`tooltipText`) and the text shown after copying (`copiedText`),
per-locale overridable via `locales.<index>.markdown.codeCopyButton`.
The copied text is emitted as a `data-copied` attribute on the button
and rendered by the theme with `content: attr(data-copied)`.
BREAKING CHANGE: `markdown.codeCopyButtonTitle` is now
`markdown.codeCopyButton.tooltipText`, and its default changed from
"Copy Code" to "Copy code". The `--vp-code-copy-copied-text-content`
CSS variable and its built-in per-language `:lang()` defaults are
removed - set `codeCopyButton.copiedText` (per locale) instead.
close#4431
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Superseded by the `locales.<index>.markdown` option from #4431, which
the config already uses. Also drops a redundant comment from the locale
config files.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Uses the new `locales.<index>.markdown` option, with the strings
exported from each locale's config file. Labels come from the
translated examples in each locale's markdown guide where available;
the rest (es/pt/ja labels and the note/important/caution set) are
best-effort and open to native-speaker review.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Strings baked into pages by the markdown renderer can now be overridden
per locale via `locales.<index>.markdown` in the site config: container
titles (including GitHub-flavored alerts and custom containers) and the
code copy button title. Values resolve against `env.localeIndex` at
render time and fall back to the root markdown options, so the single
shared renderer keeps working unchanged.
close#4431
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
It worked around rollup-plugin-dts mis-emitting mdurl's Url type when
markdown-it's types were bundled into dist (#3935). The dts build now
keeps markdown-it and its subpaths external, and the generated type
bundles are byte-identical without the patch.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
New containers can be registered via
`markdown.container.customContainers`, mapping a container name to its
default title. Registered names work as `::: name` blocks and as
GitHub-style alerts (`> [!NAME]`), with custom titles, attributes, and
no-title behaving like the built-in types. Styling is left to the theme
via `.custom-block.name`.
close#3591close#3603close#4228
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>