LoginSignup
2
0

Next.js(App router)でContentfulのMarkdownをHTMLで出力する(Remark/Rehype)

Posted at

年の瀬の迫る今日この頃、いかがお過ごしでしょうか。
モロ(@moro_is)です。

トレンドに翻弄されてWordPress->Nuxt(+WordPress REST API)->Gatsby(Contentful)と反復横跳びがごとく無駄に移行し続けてきたブログを、そろそろNext.jsに移行したら今度こそ当面安泰では、と目論むもなかなか時間が取れずすっかり放置してしまっていましたが、さすがにそろそろ着手しないといつまでも経っても中身を更新できません(ガワが良い感じになっていないと中身も触る気になれないタイプ)。

やることが山積みではあるのですが、ここでは少しでも進捗を稼ぐべく、Contentfulの「Text(Markdown)」をNext.js(App Router)でHTML出力するところをやりました。

ContentfulのText(Markdown)とは

Content Model内のフィールドで使用できる「Text」の入力形式のひとつ「Markdown」のこと。

image.png

どちらかというと「Rich text」のほうが主流なのかあまり情報が出てこない印象でした。

Unified(Remark/Rehype)周りのライブラリをインストールする

yarn add unified remark-parse remark-rehype rehype-stringify

全然詳しくないのでほぼ下記の受け売りです。

良い感じに変換するUtilsを作る

uilts/markdown.ts
import { unified } from "unified";
import remarkParse from "remark-parse";
import remarkRehype from "remark-rehype";
import rehypeStringify from "rehype-stringify";

export const markdownToHtml = async (markdown: string): Promise<string> => {
  const result = await unified()
    .use(remarkParse)
    .use(remarkRehype)
    .use(rehypeStringify)
    .process(markdown);

  return String(result.value);
};

下記を参考にさせてもらっています。

目次をはじめカスタマイズの幅はかなり広そうなので追々ちゃんとやる。

app配下の記事ページで読み込む

app/[slug]/page.tsx
import { markdownToHtml } from "@/utils/markdown";

//(中略)

async function PostPage({ params }: PostPageProps) {
  const post = await fetchPost({
    slug: params.slug,
    preview: draftMode().isEnabled,
  });

  if (!post) {
    return notFound();
  }

  const content = post.content ? await markdownToHtml(post.content) : "";

  return (
    <main>
      <h1>{post.title}</h1>
      <div dangerouslySetInnerHTML={{ __html: content }} />
    </main>
  );
}

//(後略)

以上です。

MarkdownをHTMLに変換するところさえできてしまえばもうできたも同然ですね。
年内に何とかしたい気持ちでいっぱいです。

良いお年を!

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0