在 Next.js 中使用带有注释的 PrismJS 以突出显示来自 markdown 的代码
Use PrismJS in Next.js with remark to hightlight code from markdown
我想在我的 Next.js 博客中包含 PrismJS 以突出显示 .md 文件中的代码。降价在 /lib/posts.js 中使用 remark
和 remark-html
进行处理,并作为 HTML 传递给 react-markdown
// /lib/posts.js
export async function getPostData(id) {
const fullPath = path.join(postsDirectory, `${id}.md`);
const fileContents = fs.readFileSync(fullPath, "utf8");
const matterResult = matter(fileContents);
const processedContent = await remark()
.use(html)
.process(matterResult.content);
const contentHtml = processedContent.toString();
return {
id,
contentHtml,
...matterResult.data,
};
}
contentHtml 是在 [id].js 中获取的,我在其中使用 ReactMarkdown 来呈现它。在这里我导入 Prism 使用 CodeBlock 功能来突出显示。我在我的 _app.js
中导入 prism.css
在我的 global.css
旁边
// /pages/_app.js
import Container from "../components/Container";
import "../styles/global.css";
import "../styles/prism.css";
export default ({ Component, pageProps }) => (
<Container>
<Component {...pageProps} />
</Container>
);
// /pages/posts/[id].js
import { getAllPostIds, getPostData } from "../../lib/posts";
import ReactMarkdown from "react-markdown/with-html";
import Prism from "prismjs";
const CodeBlock = (language, values) => {
return <Prism language={language}>{values}</Prism>;
};
export default function Post({ postData }) {
return (
<ReactMarkdown
escapeHtml={false} // Dangerous if content is user-generated
source={postData.contentHtml}
renderers={{ code: CodeBlock }}
/>
);
}
export async function getStaticPaths() {
const paths = getAllPostIds();
return {
paths,
fallback: false,
};
}
export async function getStaticProps({ params }) {
const postData = await getPostData(params.id);
return {
props: {
postData,
},
};
}
当我手动输入URL并按return时它正在工作。如 https://nextjs-blog-ivory-nine.vercel.app/posts/first-next-js-blog-devdiary
但是当我从主页 - https://nextjs-blog-ivory-nine.vercel.app - 导航到第一个 post 时,代码不会被突出显示。
你有什么想法吗?
提前致谢!
我刚刚创建了一个可能有用的示例。它使用:
假设您可以通过备注使用 markdown,但没有 Prism。然后只需几个步骤即可添加棱镜:
yarn add remark-prism
然后在静态渲染时调用解析器
import remark from 'remark'
import html from 'remark-html'
import prism from 'remark-prism';
// ...
const parser = remark().use(html).use(prism)
将 css 添加到 html 头部。这项工作只是 css 由用户浏览器完成的。我使用这个 link : https://cdnjs.cloudflare.com/ajax/libs/prism-themes/1.9.0/prism-coy-without-shadows.min.css
但还有其他选择。
import Head from 'next/head'
const Article = ({post}: ArticleProps) => {
return (
<div>
<Head>
<link href="https://cdnjs.cloudflare.com/ajax/libs/prism-themes/1.9.0/prism-coy-without-shadows.min.css" rel="stylesheet" />
</Head>
<article className={article.blogpost}>
{/* ... */}
</article>
</div>
)
}
export default Article
请注意,添加 .use(prism)
会使 SSR 显着变慢!这是开发模式下的问题,但在 html 导出站点中没有。
我想在我的 Next.js 博客中包含 PrismJS 以突出显示 .md 文件中的代码。降价在 /lib/posts.js 中使用 remark
和 remark-html
进行处理,并作为 HTML 传递给 react-markdown
// /lib/posts.js
export async function getPostData(id) {
const fullPath = path.join(postsDirectory, `${id}.md`);
const fileContents = fs.readFileSync(fullPath, "utf8");
const matterResult = matter(fileContents);
const processedContent = await remark()
.use(html)
.process(matterResult.content);
const contentHtml = processedContent.toString();
return {
id,
contentHtml,
...matterResult.data,
};
}
contentHtml 是在 [id].js 中获取的,我在其中使用 ReactMarkdown 来呈现它。在这里我导入 Prism 使用 CodeBlock 功能来突出显示。我在我的 _app.js
中导入 prism.css
在我的 global.css
// /pages/_app.js
import Container from "../components/Container";
import "../styles/global.css";
import "../styles/prism.css";
export default ({ Component, pageProps }) => (
<Container>
<Component {...pageProps} />
</Container>
);
// /pages/posts/[id].js
import { getAllPostIds, getPostData } from "../../lib/posts";
import ReactMarkdown from "react-markdown/with-html";
import Prism from "prismjs";
const CodeBlock = (language, values) => {
return <Prism language={language}>{values}</Prism>;
};
export default function Post({ postData }) {
return (
<ReactMarkdown
escapeHtml={false} // Dangerous if content is user-generated
source={postData.contentHtml}
renderers={{ code: CodeBlock }}
/>
);
}
export async function getStaticPaths() {
const paths = getAllPostIds();
return {
paths,
fallback: false,
};
}
export async function getStaticProps({ params }) {
const postData = await getPostData(params.id);
return {
props: {
postData,
},
};
}
当我手动输入URL并按return时它正在工作。如 https://nextjs-blog-ivory-nine.vercel.app/posts/first-next-js-blog-devdiary 但是当我从主页 - https://nextjs-blog-ivory-nine.vercel.app - 导航到第一个 post 时,代码不会被突出显示。
你有什么想法吗? 提前致谢!
我刚刚创建了一个可能有用的示例。它使用:
假设您可以通过备注使用 markdown,但没有 Prism。然后只需几个步骤即可添加棱镜:
yarn add remark-prism
然后在静态渲染时调用解析器
import remark from 'remark'
import html from 'remark-html'
import prism from 'remark-prism';
// ...
const parser = remark().use(html).use(prism)
将 css 添加到 html 头部。这项工作只是 css 由用户浏览器完成的。我使用这个 link : https://cdnjs.cloudflare.com/ajax/libs/prism-themes/1.9.0/prism-coy-without-shadows.min.css
但还有其他选择。
import Head from 'next/head'
const Article = ({post}: ArticleProps) => {
return (
<div>
<Head>
<link href="https://cdnjs.cloudflare.com/ajax/libs/prism-themes/1.9.0/prism-coy-without-shadows.min.css" rel="stylesheet" />
</Head>
<article className={article.blogpost}>
{/* ... */}
</article>
</div>
)
}
export default Article
请注意,添加 .use(prism)
会使 SSR 显着变慢!这是开发模式下的问题,但在 html 导出站点中没有。