diff --git a/packages/docusaurus-theme-classic/src/__tests__/validateThemeConfig.test.ts b/packages/docusaurus-theme-classic/src/__tests__/validateThemeConfig.test.ts index a333f882b5..6fe62bb524 100644 --- a/packages/docusaurus-theme-classic/src/__tests__/validateThemeConfig.test.ts +++ b/packages/docusaurus-theme-classic/src/__tests__/validateThemeConfig.test.ts @@ -112,6 +112,13 @@ describe('themeConfig', () => { docId: 'intro', label: 'Introduction', }, + // Doc link with HTML as label + { + type: 'doc', + position: 'left', + docId: 'intro', + html: 'Introduction', + }, // Regular link { to: '/guide/', @@ -119,6 +126,13 @@ describe('themeConfig', () => { position: 'left', activeBaseRegex: '/guide/', }, + // Regular link with HTML as label + { + to: '/guide/', + html: 'Guide', + position: 'left', + activeBaseRegex: '/guide/', + }, // Regular dropdown { label: 'Community', @@ -136,10 +150,10 @@ describe('themeConfig', () => { }, ], }, - // Dropdown with name + // Dropdown with label as HTML { type: 'dropdown', - label: 'Tools', + label: 'Tools new', position: 'left', items: [ { diff --git a/packages/docusaurus-theme-classic/src/theme-classic.d.ts b/packages/docusaurus-theme-classic/src/theme-classic.d.ts index 9f3c48ed3d..cde00cc5c6 100644 --- a/packages/docusaurus-theme-classic/src/theme-classic.d.ts +++ b/packages/docusaurus-theme-classic/src/theme-classic.d.ts @@ -651,6 +651,7 @@ declare module '@theme/NavbarItem/NavbarNavLink' { readonly activeBaseRegex?: string; readonly exact?: boolean; readonly label?: ReactNode; + readonly html?: string; readonly prependBaseUrlToHref?: string; } diff --git a/packages/docusaurus-theme-classic/src/theme/NavbarItem/NavbarNavLink.tsx b/packages/docusaurus-theme-classic/src/theme/NavbarItem/NavbarNavLink.tsx index af498982f6..e19758815f 100644 --- a/packages/docusaurus-theme-classic/src/theme/NavbarItem/NavbarNavLink.tsx +++ b/packages/docusaurus-theme-classic/src/theme/NavbarItem/NavbarNavLink.tsx @@ -21,6 +21,7 @@ export default function NavbarNavLink({ to, href, label, + html, activeClassName = '', prependBaseUrlToHref, ...props @@ -33,32 +34,47 @@ export default function NavbarNavLink({ const isExternalLink = label && href && !isInternalUrl(href); const isDropdownLink = activeClassName === dropdownLinkActiveClass; + // Link content is set through html XOR label + const linkContentProps = html + ? {dangerouslySetInnerHTML: {__html: html}} + : { + children: ( + <> + {label} + {isExternalLink && ( + + )} + + ), + }; + + if (href) { + return ( + + ); + } + return ( - activeBaseRegex - ? isRegexpStringMatch(activeBaseRegex, location.pathname) - : location.pathname.startsWith(activeBaseUrl), - } - : null), - })} - {...props}> - {label} - {isExternalLink && ( - - )} - + to={toUrl} + isNavLink + activeClassName={ + !props.className?.includes(activeClassName) ? activeClassName : '' + } + {...((activeBasePath || activeBaseRegex) && { + isActive: (_match, location) => + activeBaseRegex + ? isRegexpStringMatch(activeBaseRegex, location.pathname) + : location.pathname.startsWith(activeBaseUrl), + })} + {...props} + {...linkContentProps} + /> ); } diff --git a/packages/docusaurus-theme-classic/src/validateThemeConfig.ts b/packages/docusaurus-theme-classic/src/validateThemeConfig.ts index 8de448ea65..c168709369 100644 --- a/packages/docusaurus-theme-classic/src/validateThemeConfig.ts +++ b/packages/docusaurus-theme-classic/src/validateThemeConfig.ts @@ -49,8 +49,10 @@ const NavbarItemPosition = Joi.string().equal('left', 'right').default('left'); const NavbarItemBaseSchema = Joi.object({ label: Joi.string(), + html: Joi.string(), className: Joi.string(), }) + .nand('html', 'label') // We allow any unknown attributes on the links (users may need additional // attributes like target, aria-role, data-customAttribute...) .unknown(); diff --git a/website/docs/api/themes/theme-configuration.md b/website/docs/api/themes/theme-configuration.md index d954079d52..fd1e4ac306 100644 --- a/website/docs/api/themes/theme-configuration.md +++ b/website/docs/api/themes/theme-configuration.md @@ -259,6 +259,7 @@ Accepted fields: | --- | --- | --- | --- | | `type` | `'default'` | Optional | Sets the type of this item to a link. | | `label` | `string` | **Required** | The name to be shown for this item. | +| `html` | `string` | Optional | Same as `label`, but renders pure HTML instead of text content. | | `to` | `string` | **Required** | Client-side routing, used for navigating within the website. The baseUrl will be automatically prepended to this value. | | `href` | `string` | **Required** | A full-page navigation, used for navigating outside of the website. **Only one of `to` or `href` should be used.** | | `prependBaseUrlToHref` | `boolean` | `false` | Prepends the baseUrl to `href` values. | @@ -288,6 +289,8 @@ module.exports = { // Only one of "to" or "href" should be used // href: 'https://www.facebook.com', label: 'Introduction', + // Only one of "label" or "html" should be used + // html: 'Introduction' position: 'left', activeBaseRegex: 'docs/(next|v8)', target: '_blank',