Markdown BlogをNext.jsで作る
はてなブログに書いてるけど、興味のある技術を試す場としてブログを自分でbuildしようかと思う
Markdownで記事を書くなら、GatsbyJSとかでさくっとできそうだけど、そこはあえて自分が興味あるもので作ってみる
Next.js + MDX + TypeScript でブログを構築していく
Next.js
Installation
$ npm install next react react-dom $ npm install -D @types/node @types/react typescript
Add Index and Blog page
// src/pages/index.tsx import Link from 'next/link'; const Index = () => ( <div> <Link href="/blog"> <a>Blog</a> </Link> </div> ); export default Index;
// src/pages/blog.tsx const Blog = () => ( <div> <p>Welcome to my blog</p> </div> ); export default Blog;
Add npm script
# package.json { ... "scripts": { "dev": "next", "build": "next build", "start": "next start" } }
Start Next.js
$ npm run dev
これでindexページとblogページが表示できるはず
僕はVSCodeを使ってdebugしたいので ↓ inspect用のスクリプトも用意している
# package.json { ... "scripts": { "dev": "next", "dev:inspect": "NODE_OPTIONS='--inspect=0.0.0.0' next", "build": "next build", "start": "next start" } }
# .vscode/launch.json { "version": "0.2.0", "configurations": [ { "type": "node", "request": "launch", "name": "Docker: Next.js", "skipFiles": [ "<node_internals>/**" ], "remoteRoot": "/home/app", "protocol": "inspector", "port": 9229 } ] }
MDX
最初は react-markdown + gray-matter で行こうと思ったけど、
MDX が良さそうだったので採用
MDXはMarkdownをJSXで使えちゃうし、導入も楽ちんだった!
Installation
$ npm install @next/mdx @mdx-js/loader
// next.config.js const withMDX = require("@next/mdx")({ extension: /\.mdx?$/ }); module.exports = withMDX({ pageExtensions: ["ts", "tsx", "mdx"] });
// mdx.d.ts declare module '*.mdx' { // eslint-disable-next-line @typescript-eslint/no-explicit-any let MDXComponent: (props: any) => JSX.Element; export default MDXComponent; }
# tsconfig.json { ... "include": [ "mdx.d.ts", # 追加 "next-env.d.ts", "**/*.ts", "**/*.tsx" ] }
Add Sample post
// src/posts/sample_post.mdx export const meta = { title: 'Sample Post', }; # Sample Post ## Welcome to My Blog
// src/pages/blog.tsx import SamplePost from '../posts/sample_post.mdx'; const Blog = () => ( <div> <SamplePost /> </div> ); export default Blog;
参考
これでmarkdownの記事を表示することができました{^^)