From 34cfa91b6f14d8adfaa2d3c9f3eb6ad8b889ef1c Mon Sep 17 00:00:00 2001
From: Miroma <136986257+its-miroma@users.noreply.github.com>
Date: Sat, 27 Sep 2025 11:15:56 +0200
Subject: [PATCH] feat(theme): allow passing functions for nav links (#4963)
---
docs/en/reference/default-theme-config.md | 2 +-
docs/en/reference/default-theme-nav.md | 2 ++
docs/es/reference/default-theme-config.md | 2 +-
docs/es/reference/default-theme-nav.md | 2 ++
docs/fa/reference/default-theme-config.md | 2 +-
docs/fa/reference/default-theme-nav.md | 2 ++
docs/ko/reference/default-theme-config.md | 2 +-
docs/ko/reference/default-theme-nav.md | 2 ++
docs/pt/reference/default-theme-config.md | 2 +-
docs/pt/reference/default-theme-nav.md | 2 ++
docs/ru/reference/default-theme-config.md | 2 +-
docs/ru/reference/default-theme-nav.md | 2 ++
docs/zh/reference/default-theme-config.md | 2 +-
docs/zh/reference/default-theme-nav.md | 2 ++
.../theme-default/components/VPMenuLink.vue | 13 ++++++++++---
.../components/VPNavBarMenuGroup.vue | 2 +-
.../theme-default/components/VPNavBarMenuLink.vue | 13 ++++++++++---
.../components/VPNavScreenMenuGroupLink.vue | 15 ++++++++++++---
.../components/VPNavScreenMenuLink.vue | 15 ++++++++++++---
types/default-theme.d.ts | 2 +-
20 files changed, 67 insertions(+), 21 deletions(-)
diff --git a/docs/en/reference/default-theme-config.md b/docs/en/reference/default-theme-config.md
index 39c3fcf7..4868cda3 100644
--- a/docs/en/reference/default-theme-config.md
+++ b/docs/en/reference/default-theme-config.md
@@ -89,7 +89,7 @@ type NavItem = NavItemWithLink | NavItemWithChildren
interface NavItemWithLink {
text: string
- link: string
+ link: string | ((payload: PageData) => string)
activeMatch?: string
target?: string
rel?: string
diff --git a/docs/en/reference/default-theme-nav.md b/docs/en/reference/default-theme-nav.md
index b55a63cb..f7be114d 100644
--- a/docs/en/reference/default-theme-nav.md
+++ b/docs/en/reference/default-theme-nav.md
@@ -55,6 +55,8 @@ export default {
The `text` is the actual text displayed in nav, and the `link` is the link that will be navigated to when the text is clicked. For the link, set path to the actual file without `.md` prefix, and always start with `/`.
+The `link` can also be a function that accepts [`PageData`](./runtime-api#usedata) as the argument and returns the path.
+
Nav links can also be dropdown menus. To do this, set `items` key on link option.
```js
diff --git a/docs/es/reference/default-theme-config.md b/docs/es/reference/default-theme-config.md
index 129f16f6..e413b275 100644
--- a/docs/es/reference/default-theme-config.md
+++ b/docs/es/reference/default-theme-config.md
@@ -89,7 +89,7 @@ type NavItem = NavItemWithLink | NavItemWithChildren
interface NavItemWithLink {
text: string
- link: string
+ link: string | ((payload: PageData) => string)
activeMatch?: string
target?: string
rel?: string
diff --git a/docs/es/reference/default-theme-nav.md b/docs/es/reference/default-theme-nav.md
index d244cba5..cab8639d 100644
--- a/docs/es/reference/default-theme-nav.md
+++ b/docs/es/reference/default-theme-nav.md
@@ -55,6 +55,8 @@ export default {
`text` es el texto que se muestra en la navegación, y el `link` es el link al que será navegando cuando se hace click en el texto. Para el enlace, establezca la ruta al archivo sin el prefijo `.md` y siempre comenzar por `/`.
+El `link` también puede ser una función que acepte [`PageData`](./runtime-api#usedata) como argumento y devuelva la ruta.
+
Links de navegación también pueden ser menus _dropdown_. Para hacer eso, establezca la clave de `items` en la opción del link.
```js
diff --git a/docs/fa/reference/default-theme-config.md b/docs/fa/reference/default-theme-config.md
index 1040f79b..9208db8d 100644
--- a/docs/fa/reference/default-theme-config.md
+++ b/docs/fa/reference/default-theme-config.md
@@ -89,7 +89,7 @@ type NavItem = NavItemWithLink | NavItemWithChildren
interface NavItemWithLink {
text: string
- link: string
+ link: string | ((payload: PageData) => string)
activeMatch?: string
target?: string
rel?: string
diff --git a/docs/fa/reference/default-theme-nav.md b/docs/fa/reference/default-theme-nav.md
index eafc5b53..c847a231 100644
--- a/docs/fa/reference/default-theme-nav.md
+++ b/docs/fa/reference/default-theme-nav.md
@@ -55,6 +55,8 @@ export default {
`text` متن واقعی است که در ناوبری نمایش داده میشود و `link` لینکی است که هنگام کلیک بر روی متن به آن ناوبری میشود. برای لینک، مسیر را به صورت واقعی بدون پیشوند `.md` تنظیم کنید و همیشه با `/` شروع کنید.
+`link` همچنین میتواند تابعی باشد که [`PageData`](./runtime-api#usedata) را به عنوان آرگومان بپذیرد و مسیر را برگرداند.
+
لینکهای ناوبری همچنین میتوانند منوهای کشویی باشند. برای این کار، کلید `items` را در گزینه لینک تنظیم کنید.
```js
diff --git a/docs/ko/reference/default-theme-config.md b/docs/ko/reference/default-theme-config.md
index b0df3361..66b2f4e0 100644
--- a/docs/ko/reference/default-theme-config.md
+++ b/docs/ko/reference/default-theme-config.md
@@ -89,7 +89,7 @@ type NavItem = NavItemWithLink | NavItemWithChildren
interface NavItemWithLink {
text: string
- link: string
+ link: string | ((payload: PageData) => string)
activeMatch?: string
target?: string
rel?: string
diff --git a/docs/ko/reference/default-theme-nav.md b/docs/ko/reference/default-theme-nav.md
index cdfdc7ef..433c2e07 100644
--- a/docs/ko/reference/default-theme-nav.md
+++ b/docs/ko/reference/default-theme-nav.md
@@ -55,6 +55,8 @@ export default {
`text`는 네비게이션 바에 표시되는 실제 텍스트이며, `link`는 텍스트를 클릭했을 때 이동할 링크입니다. 링크의 경로는 `.md` 접미사 없이 실제 파일 경로로 설정하며, 항상 `/`로 시작해야 합니다.
+`link`는 또한 [`PageData`](./runtime-api#usedata)를 인자로 받아 경로를 반환하는 함수가 될 수도 있습니다.
+
네비게이션 바 링크는 드롭다운 메뉴가 될 수 있습니다. 이를 위해 `link` 옵션에 `items` 키를 설정합니다.
```js
diff --git a/docs/pt/reference/default-theme-config.md b/docs/pt/reference/default-theme-config.md
index 54e53e4a..a1ac180f 100644
--- a/docs/pt/reference/default-theme-config.md
+++ b/docs/pt/reference/default-theme-config.md
@@ -89,7 +89,7 @@ type NavItem = NavItemWithLink | NavItemWithChildren
interface NavItemWithLink {
text: string
- link: string
+ link: string | ((payload: PageData) => string)
activeMatch?: string
target?: string
rel?: string
diff --git a/docs/pt/reference/default-theme-nav.md b/docs/pt/reference/default-theme-nav.md
index 5f0d2399..fefc9661 100644
--- a/docs/pt/reference/default-theme-nav.md
+++ b/docs/pt/reference/default-theme-nav.md
@@ -55,6 +55,8 @@ export default {
`text` é o próprio texto mostrado na navegação, e o `link` é o link para o qual será navegado quando o texto for clicado. Para o link, defina o caminho para o próprio arquivo sem o prefixo `.md` e sempre comece com `/`.
+O `link` também pode ser uma função que aceita [`PageData`](./runtime-api#usedata) como argumento e retorna o caminho.
+
Links de navegação também podem ser menus _dropdown_. Para fazer isso, defina a chave `items` na opção do link.
```js
diff --git a/docs/ru/reference/default-theme-config.md b/docs/ru/reference/default-theme-config.md
index 2eb95570..27b70443 100644
--- a/docs/ru/reference/default-theme-config.md
+++ b/docs/ru/reference/default-theme-config.md
@@ -89,7 +89,7 @@ type NavItem = NavItemWithLink | NavItemWithChildren
interface NavItemWithLink {
text: string
- link: string
+ link: string | ((payload: PageData) => string)
activeMatch?: string
target?: string
rel?: string
diff --git a/docs/ru/reference/default-theme-nav.md b/docs/ru/reference/default-theme-nav.md
index 41257de8..edfb9a9e 100644
--- a/docs/ru/reference/default-theme-nav.md
+++ b/docs/ru/reference/default-theme-nav.md
@@ -55,6 +55,8 @@ export default {
`text` — это текст, отображаемый в навигации, а `link` — это ссылка, на которую будет осуществлён переход при нажатии на текст. Для ссылки задайте путь к фактическому файлу без префикса `.md` и всегда начинайте с `/`.
+`link` также может быть функцией, которая принимает [`PageData`](./runtime-api#usedata) в качестве аргумента и возвращает путь.
+
Навигационные ссылки также могут быть выпадающими меню. Для этого установите ключ `items` вместо ключа `link`:
```js
diff --git a/docs/zh/reference/default-theme-config.md b/docs/zh/reference/default-theme-config.md
index dd7e86b3..c4f76ea5 100644
--- a/docs/zh/reference/default-theme-config.md
+++ b/docs/zh/reference/default-theme-config.md
@@ -89,7 +89,7 @@ type NavItem = NavItemWithLink | NavItemWithChildren
interface NavItemWithLink {
text: string
- link: string
+ link: string | ((payload: PageData) => string)
activeMatch?: string
target?: string
rel?: string
diff --git a/docs/zh/reference/default-theme-nav.md b/docs/zh/reference/default-theme-nav.md
index 194d18ee..b7d772f4 100644
--- a/docs/zh/reference/default-theme-nav.md
+++ b/docs/zh/reference/default-theme-nav.md
@@ -55,6 +55,8 @@ export default {
`text` 是 nav 中显示的实际文本,而 `link` 是单击文本时将导航到的链接。对于链接,将路径设置为不带 `.md` 后缀的实际文件,并且始终以 `/` 开头。
+`link` 也可以是一个函数,它接受 [`PageData`](./runtime-api#usedata) 作为参数并返回路径。
+
导航链接也可以是下拉菜单。为此,请替换 `link` 选项,设置 `items` 数组。
```js
diff --git a/src/client/theme-default/components/VPMenuLink.vue b/src/client/theme-default/components/VPMenuLink.vue
index a4cebc10..249b7eee 100644
--- a/src/client/theme-default/components/VPMenuLink.vue
+++ b/src/client/theme-default/components/VPMenuLink.vue
@@ -1,15 +1,22 @@
@@ -20,11 +27,11 @@ defineOptions({ inheritAttrs: false })
:class="{
active: isActive(
page.relativePath,
- item.activeMatch || item.link,
+ item.activeMatch || href,
!!item.activeMatch
)
}"
- :href="item.link"
+ :href
:target="item.target"
:rel="item.rel"
:no-icon="item.noIcon"
diff --git a/src/client/theme-default/components/VPNavBarMenuGroup.vue b/src/client/theme-default/components/VPNavBarMenuGroup.vue
index 12e8cf6f..76cd42c5 100644
--- a/src/client/theme-default/components/VPNavBarMenuGroup.vue
+++ b/src/client/theme-default/components/VPNavBarMenuGroup.vue
@@ -17,7 +17,7 @@ const isChildActive = (navItem: DefaultTheme.NavItem) => {
if ('link' in navItem) {
return isActive(
page.value.relativePath,
- navItem.link,
+ typeof navItem.link === "function" ? navItem.link(page.value) : navItem.link,
!!props.item.activeMatch
)
}
diff --git a/src/client/theme-default/components/VPNavBarMenuLink.vue b/src/client/theme-default/components/VPNavBarMenuLink.vue
index 6f504791..e9869e1f 100644
--- a/src/client/theme-default/components/VPNavBarMenuLink.vue
+++ b/src/client/theme-default/components/VPNavBarMenuLink.vue
@@ -1,14 +1,21 @@
@@ -17,11 +24,11 @@ const { page } = useData()
VPNavBarMenuLink: true,
active: isActive(
page.relativePath,
- item.activeMatch || item.link,
+ item.activeMatch || href,
!!item.activeMatch
)
}"
- :href="item.link"
+ :href
:target="item.target"
:rel="item.rel"
:no-icon="item.noIcon"
diff --git a/src/client/theme-default/components/VPNavScreenMenuGroupLink.vue b/src/client/theme-default/components/VPNavScreenMenuGroupLink.vue
index 7633a8bb..32e97c83 100644
--- a/src/client/theme-default/components/VPNavScreenMenuGroupLink.vue
+++ b/src/client/theme-default/components/VPNavScreenMenuGroupLink.vue
@@ -1,20 +1,29 @@