自定义主题
在 Nextra 中,主题类似于布局,将作为所有页面的包装器进行渲染。本文档将指导您创建自定义主题的过程。
您可以选择部署一个示例,并按照以下步骤进一步构建它:
创建自定义主题
配置 Nextra 使用主题
首先,你需要告诉 Nextra 使用你的自定义主题文件,而不是官方的。 在你的 Next.js 配置中,你可以将主题文件的路径传递给 Nextra 插件:
next.config.js
const withNextra = require('nextra')({
theme: './theme.tsx',
})
module.exports = withNextra({
// 其他 Next.js 配置
...
})
创建基本主题
你现在可以开始着手开发你的主题了!在你的根目录下,创建相应的 theme.tsx
文件,内容如下:
theme.tsx
import type { NextraThemeLayoutProps } from 'nextra'
export default function Layout({ children }: NextraThemeLayoutProps) {
return (
<div>
<h1>我的主题</h1>
<div style={{ border: '1px solid' }}>{children}</div>
</div>
)
}
它接受一个 children
属性,这是当前页面的 MDX 内容,并在内容周围包裹一些其他元素。
创建主题后,你可以简单地添加一个 MDX 文件作为 pages/index.mdx
,然后查看结果:
在你的主题布局中,你可以使用 CSS 导入或其他方式进行样式化。
Next.js 提供的钩子,比如 useRouter
、Head
,也是可用的。
渲染活动页面的元数据
除了 children
,一些其他有用的属性也传递给了主题布局。通过 pageOpts
属性,主题可以访问页面的元信息。
例如,让我们实现以下功能:
- 在
<title>
中渲染页面标题 - 显示一个简单的目录
- 通过前置元数据为
og:image
添加一个 meta 标签
theme.tsx
import Head from 'next/head'
import type { NextraThemeLayoutProps } from 'nextra'
export default function Layout({ children, pageOpts }: NextraThemeLayoutProps) {
const { title, frontMatter, headings } = pageOpts
return (
<div>
<Head>
<title>{title}</title>
<meta name="og:image" content={frontMatter.image} />
</Head>
<h1>My Theme</h1>
Table of Contents:
<ul>
{headings.map(heading => (
<li key={heading.value}>{heading.value}</li>
))}
</ul>
<div style={{ border: '1px solid' }}>{children}</div>
</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 (item.kind === 'MdxPage') {
return (
<Link key={item.name} href={item.route}>
{item.route}
</Link>
)
}
return null
})}
<div style={{ border: '1px solid' }}>{children}</div>
</div>
)
}
还有其他类型的项目,比如 Folder
(用于目录)和 Meta
(用于 _meta.json
文件)。
所有项目都有类型,因此您可以轻松了解其属性。
高级用法
⚠️
高级用法的文档正在建设中。