Next.js(.tsx)とリッチエディタQuillを使ってWordPressのように画像を何枚もアップロードできる方法を教えて。
Next.js(TypeScript)でQuillを使って、複数の画像をアップロードできるリッチエディタを作成する方法について説明します。Quillは非常に柔軟で拡張可能なエディタなので、画像のアップロードもカスタマイズできます。基本的には以下の手順で進めます。
1.Quillのセットアップ
2.画像アップロードのカスタムハンドラー作成
3.アップロードされた画像をサーバーに保存
4.アップロードされた画像をQuillエディタ内で表示
1. Quillのインストール
まずは必要なパッケージをインストールします。
npm install react-quill
npm install quill
2. QuillエディタをNext.jsで設定
react-quillはReact用のQuillコンポーネントです。これを使ってエディタを表示します。quill自体もインストールしているので、カスタマイズを加えるために使います。
pages/index.tsxに基本的なエディタをセットアップします。
// pages/index.tsx
import { useState, useEffect } from 'react';
import ReactQuill from 'react-quill';
import 'react-quill/dist/quill.snow.css'; // クラシックスタイル
const MyEditor = () => {
const [editorValue, setEditorValue] = useState('');
// Quillエディタの画像アップロード用にカスタムモジュールを作成
const handleImageUpload = (file: File) => {
const formData = new FormData();
formData.append('file', file);
// サーバーへの画像アップロード(APIエンドポイント)
fetch('/api/upload', {
method: 'POST',
body: formData,
})
.then((response) => response.json())
.then((data) => {
// アップロード成功後、Quillに画像URLを挿入
const range = quillRef.current?.getEditor().getSelection();
if (range) {
const imageUrl = data.url; // サーバーから返された画像URL
quillRef.current?.getEditor().insertEmbed(range.index, 'image', imageUrl);
}
})
.catch((error) => {
console.error('画像アップロードに失敗しました', error);
});
};
// カスタムモジュールを作成して画像のアップロード処理を追加
const modules = {
toolbar: [
[{ 'header': '1' }, { 'header': '2' }, { 'font': [] }],
[{ 'list': 'ordered' }, { 'list': 'bullet' }],
['bold', 'italic', 'underline'],
['link', 'image'], // 画像挿入ボタン
],
imageHandler: handleImageUpload, // カスタム画像アップロード
};
return (
<div>
<ReactQuill
value={editorValue}
onChange={setEditorValue}
modules={modules} // モジュールを指定
/>
</div>
);
};
export default MyEditor;
3. 画像アップロードのバックエンド設定
次に、画像をサーバーにアップロードするAPIを作成します。Next.jsではAPIルートを簡単に作成できます。
pages/api/upload.tsに画像アップロード用のAPIを作成します。この例では、画像をローカルに保存しますが、実際にはS3やCloudinaryなどの外部ストレージを利用することが一般的です。
// pages/api/upload.ts
import type { NextApiRequest, NextApiResponse } from 'next';
import multer from 'multer';
import path from 'path';
// Multerの設定(ローカルストレージに保存)
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, './public/uploads'); // public/uploadsディレクトリに保存
},
filename: (req, file, cb) => {
cb(null, Date.now() + path.extname(file.originalname)); // ファイル名をユニークに
}
});
const upload = multer({ storage });
const handler = (req: NextApiRequest, res: NextApiResponse) => {
if (req.method === 'POST') {
// Multerでファイルを処理
upload.single('file')(req, res, (err: any) => {
if (err) {
return res.status(500).json({ error: '画像アップロードに失敗しました' });
}
const file = (req as any).file;
const imageUrl = `/uploads/${file.filename}`; // 公開パスを返す
res.status(200).json({ url: imageUrl });
});
} else {
res.status(405).json({ error: 'Method Not Allowed' });
}
};
export default handler;
このAPIは、POSTリクエストで画像を受け取り、public/uploadsディレクトリに保存します。アップロードした画像のURLを返し、そのURLをQuillエディタに挿入します。
- フォルダの準備
画像の保存先としてpublic/uploadsフォルダを作成してください。
mkdir -p public/uploads
- まとめ
これで、Quillエディタに画像挿入ボタンが表示され、画像をアップロードしてエディタ内に挿入できるようになりました。実際のプロジェクトでは、セキュリティやエラーハンドリング、ファイルサイズ制限なども考慮する必要がありますが、基本的なセットアップは以上の通りです。
もし、外部サービス(例: S3、Cloudinary)を利用したい場合は、画像アップロードAPI内でそのサービスのSDKを使って画像をアップロードする形に変更できます。
サイト
ネビ活
Laravel 12 の Quill エディター + Livewire — 完全な CRUD + 画像と動画のアップロード (ステップバイステップ)
オープンソースTiptap