diff --git a/src/node/markdown/markdown.ts b/src/node/markdown/markdown.ts index fbe92b30e..11037dd79 100644 --- a/src/node/markdown/markdown.ts +++ b/src/node/markdown/markdown.ts @@ -26,7 +26,7 @@ import mditCjkFriendly from 'markdown-it-cjk-friendly' import { full as emojiPlugin } from 'markdown-it-emoji' import type { BuiltinLanguage, BuiltinTheme, Highlighter } from 'shiki' import type { Logger } from 'vite' -import type { Awaitable } from '../shared' +import type { Awaitable, ExternalLinkAttrValue } from '../shared' import { containerPlugin, type ContainerOptions } from './plugins/containers' import { gitHubAlertsPlugin } from './plugins/githubAlerts' import { highlight as createHighlighter } from './plugins/highlight' @@ -62,7 +62,7 @@ export interface MarkdownOptions extends MarkdownItAsyncOptions { * Disable cache (experimental) */ cache?: boolean - externalLinks?: Record + externalLinks?: Record /* ==================== Syntax Highlighting ==================== */ @@ -279,7 +279,11 @@ export async function createMarkdownRenderer( imagePlugin(md, options.image) linkPlugin( md, - { target: '_blank', rel: 'noreferrer', ...options.externalLinks }, + { + target: '_blank', + rel: { value: 'noreferrer', join: true }, + ...options.externalLinks + }, base, slugify ) diff --git a/src/node/markdown/plugins/link.ts b/src/node/markdown/plugins/link.ts index 2fe2e1acc..d33726d08 100644 --- a/src/node/markdown/plugins/link.ts +++ b/src/node/markdown/plugins/link.ts @@ -8,14 +8,15 @@ import { EXTERNAL_URL_RE, isExternal, treatAsHtml, - type MarkdownEnv + type MarkdownEnv, + type ExternalLinkAttrValue } from '../../shared' const indexRE = /(^|.*\/)index.md(#?.*)$/i export const linkPlugin = ( md: MarkdownItAsync, - externalAttrs: Record, + externalAttrs: Record, base: string, slugify: (str: string) => string ) => { @@ -38,7 +39,15 @@ export const linkPlugin = ( const url = hrefAttr[1] if (isExternal(url)) { Object.entries(externalAttrs).forEach(([key, val]) => { - token.attrSet(key, val) + if (typeof val === 'string') { + token.attrSet(key, val) + } else { + if (val.join) { + token.attrJoin(key, val.value) + } else { + token.attrSet(key, val.value) + } + } }) // catch localhost links as dead link if (url.replace(EXTERNAL_URL_RE, '').startsWith('//localhost:')) { diff --git a/src/shared/shared.ts b/src/shared/shared.ts index f16a25bae..5d1c0d43d 100644 --- a/src/shared/shared.ts +++ b/src/shared/shared.ts @@ -19,7 +19,8 @@ export type { SSGContext, AdditionalConfig, AdditionalConfigDict, - AdditionalConfigLoader + AdditionalConfigLoader, + ExternalLinkAttrValue } from '../../types/shared' export const EXTERNAL_URL_RE = /^(?:[a-z]+:|\/\/)/i diff --git a/types/shared.d.ts b/types/shared.d.ts index bc8d28d46..021b627e5 100644 --- a/types/shared.d.ts +++ b/types/shared.d.ts @@ -232,3 +232,8 @@ export interface MarkdownEnv { realPath?: string localeIndex?: string } + +export interface ExternalLinkAttrValue { + value: string + join?: boolean +}