【问题标题】:Use PrismJS in Next.js with remark to hightlight code from markdown在 Next.js 中使用 PrismJS 和 remark 以突出显示来自 markdown 的代码
【发布时间】:2020-07-01 21:49:40
【问题描述】:

我想在我的 Next.js 博客中包含 PrismJS 以突出显示 .md 文件中的代码。 markdown 在 /lib/posts.js 中使用 remarkremark-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 旁边的global.css 旁边导入prism.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 并按回车时它正在工作。如https://nextjs-blog-ivory-nine.vercel.app/posts/first-next-js-blog-devdiary 但是当我从主页 - https://nextjs-blog-ivory-nine.vercel.app - 导航到第一篇文章时,代码不会被高亮显示。

你有什么想法吗? 提前致谢!

【问题讨论】:

标签: markdown next.js prismjs


【解决方案1】:

我刚刚创建了一个可能会有所帮助的示例。它使用:

https://github.com/leerob/nextjs-prism-markdown

【讨论】:

  • 我有同样的东西,但不适用于 python highlight
【解决方案2】:

假设您可以通过 remark 使用 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。我使用此链接: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 导出的站点中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-05
    • 1970-01-01
    • 2013-12-16
    相关资源
    最近更新 更多