diff --git a/packages/docusaurus-theme-classic/src/__tests__/validateThemeConfig.test.ts b/packages/docusaurus-theme-classic/src/__tests__/validateThemeConfig.test.ts
index 4817935c52f7..7ac6a7eda81e 100644
--- a/packages/docusaurus-theme-classic/src/__tests__/validateThemeConfig.test.ts
+++ b/packages/docusaurus-theme-classic/src/__tests__/validateThemeConfig.test.ts
@@ -150,12 +150,22 @@ describe('themeConfig', () => {
},
],
},
+ // HTML-only
+ {
+ type: 'html',
+ position: 'right',
+ value: '',
+ },
// Dropdown with label as HTML
{
type: 'dropdown',
label: 'Tools new',
position: 'left',
items: [
+ {
+ type: 'html',
+ value: 'Supported package managers',
+ },
{
type: 'doc',
docId: 'npm',
@@ -181,6 +191,10 @@ describe('themeConfig', () => {
},
],
dropdownItemsAfter: [
+ {
+ type: 'html',
+ value: '
',
+ },
{
to: '/versions',
label: 'All versions',
diff --git a/packages/docusaurus-theme-classic/src/theme-classic.d.ts b/packages/docusaurus-theme-classic/src/theme-classic.d.ts
index 233f229c9f84..d9462dfee076 100644
--- a/packages/docusaurus-theme-classic/src/theme-classic.d.ts
+++ b/packages/docusaurus-theme-classic/src/theme-classic.d.ts
@@ -872,6 +872,16 @@ declare module '@theme/NavbarItem/DocSidebarNavbarItem' {
export default function DocSidebarNavbarItem(props: Props): JSX.Element;
}
+declare module '@theme/NavbarItem/HtmlNavbarItem' {
+ import type {Props as DefaultNavbarItemProps} from '@theme/NavbarItem/DefaultNavbarItem';
+
+ export interface Props extends DefaultNavbarItemProps {
+ readonly value: string;
+ }
+
+ export default function HtmlNavbarItem(props: Props): JSX.Element;
+}
+
declare module '@theme/NavbarItem' {
import type {ComponentProps} from 'react';
import type {Props as DefaultNavbarItemProps} from '@theme/NavbarItem/DefaultNavbarItem';
@@ -882,12 +892,14 @@ declare module '@theme/NavbarItem' {
import type {Props as DocsVersionDropdownNavbarItemProps} from '@theme/NavbarItem/DocsVersionDropdownNavbarItem';
import type {Props as LocaleDropdownNavbarItemProps} from '@theme/NavbarItem/LocaleDropdownNavbarItem';
import type {Props as SearchNavbarItemProps} from '@theme/NavbarItem/SearchNavbarItem';
+ import type {Props as HtmlNavbarItemProps} from '@theme/NavbarItem/HtmlNavbarItem';
export type LinkLikeNavbarItemProps =
| ({readonly type?: 'default'} & DefaultNavbarItemProps)
| ({readonly type: 'doc'} & DocNavbarItemProps)
| ({readonly type: 'docsVersion'} & DocsVersionNavbarItemProps)
- | ({readonly type: 'docSidebar'} & DocSidebarNavbarItemProps);
+ | ({readonly type: 'docSidebar'} & DocSidebarNavbarItemProps)
+ | ({readonly type: 'html'} & HtmlNavbarItemProps);
export type Props = ComponentProps<'a'> & {
readonly position?: 'left' | 'right';
diff --git a/packages/docusaurus-theme-classic/src/theme/NavbarItem/HtmlNavbarItem.tsx b/packages/docusaurus-theme-classic/src/theme/NavbarItem/HtmlNavbarItem.tsx
new file mode 100644
index 000000000000..19ead028756b
--- /dev/null
+++ b/packages/docusaurus-theme-classic/src/theme/NavbarItem/HtmlNavbarItem.tsx
@@ -0,0 +1,32 @@
+/**
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+import React from 'react';
+import clsx from 'clsx';
+
+import type {Props} from '@theme/NavbarItem/HtmlNavbarItem';
+
+export default function HtmlNavbarItem({
+ value,
+ className,
+ mobile = false,
+ isDropdownItem = false,
+}: Props): JSX.Element {
+ const Comp = isDropdownItem ? 'li' : 'div';
+ return (
+
+ );
+}
diff --git a/packages/docusaurus-theme-classic/src/theme/NavbarItem/index.tsx b/packages/docusaurus-theme-classic/src/theme/NavbarItem/index.tsx
index d9c5e9d30df8..7c3c9b07b56f 100644
--- a/packages/docusaurus-theme-classic/src/theme/NavbarItem/index.tsx
+++ b/packages/docusaurus-theme-classic/src/theme/NavbarItem/index.tsx
@@ -12,6 +12,7 @@ import DropdownNavbarItem, {
} from '@theme/NavbarItem/DropdownNavbarItem';
import LocaleDropdownNavbarItem from '@theme/NavbarItem/LocaleDropdownNavbarItem';
import SearchNavbarItem from '@theme/NavbarItem/SearchNavbarItem';
+import HtmlNavbarItem from '@theme/NavbarItem/HtmlNavbarItem';
import type {Types, Props} from '@theme/NavbarItem';
const NavbarItemComponents: {
@@ -23,6 +24,7 @@ const NavbarItemComponents: {
localeDropdown: () => LocaleDropdownNavbarItem,
search: () => SearchNavbarItem,
dropdown: () => DropdownNavbarItem,
+ html: () => HtmlNavbarItem,
// Need to lazy load these items as we don't know for sure the docs plugin is
// loaded. See https://github.com/facebook/docusaurus/issues/3360
diff --git a/packages/docusaurus-theme-classic/src/validateThemeConfig.ts b/packages/docusaurus-theme-classic/src/validateThemeConfig.ts
index 70f28373cec4..6708539c2730 100644
--- a/packages/docusaurus-theme-classic/src/validateThemeConfig.ts
+++ b/packages/docusaurus-theme-classic/src/validateThemeConfig.ts
@@ -93,6 +93,12 @@ const DocSidebarItemSchema = NavbarItemBaseSchema.append({
docsPluginId: Joi.string(),
});
+const HtmlNavbarItemSchema = Joi.object({
+ className: Joi.string(),
+ type: Joi.string().equal('html').required(),
+ value: Joi.string().required(),
+});
+
const itemWithType = (type: string | undefined) => {
// because equal(undefined) is not supported :/
const typeSchema = type
@@ -125,6 +131,10 @@ const DropdownSubitemSchema = Joi.object({
is: itemWithType(undefined),
then: DefaultNavbarItemSchema,
},
+ {
+ is: itemWithType('html'),
+ then: HtmlNavbarItemSchema,
+ },
{
is: Joi.alternatives().try(
itemWithType('dropdown'),
@@ -196,6 +206,10 @@ const NavbarItemSchema = Joi.object({
is: itemWithType('search'),
then: SearchItemSchema,
},
+ {
+ is: itemWithType('html'),
+ then: HtmlNavbarItemSchema,
+ },
{
is: itemWithType(undefined),
then: Joi.object().when('.', {
diff --git a/website/docs/api/themes/theme-configuration.md b/website/docs/api/themes/theme-configuration.md
index fd1e4ac30659..d496a7ed8bd6 100644
--- a/website/docs/api/themes/theme-configuration.md
+++ b/website/docs/api/themes/theme-configuration.md
@@ -312,6 +312,7 @@ Navbar dropdown items only accept the following **"link-like" item types**:
- [Navbar doc link](#navbar-doc-link)
- [Navbar docs version](#navbar-docs-version)
- [Navbar doc sidebar](#navbar-doc-sidebar)
+- [Navbar with custom HTML](#navbar-with-custom-html)
Note that the dropdown base item is a clickable link as well, so this item can receive any of the props of a [plain navbar link](#navbar-link).
@@ -621,6 +622,39 @@ module.exports = {
};
```
+#### Navbar with custom HTML {#navbar-with-custom-html}
+
+You can also render your own HTML markup inside a navbar item using this navbar item type.
+
+
+
+| Name | Type | Default | Description |
+| --- | --- | --- | --- |
+| `type` | `'html'` | **Required** | Sets the type of this item to a HTML element. |
+| `position` | 'left' \| 'right'
| `'left'` | The side of the navbar this item should appear on. |
+| `className` | `string` | `''` | Custom CSS class for this navbar item. |
+| `value` | `string` | `''` | Custom HTML to be rendered inside this navbar item. |
+
+
+
+```js title="docusaurus.config.js"
+module.exports = {
+ themeConfig: {
+ navbar: {
+ items: [
+ // highlight-start
+ {
+ type: 'html',
+ position: 'right',
+ value: '',
+ },
+ // highlight-end
+ ],
+ },
+ },
+};
+```
+
### Auto-hide sticky navbar {#auto-hide-sticky-navbar}
You can enable this cool UI feature that automatically hides the navbar when a user starts scrolling down the page, and show it again when the user scrolls up.
diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js
index 8c4bebc928a8..8e396e641b41 100644
--- a/website/docusaurus.config.js
+++ b/website/docusaurus.config.js
@@ -419,6 +419,15 @@ const config = {
position: 'right',
dropdownActiveClassDisabled: true,
dropdownItemsAfter: [
+ {
+ type: 'html',
+ value: '
',
+ },
+ {
+ type: 'html',
+ className: 'dropdown-archived-versions',
+ value: 'Archived versions',
+ },
...ArchivedVersionsDropdownItems.map(
([versionName, versionUrl]) => ({
label: versionName,
@@ -429,6 +438,10 @@ const config = {
href: 'https://v1.docusaurus.io',
label: '1.x.x',
},
+ {
+ type: 'html',
+ value: '
',
+ },
{
to: '/versions',
label: 'All versions',
@@ -439,6 +452,10 @@ const config = {
type: 'localeDropdown',
position: 'right',
dropdownItemsAfter: [
+ {
+ type: 'html',
+ value: '
',
+ },
{
href: 'https://github.com/facebook/docusaurus/issues/3526',
label: 'Help Us Translate',
diff --git a/website/src/css/custom.css b/website/src/css/custom.css
index 728c5d628a99..11b4f2fa04e4 100644
--- a/website/src/css/custom.css
+++ b/website/src/css/custom.css
@@ -207,3 +207,12 @@ div[class^='announcementBar_'] {
height: 100%;
}
}
+
+.dropdown-separator {
+ margin: 0.3rem 0;
+}
+
+.dropdown-archived-versions {
+ font-size: 0.875rem;
+ padding: 0.2rem 0.5rem;
+}