facebook / facebook/docusaurus

Theming: use custom components as navbar/sidebar/footer items

Open
#7,227 17 comments 12 reactions 0 assignees View on GitHub
feature
Dominant language
TypeScript
Stars
66.2k
Forks
10k
Avg merge
1d 3h
Merged PRs (30d)
52

Description

Edit from @slorber:

## Temporary recommended workaround

Until we have first-class support and a convenient API to support this, here's the recommended way to add custom navbar items to your site (see also https://github.com/facebook/docusaurus/pull/7231)

Create a file in `src/theme/NavbarItem/ComponentTypes.js` to add a custom navbar item type to the existing mapping:

```js
import ComponentTypes from '@theme-original/NavbarItem/ComponentTypes';
import MyAwesomeNavbarItem from '@site/src/components/NavbarItems/MyAwesomeNavbarItem';

export default {
...ComponentTypes,
'custom-myAwesomeNavbarItem': MyAwesomeNavbarItem,
};
```

Use it in your config:

```js
module.exports = {
themeConfig: {
navbar: {
items: [
{
type: 'custom-myAwesomeNavbarItem',
position: "left",
itemProp: 44,
anotherProp: "xyz"
},
//... other navbar items
]
}
}
}
```

**Note**: using the `custom-` prefix is important: the config validation schema will only allow item types with this prefix.

----

## Original issue

### Have you read the Contributing Guidelines on issues?

- [X] I have read the [Contributing Guidelines on issues](https://github.com/facebook/docusaurus/blob/main/CONTRIBUTING.md#reporting-new-issues).

### Description

We'd like to propose a way to add custom navbar item components through the navbar items configuration, so they remain part of the regular layout of items in the navbar and mobile primary menu. To our understanding three things need to change:

1. Adjust the navbar items configuration validation to allow objects with a custom type property and a custom component property, similar to how the docs plugin allows a custom `docItemComponent` property to override the default rendering component. This object should allow arbitrary properties, which are passed as React properties to the custom component.

2. Adjust the `NavbarItem` component to allow for custom types, require their configured custom component and passing any additional custom properties to the custom component.

3. Improve API documentation on how navbar items should distinguish between if they are rendered for mobile or desktop, so the user can properly implement the component in case such a distinction is needed.

Open questions:
1. Do we regard any unknown type as custom type or do we require a certain pattern?
2. Do we require the custom component property to be configured or do we not? I guess in case the user swizzles the NavbarItem component and associates the type with a custom component there, requiring the component in the navbar items configuration is not strictly necessary.

### Has this been requested on Canny?

_No response_

### Motivation

We've implemented a custom dropdown component, which currently abuses the Docusaurus provided dropdown component configuration to bypass the configuration validation. This worked until beta.17, but from beta.18 onwards our implementation breaks, because of a major refactor in the navbar, which brought us to the point where we would like to propose a properly supported way of adding custom components to the navbar.

### API design

Configuration of the custom component in the navbar items configuration:
```
navbar: {
items: [
{
type: 'custom-type',
component: '@theme/CustomComponent',
customProperty: ...
},
...
],
...
}
```

### Have you tried building it?

We tried swizzling the `NavbarItem` component, but we ran into multiple issues, including correctly typing the custom component in the type to component map and configuration validation warnings. We'd be happy to create a PR after discussing the implementation proposed above.

### Self-service

- [x] I'd be willing to contribute this feature to Docusaurus myself.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.