Skip to content

Commit e2d4edf

Browse files
brc-ddkev1nzh37
andauthored
feat(theme): support custom target and rel in navbar links (#1993)
Co-authored-by: Kev1nzh37 <[email protected]>
1 parent 8e6e8d9 commit e2d4edf

File tree

6 files changed

+42
-7
lines changed

6 files changed

+42
-7
lines changed

docs/config/theme-config.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,15 +87,22 @@ export default {
8787
```ts
8888
type NavItem = NavItemWithLink | NavItemWithChildren
8989

90-
type NavItemWithLink = {
90+
interface NavItemWithLink {
9191
text: string
9292
link: string
9393
activeMatch?: string
94+
target?: string
95+
rel?: string
9496
}
9597

96-
interface NavItemWithChildren {
98+
interface NavItemChildren {
9799
text?: string
98100
items: NavItemWithLink[]
101+
}
102+
103+
interface NavItemWithChildren {
104+
text?: string
105+
items: (NavItemChildren | NavItemWithLink)[]
99106
activeMatch?: string
100107
}
101108
```

docs/guide/theme-nav.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,25 @@ export default {
138138
`activeMatch` is expected to be a regex string, but you must define it as a string. We can't use actual RegExp object here because it isn't serializable during the build time.
139139
:::
140140

141+
### Customize link's "target" and "rel" attributes
142+
143+
By default, VitePress automatically determines `target` and `rel` attributes based on whether the link is an external link. But if you want, you can customize them too.
144+
145+
```js
146+
export default {
147+
themeConfig: {
148+
nav: [
149+
{
150+
text: 'Merchandise',
151+
link: 'https://www.thegithubshop.com/',
152+
target: '_self',
153+
rel: 'sponsored'
154+
}
155+
]
156+
}
157+
}
158+
```
159+
141160
## Social Links
142161

143162
Refer [`socialLinks`](../config/theme-config#sociallinks).

src/client/theme-default/components/VPLink.vue

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ const props = defineProps<{
88
tag?: string
99
href?: string
1010
noIcon?: boolean
11+
target?: string
12+
rel?: string
1113
}>()
1214
1315
const tag = computed(() => props.tag ?? props.href ? 'a' : 'span')
@@ -20,8 +22,8 @@ const isExternal = computed(() => props.href && EXTERNAL_URL_RE.test(props.href)
2022
class="VPLink"
2123
:class="{ link: href }"
2224
:href="href ? normalizeLink(href) : undefined"
23-
:target="isExternal ? '_blank' : undefined"
24-
:rel="isExternal ? 'noreferrer' : undefined"
25+
:target="target || (isExternal ? '_blank' : undefined)"
26+
:rel="rel || (isExternal ? 'noreferrer' : undefined)"
2527
>
2628
<slot />
2729
<VPIconExternalLink v-if="isExternal && !noIcon" class="icon" />

src/client/theme-default/components/VPMenuLink.vue

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
<script lang="ts" setup>
2+
import type { DefaultTheme } from 'vitepress/theme'
23
import { useData } from '../composables/data.js'
34
import { isActive } from '../support/utils.js'
45
import VPLink from './VPLink.vue'
56
67
defineProps<{
7-
item: any
8+
item: DefaultTheme.NavItemWithLink
89
}>()
910
1011
const { page } = useData()
@@ -15,6 +16,8 @@ const { page } = useData()
1516
<VPLink
1617
:class="{ active: isActive(page.relativePath, item.activeMatch || item.link, !!item.activeMatch) }"
1718
:href="item.link"
19+
:target="item.target"
20+
:rel="item.rel"
1821
>
1922
{{ item.text }}
2023
</VPLink>

src/client/theme-default/components/VPNavBarMenuLink.vue

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ const { page } = useData()
2222
)
2323
}"
2424
:href="item.link"
25+
:target="item.target"
26+
:rel="item.rel"
2527
>
2628
{{ item.text }}
2729
</VPLink>

types/default-theme.d.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ export namespace DefaultTheme {
120120

121121
export type NavItem = NavItemWithLink | NavItemWithChildren
122122

123-
export type NavItemWithLink = {
123+
export interface NavItemWithLink {
124124
text: string
125125
link: string
126126

@@ -129,9 +129,11 @@ export namespace DefaultTheme {
129129
* RegExp object here because it isn't serializable
130130
*/
131131
activeMatch?: string
132+
target?: string
133+
rel?: string
132134
}
133135

134-
export type NavItemChildren = {
136+
export interface NavItemChildren {
135137
text?: string
136138
items: NavItemWithLink[]
137139
}

0 commit comments

Comments
 (0)