Nextra快速起步
体验
警告
目前我暂时放弃了Nextra,因为我感觉文档和实际代码有脱节和冲突,让我非常困扰。
我用了两天时间来学习使用Nextra,可能因为我缺乏前端开发经验,对于 npm/pnpm
不熟悉,在尝试 Nextra i18n 时遇到不少挫折,导致我目前暂时放弃:
似乎得从 GitHub: nextra 完整clone出项目,并使用
pnpm
来管理和启动,这样可以少走弯路我是最初从 nextra introduction 文档开始,文档实际上和 GitHub: nextra 是脱节的,导致我踩了坑折腾了很久
因为我的后端维护经验影响,我会去折腾从最基础的部署开始,例如我尝试手册指导的安装方法,但是由于手册没有提供模版指导,我就摸索从模版复制内容过来运行。但是JavaScript或者说 React 生态其实很复杂(叠床架屋),手册又写得简略(开源文档似乎都习惯以开发者而不是使用者角度撰写),导致我调衡了一天才完成初步运行
在 Nextra i18n 又踩了坑,原来nextjs的i18n是一种动态路径路由,但是我之前找到的文档 Build a documentation site with Next.js using Nextra 使用的模版实际上是几年前尚未实现i18n。不得已推倒重来,在 GitHub: nextra 的
examples
中找出官方i18n
模版awr-site
来部署又遇到
npm/pnpm
包管理器的迷宫了,参考文档的步骤看来是有一定执行条件的,必须按照 GitHub: nextra 完整clone出项目来搞,我这种缝合胶水的方式困难重重,直接把我劝退了( Node.js 的包管理世界真是非常蛋疼,各种依赖冲突必须按照完美的排列完成,稍有改动可能就轰然倒塌)
不太顺利,我整理 Next.js vs Remix ,准备先退回到 React 学习,等后续再有机会重新开始(nextjs依然是最主流的WEB框架,可能不得不学习使用)
简介
Nextra是基于 Next.js 的框架,用于构建内容密集型的网站,Nextra具备了 Next.js 所有功能,并提供了易于使用的Markdown撰写功能。
Nextra提供了两种不同的用途theme:
-
顶部有一个导航栏
一个搜索框
一个页面侧边栏
一个内容列表(TOC)
一系列内建组件
备注
我的目标是构建自己的 docs.cloud-atlas.dev 不同的技术手册,所以会以 Docs Theme
为起点构建
安装
# 创建项目目录,并在项目目录中安装 Next.js, React, Nextra, and Nextra Docs Theme
# 也可以采用github中已经初始化的仓库,例如 git clone [email protected]:huataihuang/docs.cloud-atlas.io.git
mkdir docs.cloud-atlas.dev
cd docs.cloud-atlas.dev
npm i next react react-dom nextra nextra-theme-docs
安装输出信息:
npm warn ERESOLVE overriding peer dependency
added 456 packages in 20m
191 packages are looking for funding
run `npm fund` for details
npm notice
npm notice New major version of npm available! 10.9.2 -> 11.4.1
npm notice Changelog: https://github.com/npm/cli/releases/tag/v11.4.1
npm notice To update run: npm install -g [email protected]
npm notice
可以根据上述提示升级 npm
版本(可选): npm install -g npm@11.4.1
在上述安装步骤完成后,在项目目录下有如下文件:
574M node_modules
4.0K package.json
240K package-lock.json
完成安装之后,在项目目录下会有 package.json
生成,该文件用于指导安装对应依赖以及启动运行脚本:
package.json
{
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start"
},
"dependencies": {
"next": "^15.3.3",
"nextra": "^4.2.17",
"nextra-theme-docs": "^4.2.17",
"react": "^19.1.0",
"react-dom": "^19.1.0"
}
}
起步
运行:
dev
模式npm run dev
模版(归档)
备注
这一段所使用的模版不支持 Nextra i18n ,我因为需要撰写多语言文档,所以我改为下一段记录的 模版
步骤
这里有报错,显示还没有 pages
和 app
目录:
pages
和 app
目录的报错
> dev
> next
▲ Next.js 15.3.3
- Local: http://localhost:3000
- Network: http://172.17.0.2:3000
✓ Starting...
[Error: > Couldn't find any `pages` or `app` directory. Please create one under the project root]
这个问题看起来是缺少基本内容目录导致无法运行,不过,不用急,继续按照 Nextra Docs Theme 指南进行配置和初始化
在项目根目录下创建
next.config.mjs
,这个配置文件可以让Nextra处理 Next.js 项目中Markdown文件
next.config.mjs
import nextra from 'nextra'
// Set up Nextra with its configuration
const withNextra = nextra({
// ... Add Nextra-specific options here
})
// Export the final Next.js config with Nextra included
export default withNextra({
// ... Add regular Next.js options here
})
添加
mdx-components
文件:设置搜索
创建根目录的布局:的
现在需要在 app
目录下创建一个根布局,也就是创建 app/layout.jsx
文件:
app/layout.jsx
import { Footer, Layout, Navbar } from 'nextra-theme-docs'
import { Banner, Head } from 'nextra/components'
import { getPageMap } from 'nextra/page-map'
import 'nextra-theme-docs/style.css'
export const metadata = {
// Define your metadata here
// For more information on metadata API, see: https://nextjs.org/docs/app/building-your-application/optimizing/metadata
}
const banner = <Banner storageKey="some-key">Nextra 4.0 is released 🎉</Banner>
const navbar = (
<Navbar
logo={<b>Nextra</b>}
// ... Your additional navbar options
/>
)
const footer = <Footer>MIT {new Date().getFullYear()} © Nextra.</Footer>
export default async function RootLayout({ children }) {
return (
<html
// Not required, but good for SEO
lang="en"
// Required to be set
dir="ltr"
// Suggested by `next-themes` package https://github.com/pacocoursey/next-themes#with-app
suppressHydrationWarning
>
<Head
// ... Your additional head options
>
{/* Your additional tags should be passed as `children` of `<Head>` element */}
</Head>
<body>
<Layout
banner={banner}
navbar={navbar}
pageMap={await getPageMap()}
docsRepositoryBase="https://github.com/shuding/nextra/tree/main/docs"
footer={footer}
// ... Your additional layout options
>
{children}
</Layout>
</body>
</html>
)
}
渲染
MDX
文件: 也就是使用基于文件的路由
(file-based routing)来渲染MDX文件,有两种方式:通过
page
文中件通过
content
目录
按照 nextra Documentataion: File Conventions > content 介绍,现在的文件转换是采用 content
目录,只需要简单将 pages
目录重命名为 content
就可以
我尝试将 GitHub: shuding/nextra-docs-template 项目中初始页面复制过来修改:
nextra-docs-template
cp -R ../nextra-docs-template/pages ./content
# nextra-docs-template 项目的页面使用了 components 目录下的
cp -R ../nextra-docs-template/components ./
当然,如果更为简单,就只需要 content/index.mdx
一个文件,简单案例内容可以如下:
index.mdx
# Welcome to Nextra
Hello, world!
添加
[[...mdxPath]]/page.jsx
文件:
[[...mdxPath]]/page.jsx
import { generateStaticParamsFor, importPage } from 'nextra/pages'
import { useMDXComponents as getMDXComponents } from '../../mdx-components'
export const generateStaticParams = generateStaticParamsFor('mdxPath')
export async function generateMetadata(props) {
const params = await props.params
const { metadata } = await importPage(params.mdxPath)
return metadata
}
const Wrapper = getMDXComponents().wrapper
export default async function Page(props) {
const params = await props.params
const result = await importPage(params.mdxPath)
const { default: MDXContent, toc, metadata } = result
return (
<Wrapper toc={toc} metadata={metadata}>
<MDXContent {...props} params={params} />
</Wrapper>
)
}
这里我修改了第2行,因为我发现项目根目录是 ../../
,在这个根目录下有一个 mdx-components.js
另外,我还修改了 components/counter.tsx
添加了一行 use client'
,原因是:
TypeError: useState only works in Client Components. Add the "use client" directive at the top of the file to use it. Read more: https://nextjs.org/docs/messages/react-client-hook-in-server-component
模版
备注
现在我使用这段记录的步骤,使用nextra官方发布的 examples/swr-site
模版,以支持多国语言文档撰写
将 nextra/examples/swr-site/ 内容同步到这个目录下(忽略已经存在的文件不覆盖):
cd cloud-atlas.dev_arch
# 使用rsync同步
rsync -avz <nextra_dir>/examples/swr-site/ .
安装(使用pnpm)
pnpm
安装pnpm i
报错:
pnpm
安装报错 ERR_PNPM_WORKSPACE_PKG_NOT_FOUND In : "nextra@workspace:*" is in the dependencies but no package named "nextra" is present in the workspace
This error happened while installing a direct dependency of /Users/admin/docs/github/huataihuang/cloud-atlas.dev_arch
Packages found in the workspace:
原来 pnpm > introduction > Installation 在Workstpace中必须有一个 pnpm-workspace.yaml
来配置工作区
我参考 next.js learn: Getting Started 的方法来构建目录
git clone
cd cloud-atlas.dev_arch
# 先本地安装packages
npm i next react react-dom nextra nextra-theme-docs
# 从模版下载初始项目录,也就是从 swr-site 案例复制到本地的 arch 目录形成初始的开发项目,后续修改arch目录下内容进行定制
npx create-next-app arch --example "https://github.com/shuding/nextra/tree/main/examples/swr-site" --use-pnpm
# 失败,问题没有解决,看来我还需要学习
导航栏
nextra Documentataion: Built-In Components > Navbar 介绍了如何在导航栏设置内容,其中有一些是默认链接,例如 projectLink
/ chatLink
。
还可以将一些菜单和定制链接添加到导航栏,需要参考 Page Configuration >> navbar-items
favicon.ico
参考 next.js favicon,icon, and apple-icon
在Next.js中为应用设置icon的图片类型可以是 .ico
/ .jpg
/ .png
,文件存储在 /app
目录中。需要注意其中
favicon
图片必须位于app/
顶层目录,且只支持.ico
文件类型应用
icon
则可以是多种类型.ico, .jpg, .jpeg, .png, .svg
apple-icon
则支持.jpg, .jpeg, .png
除了
favicon
必须位于app/
外,另外两种图片类型可以位于app/**/*