如何在React(Next.js)中使用CKEditor插入图片
解决CKEditor在Next.js中无法插入图片的问题
默认的@ckeditor/ckeditor5-build-classic预构建包不包含图片上传相关插件,这就是你无法使用图片插入功能的核心原因。以下是两种可行的解决方式:
方式一:手动组装编辑器并配置图片上传插件
这种方式无需自定义构建,直接通过安装所需插件组装编辑器,适合快速实现需求。
1. 安装必要依赖
执行命令安装编辑器核心、基础插件和上传插件:
npm install @ckeditor/ckeditor5-editor-classic @ckeditor/ckeditor5-essentials @ckeditor/ckeditor5-paragraph @ckeditor/ckeditor5-basic-styles @ckeditor/ckeditor5-list @ckeditor/ckeditor5-upload @ckeditor/ckeditor5-react
2. 修改Ckeditor.js组件
替换原有代码,手动组装编辑器并配置图片上传接口:
import React, { useEffect, useRef } from "react"; export default function CKeditor({ onChange, editorLoaded, name, value }) { const editorRef = useRef(); const { CKEditor, ClassicEditor } = editorRef.current || {}; useEffect(() => { // 动态导入编辑器和插件,避免Next.js SSR报错 const loadEditor = async () => { const { CKEditor } = await import("@ckeditor/ckeditor5-react"); const { ClassicEditor } = await import("@ckeditor/ckeditor5-editor-classic"); const { Essentials } = await import("@ckeditor/ckeditor5-essentials"); const { Paragraph } = await import("@ckeditor/ckeditor5-paragraph"); const { Bold, Italic } = await import("@ckeditor/ckeditor5-basic-styles"); const { NumberedList, BulletedList } = await import("@ckeditor/ckeditor5-list"); const { SimpleUploadAdapter } = await import("@ckeditor/ckeditor5-upload"); editorRef.current = { CKEditor, ClassicEditor: ClassicEditor.builtinPlugins = [ Essentials, Paragraph, Bold, Italic, NumberedList, BulletedList, SimpleUploadAdapter ], ClassicEditor }; }; loadEditor(); }, []); return ( <> {editorLoaded && CKEditor && ClassicEditor ? ( <CKEditor name={name} editor={ClassicEditor} data={value} config={{ // 配置图片上传接口,替换成你的后端上传API地址 simpleUpload: { uploadUrl: "/api/upload-image", // 可选:添加请求头,比如认证token headers: { 'Authorization': `Bearer ${localStorage.getItem('token')}` } } }} onChange={(event, editor) => { const data = editor.getData(); onChange(data); }} /> ) : ( <div>Editor loading</div> )} </> ); }
3. 实现后端上传接口
在Next.js项目中创建pages/api/upload-image.js,处理图片接收、存储并返回CKEditor要求的格式:
// pages/api/upload-image.js import formidable from 'formidable'; import fs from 'fs'; import path from 'path'; export const config = { api: { bodyParser: false, }, }; export default async function handler(req, res) { if (req.method !== 'POST') { return res.status(405).json({ message: 'Method not allowed' }); } const form = formidable({ uploadDir: path.join(process.cwd(), 'public/uploads'), keepExtensions: true, }); // 确保uploads目录存在 if (!fs.existsSync(path.join(process.cwd(), 'public/uploads'))) { fs.mkdirSync(path.join(process.cwd(), 'public/uploads'), { recursive: true }); } form.parse(req, (err, fields, files) => { if (err) { return res.status(500).json({ error: err.message }); } const image = files.upload; if (!image) { return res.status(400).json({ error: 'No image uploaded' }); } // 返回CKEditor要求的JSON格式 res.status(200).json({ url: `/uploads/${path.basename(image.filepath)}` }); }); }
执行命令安装formidable依赖:
npm install formidable
方式二:自定义CKEditor构建
如果需要更灵活的插件配置,可使用CKEditor在线构建工具生成包含图片上传插件的自定义包:
- 进入CKEditor在线构建工具,选择ClassicEditor模板
- 添加
SimpleUploadAdapter或ImageUpload等图片相关插件 - 下载构建包,替换项目中
@ckeditor/ckeditor5-build-classic依赖,或直接将构建包导入项目 - 在组件中配置上传接口即可,步骤参考方式一
内容的提问来源于stack exchange,提问作者nick
相关产品推荐
相关产品推荐

