#ckeditor #next.js
#ckeditor #next.js
Вопрос:
Я следую инструкциям из этого. И мой редактор CKEditor теперь может работать в моем приложении nextjs. Но проблема в том, что когда я хочу поместить simpleUploadAdapter, появляется сообщение об ошибке, в котором говорится, что props.editor.create не является функцией. Вот код :
import Head from 'next/head'
import styles from '../styles/Home.module.css'
import React, { useState, useEffect, useRef } from 'react'
export default function Home() {
const editorCKRef = useRef()
const [editorLoaded, setEditorLoaded] = useState(false)
const { CKEditor, SimpleUploadAdapter, ClassicEditor } = editorCKRef.current || {}
useEffect(() => {
editorCKRef.current = {
CKEditor: require('@ckeditor/ckeditor5-react'),
// SimpleUploadAdapter: require('@ckeditor/ckeditor5-upload/src/adapters/simpleuploadadapter'),
ClassicEditor: require('@ckeditor/ckeditor5-build-classic')
}
setEditorLoaded(true)
}, [])
return (
<div className={styles.container}>
<Head>
<title>My CKEditor 5</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<h2>Using CKEditor 5 build in Next JS</h2>
{editorLoaded amp;amp; ClassicEditor amp;amp;
<CKEditor
name="editor"
editor={ typeof ClassicEditor !== 'undefined' ?
ClassicEditor.create(
document.getElementsByName("editor"), {
plugins: [ SimpleUploadAdapter],
//toolbar: [ ... ],
simpleUpload: {
// The URL that the images are uploaded to.
uploadUrl: 'http://example.com',
// Enable the XMLHttpRequest.withCredentials property.
withCredentials: false
}
}
): ''
}
data="<p>Hello from CKEditor 5!</p>"
onInit={ editor => {
// You can store the "editor" and use when it is needed.
console.log( 'Editor is ready to use!', editor );
} }
onChange={ ( event, editor ) => {
const data = editor.getData();
console.log('ON CHANGE')
// console.log(ClassicEditor.create())
// console.log( { event, editor, data } );
} }
onBlur={ ( event, editor ) => {
console.log( 'Blur.', editor );
} }
onFocus={ ( event, editor ) => {
console.log( 'Focus.', editor );
} }
config={
{
simpleUpload: {
uploadUrl: 'localhost:8000/api/files/upload/question/1'
}
}
}
/>
}
</div>
)
}
Так в чем же здесь проблема? Спасибо
Ответ №1:
Я заставил свой работать, обернув компонент CKEditor в собственный компонент класса.
class RichTextEditor extends React.Component<Props, State> {
render() {
const { content } = this.props;
return (
<CKEditor
editor={ClassicEditor}
data={content}
/>
);
}
}
Кажется, CKEditor просто плохо работает с функциональными компонентами. Затем используйте динамический импорт для загрузки оболочки, если вы используете NextJS.
const RichTextEditor = dynamic(() => import("/path/to/RichTextEditor"), {
ssr: false,
});
Ответ №2:
Я вспомнил, что CKEditor4 проще настроить в Next.js . CKEditor5 требует дополнительной работы, вы должны использовать динамический импорт с режимом ssr=false
Но в вашем случае вы также хотите использовать другой плагин SimpleUploadAdapter
Я попытался использовать компонент CKEditor React build classic SimpleUploadAdapter, но обнаружил ошибку «Дублирование кода между build classic и исходным кодом (SimpleUploadAdapter)».
Поэтому я решил настроить ckeditor5-build-classic, добавить туда плагин и перестроить, а затем заставить его работать :)(https://ckeditor.com/docs/ckeditor5/latest/builds/guides/development/custom-builds.html )
Вот несколько замечаний:
- Пользовательский ckeditor5-build-classic
// ckeditor5-build-classic-custom local package
// Add SimpleUploadAdapter into the plugin list
// src/ckeditor.js
import SimpleUploadAdapter from '@ckeditor/ckeditor5-upload/src/adapters/simpleuploadadapter';
ClassicEditor.builtinPlugins = [
...
SimpleUploadAdapter
...
]
// Rebuild for using in our app
npm run build
- Используйте пользовательскую сборку в нашем приложении
// app/components/Editor.js
import CKEditor from "@ckeditor/ckeditor5-react";
import ClassicEditor from "@ckeditor/ckeditor5-build-classic";
...
<CKEditor
editor={ClassicEditor}
config={{
// Pass the config for SimpleUploadAdapter
// https://ckeditor.com/docs/ckeditor5/latest/features/image-upload/simple-upload-adapter.html
simpleUpload: {
// The URL that the images are uploaded to.
uploadUrl: "http://example.com",
// Enable the XMLHttpRequest.withCredentials property.
withCredentials: true,
// Headers sent along with the XMLHttpRequest to the upload server.
headers: {
"X-CSRF-TOKEN": "CSRF-Token",
Authorization: "Bearer <JSON Web Token>",
},
},
}}
...
- Динамический импорт для загрузки редактора со стороны клиента
// pages/index.js
import dynamic from "next/dynamic";
const Editor = dynamic(() => import("../components/editor"), {ssr: false})
Подводя итог:
- Настройте сборку CKEditor, добавьте необходимые плагины… затем перестройте. Создайте их как локальный пакет
- Используйте этот локальный пакет в нашем приложении!
- Проверьте мой пример git с длинными комментариями: https://github.com/nghiaht/nextjs-ckeditor5