import { Hue, Lightness, Saturation } from '@components/_slider'
import { Screenshot } from 'components/screenshot'
import { Callout } from 'nextra/components'
import logoImage from 'public/assets/docs/logo.png'
import sidebarTitleComponentImage from 'public/assets/docs/sidebar-customized.png'

# Theme Configuration

The theme is configured with the
[theme.config.jsx](/docs/docs-theme/start#create-docs-theme-config) file. It
should export an object that contains your configurations, for example:

```jsx filename="theme.config.jsx"
export default {
  project: {
    link: 'https://github.com/shuding/nextra'
  },
  logo: <b>Project</b>
}
```

Detailed information for each option is listed below.

## Global

### Docs Repository

Set the repository URL of the documentation. It’s used to generate the
“[Edit this page](#edit-link)” link and the “[Feedback](#feedback-link)” link.

export function Table({ children }) {
  return (
    <table className="w-full !table text-sm">
      <thead>
        <tr>
          <th align="left">Option</th>
          <th align="left">Type</th>
          <th align="left">Description</th>
        </tr>
      </thead>
      <tbody className="break-all first:[&_td]:font-semibold first:[&_td]:text-violet-600 first:[&_td]:dark:text-violet-500 [&_tr]:!bg-transparent">
        {children.props.children[1].props.children}
      </tbody>
    </table>
  )
}

<Table>

|                    |          |                                     |
| ------------------ | -------- | ----------------------------------- |
| docsRepositoryBase | `string` | URL of the documentation repository |

</Table>

#### Specify a Path

If the documentation is inside a monorepo, a subfolder, or a different branch of
the repository, you can simply set the `docsRepositoryBase` to the root path of
the `pages/` folder of your docs. For example:

```js filename="theme.config.jsx"
export default {
  docsRepositoryBase: 'https://github.com/shuding/nextra/tree/main/docs'
}
```

Then Nextra will automatically generate the correct file path for all pages.

### Head Tags

Configure the `<head>` tags of the website. You can add meta tags, title,
favicon, etc.

<Table>

|      |                                |                                             |
| ---- | ------------------------------ | ------------------------------------------- |
| head | `React.ReactNode \|  React.FC` | Component that renders the `<head>` content |

</Table>

#### Static Head Tags

If you have only static head tags, it’s easy to directly put them in `head`. For
example:

```jsx filename="theme.config.jsx"
export default {
  head: (
    <>
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      <meta property="og:title" content="Nextra" />
      <meta property="og:description" content="The next site builder" />
    </>
  )
}
```

#### Dynamic Tags Based on Page

You can also use a _function component_ as `head` to dynamically generate the
head tags based on the current page’s front matter. For example:

```jsx filename="theme.config.jsx"
import { useRouter } from 'next/router'
import { useConfig } from 'nextra-theme-docs'

export default {
  head() {
    const { asPath, defaultLocale, locale } = useRouter()
    const { frontMatter } = useConfig()
    const url =
      'https://my-app.com' +
      (defaultLocale === locale ? asPath : `/${locale}${asPath}`)

    return (
      <>
        <meta property="og:url" content={url} />
        <meta property="og:title" content={frontMatter.title || 'Nextra'} />
        <meta
          property="og:description"
          content={frontMatter.description || 'The next site builder'}
        />
      </>
    )
  }
}
```

You can refer to the [`useConfig`](/docs/docs-theme/api/use-config) API section
for more information about the `useConfig` hook and the `frontMatter` object.

### Dark Mode and Themes

Customize the theme behavior of the website.

<Table>

|            |           |                                                                                                       |
| ---------- | --------- | ----------------------------------------------------------------------------------------------------- |
| darkMode   | `boolean` | Show or hide the dark mode toggle button                                                              |
| nextThemes | `object`  | Configuration for the [next-themes](https://github.com/pacocoursey/next-themes#themeprovider) package |

</Table>

### Theme Color

You can adjust the theme color of the website by setting primary hue, saturation
and lightness (HSL) values for light and dark themes.

<Table>

|                       |                                             |                                                     |
| --------------------- | ------------------------------------------- | --------------------------------------------------- |
| color.hue             | `number \| { dark: number; light: number }` | The hue of the primary theme color (0 - 360)        |
| color.saturation      | `number \| { dark: number; light: number }` | The saturation of the primary theme color (0 - 100) |
| color.lightness       | `number \| { dark: number; light: number }` | The lightness of the primary theme color (0 - 100)  |
| backgroundColor.dark  | `string` in format `RRR,GGG,BBB`            | Background color for light theme                    |
| backgroundColor.light | `string` in format `RRR,GGG,BBB`            | Background color for dark theme                     |

</Table>

Try it out for this website:

| Hue (H) | Saturation (S) | Lightness (L) |
| ------- | -------------- | ------------- |
| <Hue /> | <Saturation /> | <Lightness/>  |

<Callout>

You can adjust the lightness independently for dark or light mode to increase
legibility. For example, to have a neutral primary color you can set the primary
colour to be white `HSL(0, 0%, 100%)` on dark theme and gray `HSL(0, 0%, 50%)`
for light theme.

```jsx filename="theme.config.jsx"
export default {
  color: {
    hue: 0,
    saturation: 0,
    lightness: {
      dark: 100,
      light: 50
    }
  }
}
```

</Callout>

## Navbar

### Logo

The logo of the website rendered on the navbar. It can be a React node or a
function component.

<Table>

|          |                               |                     |
| -------- | ----------------------------- | ------------------- |
| logo     | `React.ReactNode \| React.FC` | Logo of the website |
| logoLink | `boolean \| string`           | Link of the logo    |

</Table>

<Screenshot src={logoImage} alt="Customized Logo" />

<div className="mt-8 text-center text-sm">
  [Live example on StackBlitz
  ↗](https://stackblitz.com/edit/nextra-2-docs-yrlccm?file=theme.config.jsx)
</div>

```jsx filename="theme.config.jsx"
export default {
  logo: (
    <>
      <svg width="24" height="24" viewBox="0 0 24 24">
        <path
          fill="currentColor"
          d="M14.683 14.828a4.055 4.055 0 0 1-1.272.858a4.002 4.002 0 0 1-4.875-1.45l-1.658 1.119a6.063 6.063 0 0 0 1.621 1.62a5.963 5.963 0 0 0 2.148.903a6.035 6.035 0 0 0 3.542-.35a6.048 6.048 0 0 0 1.907-1.284c.272-.271.52-.571.734-.889l-1.658-1.119a4.147 4.147 0 0 1-.489.592z M12 2C6.486 2 2 6.486 2 12s4.486 10 10 10s10-4.486 10-10S17.514 2 12 2zm0 2c2.953 0 5.531 1.613 6.918 4H5.082C6.469 5.613 9.047 4 12 4zm0 16c-4.411 0-8-3.589-8-8c0-.691.098-1.359.264-2H5v1a2 2 0 0 0 2 2h2a2 2 0 0 0 2-2h2a2 2 0 0 0 2 2h2a2 2 0 0 0 2-2v-1h.736c.166.641.264 1.309.264 2c0 4.411-3.589 8-8 8z"
        />
      </svg>
      <span style={{ marginLeft: '.4em', fontWeight: 800 }}>
        My Cool Project
      </span>
    </>
  )
}
```

### Project Link

Show a button that links to your project’s homepage on the navbar. By default,
it links to Nextra’s GitHub repository.

<Table>

|              |                               |                                     |
| ------------ | ----------------------------- | ----------------------------------- |
| project.link | `string`                      | URL of the project homepage         |
| project.icon | `React.ReactNode \| React.FC` | Icon or element of the project link |

</Table>

You can configure `project.link` and `project.icon` to customize the project
link, for example make it link to your GitLab repository:

import projectLinkImage from 'public/assets/docs/project-link.png'

<Screenshot src={projectLinkImage} alt="Project link" full />

```jsx filename="theme.config.jsx"
export default {
  project: {
    link: 'https://gitlab.com/inkscape/inkscape',
    icon: (
      <svg width="24" height="24" fill="currentColor" viewBox="0 0 256 256">
        <path d="m231.9 169.8l-94.8 65.6a15.7 15.7 0 0 1-18.2 0l-94.8-65.6a16.1 16.1 0 0 1-6.4-17.3L45 50a12 12 0 0 1 22.9-1.1L88.5 104h79l20.6-55.1A12 12 0 0 1 211 50l27.3 102.5a16.1 16.1 0 0 1-6.4 17.3Z" />
      </svg>
    )
  }
}
```

If `icon` is missing, it will be a
[GitHub icon](https://primer.style/octicons/mark-github-16) by default.

### Chat Link

Show a button that links to your project’s forum or other social media on the
navbar.

<Table>

|           |                               |                                  |
| --------- | ----------------------------- | -------------------------------- |
| chat.link | `string`                      | URL of the chat link             |
| chat.icon | `React.ReactNode \| React.FC` | Icon or element of the chat link |

</Table>

You can configure `chat.link` and `chat.icon` to customize the chat link, for
example make it link to your Twitter account:

```jsx filename="theme.config.jsx"
export default {
  chat: {
    link: 'https://twitter.com/shuding_',
    icon: (
      <svg width="24" height="24" viewBox="0 0 248 204">
        <path
          fill="currentColor"
          d="M221.95 51.29c.15 2.17.15 4.34.15 6.53 0 66.73-50.8 143.69-143.69 143.69v-.04c-27.44.04-54.31-7.82-77.41-22.64 3.99.48 8 .72 12.02.73 22.74.02 44.83-7.61 62.72-21.66-21.61-.41-40.56-14.5-47.18-35.07a50.338 50.338 0 0 0 22.8-.87C27.8 117.2 10.85 96.5 10.85 72.46v-.64a50.18 50.18 0 0 0 22.92 6.32C11.58 63.31 4.74 33.79 18.14 10.71a143.333 143.333 0 0 0 104.08 52.76 50.532 50.532 0 0 1 14.61-48.25c20.34-19.12 52.33-18.14 71.45 2.19 11.31-2.23 22.15-6.38 32.07-12.26a50.69 50.69 0 0 1-22.2 27.93c10.01-1.18 19.79-3.86 29-7.95a102.594 102.594 0 0 1-25.2 26.16z"
        />
      </svg>
    )
  }
}
```

If `icon` is missing, it will be a Discord icon by default.

### Menu and Custom Links

Check out [Page Configuration](/docs/docs-theme/page-configuration#navbar-items)
to learn how to add custom menus or links to the navbar.

### Search

<Table>

|                    |                                                                                  |                  |
| ------------------ | -------------------------------------------------------------------------------- | ---------------- |
| search.component   | `React.ReactNode \|`<br/>`React.FC<{ className?: string; directories: Item[] }>` |                  |
| search.emptyResult | `React.ReactNode \| React.FC`                                                    | Not found text   |
| search.loading     | `React.ReactNode \| React.FC`                                                    | Loading text     |
| search.error       | `string \| (() => string)`                                                       | Error text       |
| search.placeholder | `string \| (() => string)`                                                       | Placeholder text |

</Table>

### Banner

Show a banner on the top of the website. It can be used to show a warning or a
notice.

<Table>

|                      |                               |                                                         |
| -------------------- | ----------------------------- | ------------------------------------------------------- |
| `banner.dismissible` | `boolean`                     | Closable banner or not                                  |
| `banner.key`         | `string`                      | Storage key to keep the banner state (dismissed or not) |
| `banner.content`     | `React.ReactNode \| React.FC` | Content of the banner                                   |

</Table>

#### Banner key

A banner can be dismissed. By default `banner.key` will be `"nextra-banner"` and
it’s used by
[localStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage)
to keep the banner state (dismissed or not) on the client.

If you have updated your banner text, you should change the key to make sure the
banner is shown again. The best practice is to always use a descriptive key for
the current text, for example:

import bannerImage from 'public/assets/docs/banner.png'

<Screenshot src={bannerImage} alt="Banner" />

```jsx filename="theme.config.jsx"
export default {
  banner: {
    key: '2.0-release',
    content: (
      <a href="https://nextra.site" target="_blank">
        🎉 Nextra 2.0 is released. Read more →
      </a>
    )
  }
}
```

### Customize the Navbar

Customize the entire navbar component.

<Table>

|                     |                                            |                                       |
| ------------------- | ------------------------------------------ | ------------------------------------- |
| navbar.component    | `React.ReactNode \| React.FC<NavBarProps>` | Navbar component                      |
| navbar.extraContent | `React.ReactNode \| React.FC`              | Display extra content after last icon |

</Table>

## Sidebar

<Table>

|                                  |           |                                                                                                 |
| -------------------------------- | --------- | ----------------------------------------------------------------------------------------------- |
| sidebar.defaultMenuCollapseLevel | `number`  | Specifies the folder level at which the menu on the left is collapsed by default. Defaults to 2 |
| sidebar.autoCollapse             | `boolean` | If true, automatically collapse inactive folders above `defaultMenuCollapseLevel`               |
| sidebar.toggleButton             | `boolean` | Hide/show sidebar toggle button. Defaults to `false`                                            |

</Table>

### Menu Collapse Level

By default, the sidebar menu is collapsed at level `2`. You can change it by
setting `sidebar.defaultMenuCollapseLevel` to a different number. For example,
when set to `1`, every folder will be collapsed by default and when set to
`Infinity`, all nested folders will be expanded by default.

If `sidebar.autoCollapse` is set to `true`, then all folders that do not contain
an active/focused route will automatically collapse up to the level set by
`sidebar.defaultMenuCollapseLevel`. e.g. if `defaultMenuCollapseLevel` is `2`,
then top-level folders will not auto-collapse.

### Customize Sidebar Content

Together with the [Separators](/docs/docs-theme/page-configuration#separators)
item, you can customize how the sidebar content is rendered by using JSX
elements:

```jsx filename="_meta.jsx" {5-10}
export default {
  index: 'Intro',
  '--': {
    type: 'separator',
    title: (
      <div className="flex items-center gap-2">
        <MyLogo />
        {children}
      </div>
    )
  },
  frameworks: 'JS Frameworks & Libs',
  about: 'About'
}
```

<Screenshot src={sidebarTitleComponentImage} alt="Customized Sidebar" />

### Customize Sidebar with Frontmatter

In addition, you can customize the sidebar title using the `sidebarTitle`
property in your front matter:

```mdx filename="pages/getting-started.mdx"
---
sidebarTitle: Getting Started 🚀
---
```

The priority of the sidebar title is as follows:

1. `title` property from `_meta.js` file
1. Front matter `sidebarTitle`
1. Front matter `title`
1. Filename of the page formatted with [Title](https://title.sh)

## Content

### MDX Components

Provide custom [MDX components](https://mdxjs.com/table-of-components/) to
render the content. For example, you can use a custom `pre` component to render
code blocks.

<Table>

|            |                            |                       |
| ---------- | -------------------------- | --------------------- |
| components | `Record<string, React.FC>` | Custom MDX components |

</Table>

### Writing Direction

The default writing direction of the website.

<Table>

|           |                  |                           |
| --------- | ---------------- | ------------------------- |
| direction | `"ltr" \| "rtl"` | Default writing direction |

</Table>

### Main Content

Render top and/or bottom content of main area of the page. It can be used to
render a comment section, a newsletter form, or any other type of content.

<Table>

|      |                                           |                           |
| ---- | ----------------------------------------- | ------------------------- |
| main | `React.FC<{ children: React.ReactNode }>` | Component of main content |

</Table>

## TOC Sidebar

### Table of Contents

Show a table of contents on the right side of the page. It’s useful for
navigating between headings.

<Table>

|                  |                                         |                                                          |
| ---------------- | --------------------------------------- | -------------------------------------------------------- |
| toc.component    | `React.ReactNode \| React.FC<TOCProps>` | Custom renderer of the TOC                               |
| toc.extraContent | `React.ReactNode \| React.FC`           | Display extra content below the TOC content              |
| toc.float        | `boolean`                               | Float the TOC next to the content                        |
| toc.title        | `React.ReactNode \| React.FC`           | Title of the TOC sidebar. By default it’s “On This Page” |
| toc.backToTop    | `React.ReactNode \| React.FC`           | Text of `Scroll to top` button                           |

</Table>

#### Floating TOC

`toc.float` is enabled by default. When enabled, the TOC will be displayed on
the right side of the page and it will be sticky when scrolling. If it’s
disabled, the TOC will be displayed directly on the page sidebar.

### Edit Link

Show an “Edit this page” link on the page that points to the file URL on GitHub
(or other places).

<Table>

|                    |                                                                                          |                                |
| ------------------ | ---------------------------------------------------------------------------------------- | ------------------------------ |
| editLink.content   | `React.ReactNode \| React.FC`                                                            | Content of the edit link       |
| editLink.component | `React.FC<{ children: React.ReactNode; className?: string; filePath?: string }> \| null` | Customized edit link component |

</Table>

<Callout type="info">
  To disable it, you can set `editLink.component` to `null`.
</Callout>

### Feedback Link

The built-in feedback link provides a way for users to submit feedback about the
documentation. By default, it’s a link that points to the issue creation form of
the docs repository, with the current website title prefilled:
[example](https://github.com/shuding/nextra/issues/new?title=Feedback%20for%20%E2%80%9CTheme%20Configuration%E2%80%9D&labels=feedback).

<Table>

|                  |                               |                                                                                           |
| ---------------- | ----------------------------- | ----------------------------------------------------------------------------------------- |
| feedback.content | `React.ReactNode \| React.FC` | Content of the feedback button                                                            |
| feedback.labels  | `string`                      | Labels that can be added to the new created GitHub issue                                  |
| feedback.useLink | `() => string`                | Custom link, by default, will open an issue in the repository set in `docsRepositoryBase` |

</Table>

<Callout type="info">
  To disable it, you can set `feedback.content` to `null`.
</Callout>

## End of Page

### Navigation

Show previous and next page links on the bottom of the content. It’s useful for
navigating between pages.

<Table>

|                 |                     |                                          |
| --------------- | ------------------- | ---------------------------------------- |
| navigation      | `boolean \| object` | Enable or disable navigation link        |
| navigation.prev | `boolean`           | Enable or disable the previous page link |
| navigation.next | `boolean`           | Enable or disable the next page link     |

</Table>

import navigationImage from 'public/assets/docs/navigation.png'

<Screenshot src={navigationImage} alt="Navigation" full />

```jsx filename="theme.config.jsx"
export default {
  navigation: {
    prev: true,
    next: true
  }
}
```

The above is also equivalent to `navigation: true`.

### Last Updated Date

Show the last updated date of each page. It’s useful for showing the freshness
of the content.

<Table>

|              |                                                    |                                           |
| ------------ | -------------------------------------------------- | ----------------------------------------- |
| gitTimestamp | `React.ReactNode \| React.FC<{ timestamp: Date }>` | Component to render the last updated info |

</Table>

## Footer

The footer area of the website. You can either specify some content for the
default footer, or fully customize it with a custom component.

<Table>

|                  |                                                  |                                 |
| ---------------- | ------------------------------------------------ | ------------------------------- |
| footer.content   | `React.ReactNode \| React.FC`                    | Content of the footer component |
| footer.component | `React.ReactNode \| React.FC<{ menu: boolean }>` | Customized footer component     |

</Table>

### Copyright Information

You can add some simple content, such as copyright information to the default
footer:

```jsx filename="theme.config.jsx"
export default {
  footer: {
    content: (
      <span>
        MIT {new Date().getFullYear()} ©{' '}
        <a href="https://nextra.site" target="_blank">
          Nextra
        </a>
        .
      </span>
    )
  }
}
```

## Theme Switch

<Table>

|                        |                                                                             |                                      |
| ---------------------- | --------------------------------------------------------------------------- | ------------------------------------ |
| themeSwitch.component  | `React.ReactNode \|`<br/>`React.FC<{ lite?: boolean, className?: string }>` | Component to render the theme switch |
| themeSwitch.useOptions | `ThemeOptions \| () => ThemeOptions`                                        | Options in the theme switch          |

</Table>

### Options

You are able to customize the option names for localization or other purposes:

```jsx filename="theme.config.jsx"
export default {
  themeSwitch: {
    useOptions() {
      return {
        light: 'Light',
        dark: 'Dark',
        system: 'System'
      }
    }
  }
}
```

## Not Found Page

Options to configure report of broken link on not found page.

<Table>

|                  |                   |                                                |
| ---------------- | ----------------- | ---------------------------------------------- |
| notFound.content | `ReactNode \| FC` | Default: `Submit an issue about broken link →` |
| notFound.labels  | `string`          | Default: `bug`                                 |

</Table>

## I18n

Options to configure the language dropdown for
[the i18n docs website](/docs/guide/i18n).

<Table>

|                        |                  |                                                        |
| ---------------------- | ---------------- | ------------------------------------------------------ |
| i18n[number].locale    | `string`         | Locale from `i18n.locales` field in `next.config` file |
| i18n[number].name      | `string`         | Locale name in dropdown                                |
| i18n[number].direction | `'ltr' \| 'rtl'` | Locale writing direction. Default: `ltr`               |

</Table>

## Favicon Glyph

This isn’t supported by all browsers, but it’s a nice way to customize the
favicon of the website simply by using an emoji or character.

<Table>

|              |          |                                 |
| ------------ | -------- | ------------------------------- |
| faviconGlyph | `string` | The glyph to use as the favicon |

</Table>
