feat(theme): support custom target and rel in navbar links (#1993)

Co-authored-by: Kev1nzh37 <kev1nzh37@gmail.com>
pull/1995/head
Divyansh Singh 2 years ago committed by GitHub
parent 8e6e8d9af5
commit e2d4edf45b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -87,15 +87,22 @@ export default {
```ts ```ts
type NavItem = NavItemWithLink | NavItemWithChildren type NavItem = NavItemWithLink | NavItemWithChildren
type NavItemWithLink = { interface NavItemWithLink {
text: string text: string
link: string link: string
activeMatch?: string activeMatch?: string
target?: string
rel?: string
} }
interface NavItemWithChildren { interface NavItemChildren {
text?: string text?: string
items: NavItemWithLink[] items: NavItemWithLink[]
}
interface NavItemWithChildren {
text?: string
items: (NavItemChildren | NavItemWithLink)[]
activeMatch?: string activeMatch?: string
} }
``` ```

@ -138,6 +138,25 @@ export default {
`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. `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.
::: :::
### Customize link's "target" and "rel" attributes
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.
```js
export default {
themeConfig: {
nav: [
{
text: 'Merchandise',
link: 'https://www.thegithubshop.com/',
target: '_self',
rel: 'sponsored'
}
]
}
}
```
## Social Links ## Social Links
Refer [`socialLinks`](../config/theme-config#sociallinks). Refer [`socialLinks`](../config/theme-config#sociallinks).

@ -8,6 +8,8 @@ const props = defineProps<{
tag?: string tag?: string
href?: string href?: string
noIcon?: boolean noIcon?: boolean
target?: string
rel?: string
}>() }>()
const tag = computed(() => props.tag ?? props.href ? 'a' : 'span') const tag = computed(() => props.tag ?? props.href ? 'a' : 'span')
@ -20,8 +22,8 @@ const isExternal = computed(() => props.href && EXTERNAL_URL_RE.test(props.href)
class="VPLink" class="VPLink"
:class="{ link: href }" :class="{ link: href }"
:href="href ? normalizeLink(href) : undefined" :href="href ? normalizeLink(href) : undefined"
:target="isExternal ? '_blank' : undefined" :target="target || (isExternal ? '_blank' : undefined)"
:rel="isExternal ? 'noreferrer' : undefined" :rel="rel || (isExternal ? 'noreferrer' : undefined)"
> >
<slot /> <slot />
<VPIconExternalLink v-if="isExternal && !noIcon" class="icon" /> <VPIconExternalLink v-if="isExternal && !noIcon" class="icon" />

@ -1,10 +1,11 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { DefaultTheme } from 'vitepress/theme'
import { useData } from '../composables/data.js' import { useData } from '../composables/data.js'
import { isActive } from '../support/utils.js' import { isActive } from '../support/utils.js'
import VPLink from './VPLink.vue' import VPLink from './VPLink.vue'
defineProps<{ defineProps<{
item: any item: DefaultTheme.NavItemWithLink
}>() }>()
const { page } = useData() const { page } = useData()
@ -15,6 +16,8 @@ const { page } = useData()
<VPLink <VPLink
:class="{ active: isActive(page.relativePath, item.activeMatch || item.link, !!item.activeMatch) }" :class="{ active: isActive(page.relativePath, item.activeMatch || item.link, !!item.activeMatch) }"
:href="item.link" :href="item.link"
:target="item.target"
:rel="item.rel"
> >
{{ item.text }} {{ item.text }}
</VPLink> </VPLink>

@ -22,6 +22,8 @@ const { page } = useData()
) )
}" }"
:href="item.link" :href="item.link"
:target="item.target"
:rel="item.rel"
> >
{{ item.text }} {{ item.text }}
</VPLink> </VPLink>

@ -120,7 +120,7 @@ export namespace DefaultTheme {
export type NavItem = NavItemWithLink | NavItemWithChildren export type NavItem = NavItemWithLink | NavItemWithChildren
export type NavItemWithLink = { export interface NavItemWithLink {
text: string text: string
link: string link: string
@ -129,9 +129,11 @@ export namespace DefaultTheme {
* RegExp object here because it isn't serializable * RegExp object here because it isn't serializable
*/ */
activeMatch?: string activeMatch?: string
target?: string
rel?: string
} }
export type NavItemChildren = { export interface NavItemChildren {
text?: string text?: string
items: NavItemWithLink[] items: NavItemWithLink[]
} }

Loading…
Cancel
Save