Next.js 製ブログで public 以外の場所に画像を配置する
はじめに
Next.js では、静的ファイルを配信する際は public
配下を参照する仕様となっている。
記事を管理する上ではこれだと不便。Markdown ファイルと同じ階層に画像ファイルを配置したい。
そこで、下記のように Markdown ファイルと同じ階層に画像を配置できるようにした。
_posts
├── hello-world/
│ └── index.md # 記事
│ └── image.png # 記事に埋め込む画像
実現方法
Next.js製マークダウンブログの画像をMDファイルと同じ階層に置く を参照。
※「build 時に静的ファイルを別のディレクトリへコピーできるプラグイン」を利用して、public
配下に画像をコピーする。
手順メモ
build 時に画像を public ディレクトリにコピーするための設定を追加
プラグインをインストールする。
npm install -S copy-webpack-plugin write-file-webpack-plugin
build 時に「jpn, png」ファイルを public
配下の指定のディレクトリ(public/assets/images/posts
)にコピーする設定を追加する。
diff --git a/next.config.js b/next.config.js
index ae88795..04cb118 100644
--- a/next.config.js
+++ b/next.config.js
@@ -1,7 +1,26 @@
/** @type {import('next').NextConfig} */
+const { resolve } = require('path')
+const CopyFilePlugin = require('copy-webpack-plugin')
+const WriteFilePlugin = require('write-file-webpack-plugin')
+
const nextConfig = {
reactStrictMode: true,
swcMinify: true,
+ webpack(config) {
+ config.plugins.push(
+ new CopyFilePlugin({
+ patterns: [
+ {
+ context: '_posts',
+ from: '**/*.{jpg,png}',
+ to: resolve(__dirname, 'public/assets/images/posts'),
+ },
+ ],
+ }),
+ new WriteFilePlugin()
+ )
+ return config
+ },
}
画像の参照先をコピー先のディレクトリに変更する処理を追加
Markdown ファイル内の「@@imageUrl@@
」の文字列をコピー先のディレクトリのパスに置換する処理を記述する。
diff --git a/lib/markdownToHtml.ts b/lib/markdownToHtml.ts
index 1976c7d..6f35c04 100644
--- a/lib/markdownToHtml.ts
+++ b/lib/markdownToHtml.ts
@@ -1,7 +1,8 @@
import { remark } from 'remark'
import html from 'remark-html'
-export default async function markdownToHtml(markdown: string) {
- const result = await remark().use(html).process(markdown)
+export default async function markdownToHtml(markdown: string, slug?: string) {
+ const markdownReplacedImgPath = markdown.replace(/@@imageUrl@@/g, `/assets/images/posts/${slug}`)
+ const result = await remark().use(html).process(markdownReplacedImgPath)
return result.toString()
}
呼び出し元も修正する。
diff --git a/pages/posts/[slug].tsx b/pages/posts/[slug].tsx
index d8d47f8..0bbc784 100644
--- a/pages/posts/[slug].tsx
+++ b/pages/posts/[slug].tsx
@@ -37,7 +37,7 @@ export async function getStaticProps({ params }: Params) {
'tags',
'content',
])
- const content = await markdownToHtml(post.content || '')
+ const content = await markdownToHtml(post.content || '', post.slug)
return {
props: {
post: {
以上👍
Markdown ファイルでの画像パスの指定方法
下記のように記述することで、画像を参照できる。
![](@@imageUrl@@/image.jpg)
おわりに
「画像ファイルを build 時に public 配下にコピーする」という発想はなかったので、こちら のサイトには感謝したい。
今後運用していく中で下記の問題が発生したら、ローカル画像はやめてリモートの画像サーバーを移行するなどの対策を打つ。
- 画像の数が増えていけば、それだけコピーにかかる時間も増えるので、build 時間が増加する(はず)。