渲染 Markdown

要渲染 markdown 內容,我們將使用 remark 函式庫。首先,安裝它:

npm install remark remark-html

接著,開啟 lib/posts.js 並在檔案頂部新增以下引入:

import { remark } from 'remark';
import html from 'remark-html';

並更新同檔案中的 getPostData() 函式以使用 remark

export async function getPostData(id) {
  const fullPath = path.join(postsDirectory, `${id}.md`);
  const fileContents = fs.readFileSync(fullPath, 'utf8');
 
  // 使用 gray-matter 解析文章元數據區塊
  const matterResult = matter(fileContents);
 
  // 使用 remark 將 markdown 轉換為 HTML 字串
  const processedContent = await remark()
    .use(html)
    .process(matterResult.content);
  const contentHtml = processedContent.toString();
 
  // 將資料與 id 和 contentHtml 結合
  return {
    id,
    contentHtml,
    ...matterResult.data,
  };
}

重要:我們在 getPostData 中新增了 async 關鍵字,因為需要使用 await 來處理 remarkasync/await 讓你能夠非同步獲取資料。

這表示我們需要更新 pages/posts/[id].js 中的 getStaticProps,在呼叫 getPostData 時使用 await

export async function getStaticProps({ params }) {
  // 像這樣新增 "await" 關鍵字:
  const postData = await getPostData(params.id);
 
  return {
    props: {
      postData,
    },
  };
}

最後,更新 pages/posts/[id].js 中的 Post 元件,使用 dangerouslySetInnerHTML 來渲染 contentHtml

export default function Post({ postData }) {
  return (
    <Layout>
      {postData.title}
      <br />
      {postData.id}
      <br />
      {postData.date}
      <br />
      <div dangerouslySetInnerHTML={{ __html: postData.contentHtml }} />
    </Layout>
  );
}

嘗試再次造訪這些頁面:

你現在應該能看到部落格內容:

如何使用動態路由靜態生成頁面

我們快完成了!接下來讓我們完善每個頁面。