Replace the standalone `useData().hash` ref (backed by its own
`hashchange` listener in `initData`) with the `hash` already tracked on
the route, so the current URL is observed in one place and behaves
consistently during SSR.
- `isActive()` no longer reads `location.hash` at call time; it takes
the current hash as an argument (plus an optional `skipHashCheck`)
and `matchPath` is now required, making it pure and SSR-safe
- nav bar menus, nav screen menus, and menu links now react to hash-only
navigation too
- sidebar active-state tracking is reworked on top of the route: items
without a link are handled, and collapsed groups reliably auto-expand
when a child link becomes active (including on hash changes)
- prev/next links now properly ignore query strings and hashes when
deduplicating sidebar candidates (via `normalize`) and when matching
the current page
- custom `i18nRouting` functions receive the whole current `Route`
instead of only the hash string; language menu links are resolved
from the route (en + ru docs updated)
- `useLangs()` / `resolveLocaleLink()` are refactored with
self-documenting, JSDoc'd options (`linkToCorrespondingPage`,
`targetLocaleLink`, `currentLocaleLink`), and `resolveLocaleLink`
gained focused unit tests covering locale-home links, corresponding
links, cleanUrls, index pages, root-locale switching, and custom
routing functions
- unavoidable hydration mismatches are silenced with
`data-allow-mismatch` (viewport-dependent inline styles, per-locale
alternate links that embed the current query/hash)
- the `Route` interface moved to the shared types so
`DefaultTheme.I18nRouting` can reference it; the `vitepress` type
export is unchanged
- misc cleanups: `uniqBy` moved to theme support utils, `smartComputed`
comparator now called as `(newValue, oldValue)`, import ordering
BREAKING CHANGE: `useData().hash` has been removed. Read the hash from
`useRoute()` instead.
BREAKING CHANGE: custom `themeConfig.i18nRouting` functions now receive
the current `Route` as their second argument instead of the hash
string: `(data, route, targetLocale) => string`. Use `route.hash` for
the previous value; `route.path`, `route.query`, and `route.data` are
available as well.