Migrate the Algolia search integration to @docsearch v5. Replace the
singular `indexName` option with an `indices` array and rename the Ask
AI `assistantId` to Agent Studio's `agentId`. Split the DocSearch JS and
CSS bundles so keyword-only, Ask AI, and side panel modes each load only
what they need, and cache each entry point separately. Move language
filtering into per-index search parameters and validate credentials per
resolved mode so side-panel-only configurations initialize correctly.
BREAKING CHANGE: The Algolia search options have changed. `indexName` is
replaced by an `indices` array, the Ask AI `assistantId` is renamed to
`agentId`, and the root-level `searchParameters` option is removed in
favor of per-index `searchParameters` inside `indices`. Update your
`themeConfig.search.options` accordingly.
The local nav's bottom rule reads its own token instead of a
hardcoded gutter color. It follows --vp-nav-divider-color by default,
like the surface color follows the navbar's.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The frosted-glass surface disappeared from builds. Two causes stacked:
lightningcss (vite's css minifier) collapses a standard-first pair
into the prefixed declaration alone, and -webkit-backdrop-filter is
dead weight everywhere — Chromium and Firefox don't recognize it, and
WebKit ignores var() values in it (bug 289800).
Only the standard property is written now. The minifier re-adds the
prefix from it for its own targets. Safari 17 and earlier show the
translucent color without the blur, noted in the glass recipe's
warning.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The sidebar item row was a `role="button"` wrapping both the group heading
and a second `role="button"` caret, which is invalid HTML and nests
interactive controls. The caret is now the only control (a native button
with `aria-expanded`), the row keeps its click handler as a mouse-only
affordance, and groups without a heading render a `div` instead of a
`section`.
fixes#5366closes#5371
Co-authored-by: Jibin7Jose <jibinjose884@gmail.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Any element with an `id` is keyed by it regardless of attribute order, and a
`meta` without one is keyed by its first attribute other than `content`. This
stops differently named meta tags with the same content from overriding each
other and lets repeated meta tags be kept apart with unique ids.
fixes#5362closes#5363closes#5379
Co-authored-by: Lazizbek Ergashev <20501725+lazerg@users.noreply.github.com>
Co-authored-by: shamu45678 <220251922@seu.edu.cn>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
`watch([props, navEl], ...)` is only accidentally valid on the client,
where props reaching setup are shallow-reactive. During SSR props are
not reactified (dev mode additionally wraps them in shallowReadonly),
so dev-flavored SSR warns "Invalid watch source: Proxy({ open: false })"
once per rendered page. Normally invisible because build() forces
NODE_ENV=production before vue loads — but any process that already
required vue under a different NODE_ENV (programmatic builds inside
test runners) keeps dev vue in the module cache and surfaces it.
Repro (pure Vue, no vitepress): renderToString of a component doing
watch([props, ref], cb, { immediate: true, flush: 'post' }) under dev
vue. Watching `() => props.open` expresses the actual dependency and
is valid in both environments.
dcb7a755 turned hasActiveLink from a computed into a ref fed only by a
non-immediate watch and onMounted, so is-active/has-active stopped
rendering in static HTML. This broke pre-hydration sidebar highlighting
and the docsearch crawler's lvl0 selector (section.has-active div h2),
which has indexed every record as the defaultValue since then.
Run the update once during setup with the hash check skipped: the server
and the client's initial render compute identical path-only state, so
hydration stays clean; the watch and onMounted refine with the real hash
after mount.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Indexing runs unawaited from `configureServer`, so a page whose snippet or
include cannot be resolved rejected the scan and killed the process on
startup. Warn and skip the page instead; the error is still reported by the
markdown transform, and the build still fails on it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Documents the rewritten behavior: multi-region concatenation across
comment styles, region marker stripping, extra fence attributes from
snippet braces, build errors for missing files, regions and ranges
with the silent opt-out, url rebasing, which extensions are inferred
as a language, and including code files by line range through fenced
includes. Removes the outdated note claiming missing include files do
not error.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Relative image and link urls inside included markdown files now
resolve from the included file's location instead of from the page
including it, so a partial can link to its neighbors regardless of who
includes it. This matches @mdit/plugin-include, whose resolveImagePath
and resolveLinkPath are on by default as well.
Included content is wrapped in marker comments during expansion;
hidden html_block rules maintain a per-render directory stack and the
image and link_open renderer wrappers rebase '.'-prefixed urls against
its top, so nested includes resolve correctly and urls outside
included content are untouched. The markers are separated by blank
lines so an adjacent html block cannot absorb them, and are only
emitted for directives on a line of their own outside fenced blocks,
so they can never reach the output. The include plugin registers after
the image and link plugins so that rebasing runs before their url
handling.
BREAKING CHANGE: relative urls in included markdown files resolve
against the included file rather than the including page. Partials
written for one specific location may need their links updated, or
markdown.include.rebaseRelativeUrls set to false to keep resolving
them from the including page. Absolute and external urls are
unaffected. Note that the marker comments shift the line numbers
reported for dead links following an include, which already pointed
into the include-expanded source rather than the original file.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Moves <!-- @include: --> expansion out of markdownToVue and the local
search plugin into an include plugin registered on the renderer, which
wraps renderAsync and expands includes whenever the env carries a file
path. createMarkdownRenderer users and createContentLoader with render
or excerpt enabled now get includes expanded too (previously the
directives silently came through unexpanded), and the expansion is
reachable from the public API without exporting the helper (#4838).
Region selection uses the region engine (all same-named regions
concatenate, matched across comment styles), frontmatter of markdown
files is stripped before locating regions and headings so both share
one coordinate space, and the region suffix is anchored to the end of
the include path, so paths containing # now work.
Files reached by a failed render are still reported, so that creating
a missing snippet or include recovers the page instead of requiring an
edit of the including file.
BREAKING CHANGES:
- a missing region or heading anchor now throws instead of silently
including the whole file, and out-of-bounds or inverted ranges throw
instead of clamping; markdown.include.silent logs a warning and
expands to nothing instead
- markdown.include is a new option; false disables include processing
- custom search _render functions receive the raw source (sync
md.render does not expand includes; use renderAsync)
- the include-expanded source is exposed as env.src
Co-authored-by: Miroma <its.miroma@proton.me>
Co-authored-by: Naloam <110604855+Naloam@users.noreply.github.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Replaces the single-regex raw path parsing with a structural parser
that peels [title], {meta} and #region off the end, so meta can no
longer be silently swallowed into the file path. Inside the braces,
everything after the language is now passed through to the fence info
verbatim, allowing multiple attributes and quoted values (e.g.
{ts twoslash key="a b"}). Extensions are derived from the file name,
so dotfiles resolve, region references may contain dots, and {1, 2}
style spacing is tolerated.
Region extraction uses the new region engine, so all same-named
regions are concatenated in document order, and which marker lines are
removed from the output is configurable through stripRegionMarkers.
BREAKING CHANGES:
- a missing snippet file or region now throws instead of rendering an
error message inside the code block (or importing the whole file, in
the region case); the silent option restores non-fatal behavior by
logging a warning and rendering nothing
- the language inferred from a file name now includes uppercase
extensions, which were previously matched as [a-z0-9]+ only, so a
snippet of e.g. Foo.TS is highlighted where it used to render
without a language; suffixes that are not alphanumeric, like .c++ or
.code-snippets, are still not inferred and need the language given
in the braces
- markdown.snippet now accepts an options object in addition to the
boolean toggle
- rawPathToToken, findRegion and dedent are no longer exported from
the plugin module
Co-authored-by: Miroma <its.miroma@proton.me>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>