Nextra 3.0 发布。 阅读更多
文档自定义主题

自定义主题

Nextra 中的主题就像一个布局,它将被渲染为所有页面的包装器。本文档将引导您完成创建自定义主题的过程。

可选地,您可以部署一个示例并在遵循以下步骤的基础上进一步构建它

创建自定义主题

配置 Nextra 以使用主题

首先,您需要告诉 Nextra 使用您的自定义主题文件而不是官方主题文件。在您的 Next.js 配置中,您可以将主题文件的路径传递给 Nextra 插件

next.config.mjs
import nextra from 'nextra'
 
const withNextra = nextra({
  theme: './theme.tsx'
})
 
// If you have other Next.js configurations, you can pass them as the parameter:
// export default withNextra({ /* other next.js config */ })

创建基本主题

您现在可以开始处理您的主题了!在您的根目录中,创建相应的 theme.tsx 文件,其中包含基本内容

theme.tsx
import type { NextraThemeLayoutProps } from 'nextra'
 
export default function Layout({ children }: NextraThemeLayoutProps) {
  return (
    <div>
      <h1>My Theme</h1>
      <div style={{ border: '1px solid' }}>{children}</div>
    </div>
  )
}

它接受一个 children 属性,该属性是当前页面的 MDX 内容,并在内容周围包装了一些其他元素。创建主题后,您可以简单地添加一个 MDX 文件作为 pages/index.mdx 并查看结果

Custom theme

在您的主题布局中,您可以使用 CSS 导入或其他方式对其进行样式设置。Next.js 钩子,例如 useRouterHead 也可用。

渲染活动页面的元数据

除了 children 之外,还会将一些其他有用的属性传递给主题布局。使用 pageOpts 属性,主题可以访问页面的元信息。

例如,让我们实现以下功能

  • <title> 中渲染页面标题
  • 通过 MDX <Wrapper> 组件显示简单的目录
  • 通过前置 matter 添加 og:image 的元标记
theme.tsx
import Head from 'next/head'
import type { NextraThemeLayoutProps } from 'nextra'
import { MDXProvider } from 'nextra/mdx'
 
export default function Layout({ children, pageOpts }: NextraThemeLayoutProps) {
  const { title, frontMatter } = pageOpts
 
  return (
    <>
      <Head>
        <title>{title}</title>
        <meta name="og:image" content={frontMatter.image} />
      </Head>
      <MDXProvider components={{ wrapper: MyWrapper }}>{children}</MDXProvider>
    </>
  )
}
 
function MyWrapper({ children, toc }) {
  return (
    <>
      <h1>My Theme</h1>
      Table of Contents:
      <ul>
        {toc.map(heading => (
          <li key={heading.value}>{heading.value}</li>
        ))}
      </ul>
      <div style={{ border: '1px solid' }}>{children}</div>
    </>
  )
}

使用整个站点的页面映射

现在,如果您想渲染一些东西,例如侧边栏或导航栏,这些内容不仅依赖于当前页面,还依赖于其他页面,则可以使用 pageMap 值。

例如,我们可以使用顶层的所有页面渲染一个简单的导航列表

theme.tsx
import Link from 'next/link'
import type { NextraThemeLayoutProps } from 'nextra'
 
export default function Layout({ children, pageOpts }: NextraThemeLayoutProps) {
  const { pageMap } = pageOpts
 
  return (
    <div>
      <h1>My Theme</h1>
      {pageMap.map(item => {
        if ('route' in item && !('children' in item)) {
          return (
            <Link key={item.name} href={item.route}>
              {item.route}
            </Link>
          )
        }
      })}
      <div style={{ border: '1px solid' }}>{children}</div>
    </div>
  )
}

还有其他项目类型,例如 Folder(用于目录)和 Meta(用于 _meta.js 文件)。所有项目都已键入,因此您可以轻松了解属性。

高级用法

⚠️

高级用法的文档正在建设中。