投稿 2021.10.15
Next.jsでは「public」ファルダ配下から画像を参照するようになっています。
しかし、マークダウンでブログを書いている都合上、mdファイルと同じ場所に画像を配置したいと考えました。
以下のようなディレクトリ構成で画像を置いておけるようにします。
my-blog-project
┗ _posts
┗ my-first-post
┗ index.md
┗ 画像01.png
┗ my-seond-post
┗ index.md
┗ 画像02.png
┗ my-third-post
┗ index.md
┗ 画像01.png
build時に静的ファイルを別のディレクトリへコピーできるプラグインをインストールします。
❯ npm install -S copy-webpack-plugin write-file-webpack-plugin
「jpg」「png」ファイルを「public/assets/images/posts」にコピーできるように設定ファイルを変更します。
+const { resolve } = require('path')
const withBundleAnalyzer = require('@next/bundle-analyzer')({
enabled: process.env.ANALYZE === 'true',
});
-
+const CopyFilePlugin = require('copy-webpack-plugin')
+const WriteFilePlugin = require('write-file-webpack-plugin')
+module.exports = {
+ webpack(config) {
+ config.plugins.push(
+ new CopyFilePlugin({
+ patterns: [
+ {
+ context: '_posts',
+ from: '**/*.{jpg,png}',
+ to: resolve(__dirname, 'public/assets/images/posts'),
+ },
+ ],
+ }),
+ new WriteFilePlugin()
+ )
+ return config
+ },
+}
mdファイル内の「@@imageUrl@@」の文字列をパスに置換する処理を記述します。
-export async function markdownToHtml(content: string) {
+export async function markdownToHtml(content: string, slug?: string) {
const markdownIt = new MarkdownIt(
{
langPrefix: 'language-',
preset: 'default',
linkify: true,
breaks: true,
html: true,
typegraphy: true,
}
).use(mdContainer, 'afilink', containerAfilinkOptions)
.use(mdContainer, 'question', containerQuestionOptions)
.use(mdContainer, 'attention', containerAttentionOptions);
- return markdownIt.render(content).replace(//assets/images/posts/20211015-nextjs-image-dir/g, process.env.baseUrl || '');
+ return markdownIt.render(content).replace(/@@imageUrl@@/g, `/assets/images/posts/${slug}`);
}
「markdownToHtml」の引数を増やしているので、呼び元も忘れずに更新します。
- const content = await markdownToHtml(post.content || '');
+ const content = await markdownToHtml(post.content || '', params!.slug);
mdファイル内では以下のように書くことができます。
![](@@imageUrl@@/01.png)