Closed Mgsy closed 4 months ago
Currently, it's not possible to build the editor from the source using Next.js. I think it's related to a webpack configuration and Next.js webpack config requires some adjustments to make it compatible with CKEditor 5.
However, it's possible to run CKEditor 5 build inside Next.js application. To everyone struggling with the integration, please check the below workaround based on StackOverflow answer:
create-next-app
.npm install --save @ckeditor/ckeditor5-build-classic @ckeditor/ckeditor5-react
pages/index.js
file:import React, { useState, useEffect, useRef } from 'react'
export default function MyEditor () {
const editorRef = useRef()
const [ editorLoaded, setEditorLoaded ] = useState( false )
const { CKEditor, ClassicEditor } = editorRef.current || {}
useEffect( () => {
editorRef.current = {
CKEditor: require( '@ckeditor/ckeditor5-react' ),
ClassicEditor: require( '@ckeditor/ckeditor5-build-classic' )
}
setEditorLoaded( true )
}, [] )
return editorLoaded ? (
<CKEditor
editor={ ClassicEditor }
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( { event, editor, data } )
} }
/>
) : (
<div>Editor loading</div>
)
}
yarn dev
and open the application.The above solution uses our official classic editor build, however, you can customize a build "outside of the Next.js integration" and load it the same way. Also, you can use CKEditor 5 online builder to get a ready-to-use build with a set of desired plugins.
@Mgsy your solution works fine with basic use but got errors when I integrated with CKEditor Plugins like Easy Image or Alignment. Seems regarding to webpack configurtion:
_error - ./node_modules/@ckeditor/ckeditor5-ui/theme/icons/dropdown-arrow.svg 1:0 Module parse failed: Unexpected token (1:0) You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
Could not find files for /dashboard in .next/build-manifest.json ModuleParseError: Module parse failed: Unexpected token (1:0) You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders`
I was trying to follow the tutorial to create a simple plugin but I'm having the issue mentioned in #7343, because I'm importing the @ckeditor/ckeditor5-ui and @ckeditor/ckeditor5-core packages. I assume the same issue will arise in other packages as well, for anyone working with Next.js.
Could you please provide compiled packages or a workaround for this?
Thanks for your attention.
@Mgsy Just for context, Filipa is on my team (I'm the guy who originally raised the issue). We were doing great with the online build tool for a while, but we're now at the point where we need to add our own plug-in and the online build has become insufficient for our needs. If there's any way you could push offering compiled versions of your individual packages up your priority list, that would help us out tremendously. Until then, we'll probably need to handle this in some hacky way, which we really don't want to do. Thanks so much!
How do I enable the upload image option?
Might be useful: https://medium.com/@aisynurul99/custom-ckeditor-5-next-js-d6ef5cc7dd93 (did not review it)
@Mgsy your solution works fine with basic use but got errors when I integrated with CKEditor Plugins like Easy Image or Alignment. Seems regarding to webpack configurtion:
_error - ./node_modules/@ckeditor/ckeditor5-ui/theme/icons/dropdown-arrow.svg 1:0 Module parse failed: Unexpected token (1:0) You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
Could not find files for /dashboard in .next/build-manifest.json ModuleParseError: Module parse failed: Unexpected token (1:0) You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders`
I have the same issue. Were you able to resolve this?
Solve with this simple step
yarn install @ckeditor/ckeditor5-react @ckeditor/ckeditor5-build-classic
src/components/Editor.js
import ClassicEditor from '@ckeditor/ckeditor5-build-classic';
import CKEditor from '@ckeditor/ckeditor5-react';
const Editor = (props) => {
return (
<CKEditor
editor={ ClassicEditor }
data={props.value}
onChange={ (event, editor ) => {
const data = editor.getData()
props.onChange(data)
} }
/>
)
}
export default Editor;
src/pages/Home
, use component Editor like thisimport dynamic from 'next/dynamic'
const Editor = dynamic(() => import('../components/Editor'), { ssr: false })
const Home = () => {
return (
<Editor value="" onChange={(v)=> console.log(v)} />
)
}
export default Home;
@hscstudio @Mgsy both solutions result in an unhandled Runtime Error Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
Check the render method of MyEditor
.
Call Stack
createFiberFromTypeAndProps
node_modules\react-dom\cjs\react-dom.development.js (25058:0)
"dependencies": { "@ckeditor/ckeditor5-build-classic": "^24.0.0", "@ckeditor/ckeditor5-react": "^3.0.0", "next": "10.0.3", "react": "17.0.1", "react-dom": "17.0.1" }
AND
Unhandled Runtime Error Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
Check the render method of Editor
.
@hscstudio @Mgsy both solutions result in an unhandled Runtime Error Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
Check the render method of
MyEditor
.Call Stack createFiberFromTypeAndProps node_modules\react-dom\cjs\react-dom.development.js (25058:0)
"dependencies": { "@ckeditor/ckeditor5-build-classic": "^24.0.0", "@ckeditor/ckeditor5-react": "^3.0.0", "next": "10.0.3", "react": "17.0.1", "react-dom": "17.0.1" }
AND
Unhandled Runtime Error Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
Check the render method of
Editor
.
Show your code?
Here it is https://github.com/jorissparla/x. Very basic.
Here it is https://github.com/jorissparla/x. Very basic. Maybe error from code in pages/index.js, remove pages/index.js and rename pages/home.js to be pages/index.js
Here it is https://github.com/jorissparla/x. Very basic. Maybe error from code in pages/index.js, remove pages/index.js and rename pages/home.js to be pages/index.js
@jorissparla
change in Your packages to this version "@ckeditor/ckeditor5-react": "^1.1.0",
and then npm install
but I see working example
that worked, Also the second link worked. Need to play around to see what is causing the issues in my basic example. Thank you!!!
moving from "@ckeditor/ckeditor5-react": "^2.1.0", to "@ckeditor/ckeditor5-react": "^3.0.0", breaks the example. Bug report https://github.com/ckeditor/ckeditor5/issues/8704
Customized editor (with plugins) was really easy following the following docs and using the online builder.
@afk-mario Would you mind sharing how you got CKEditor plugins working with Next? I keep running into the "Global CSS cannot be imported from within node_modules" error when trying to set up ExportPdf.
@OrionLayton
node_modules
yarn add file:./ckeditor5
(ckeditor5 is the default name of the uncompressed zip build)import React, { Component } from 'react';
// When you add the ckeditor5 folder you can import it this way
import Editor from 'ckeditor5-custom-build/build/ckeditor';
import { CKEditor } from '@ckeditor/ckeditor5-react'
const editorConfiguration = {
toolbar: [ 'bold', 'italic' ]
};
function Editor () {
return (
<CKEditor
editor={ Editor }
config={ editorConfiguration }
data="<p>Hello from CKEditor 5!</p>"
onChange={ ( event, editor ) => {
const data = editor.getData();
console.log( { event, editor, data } );
}
/>
);
}
export default Editor;
Finally when you import this component make sure you are skipping server side rendering.
import React from 'react';
import dynamic from 'next/dynamic';
const Editor = dynamic(() => import('./components/editor'), {
ssr: false,
});
function App = () => {
return (
<div>
<Editor />
</div>
);
};
export default App;
If you need plugins outside of the ones that the online builder has support for I think you can create a custom build by yourself but didn't tried that, the process after getting the custom build should be similar.
@Mgsy I'm getting window is not defined
when I build
and get this during development.
From my experiment, I got ReferenceError: window is not defined
when running next build
if I implemented custom _app.js
file with some server-side data fetching method, such as getInitialProps
. The build didn't fail when I remove my custom _app.js
implementation. Ya... This is actually so annoying... :disappointed:
// // pages/_app.js (got from nextjs documentation: https://nextjs.org/docs/advanced-features/custom-app)
// Only uncomment this method if you have blocking data requirements for
// every single page in your application. This disables the ability to
// perform automatic static optimization, causing every page in your app to
// be server-side rendered.
//
// MyApp.getInitialProps = async (appContext) => {
// // calls page's `getInitialProps` and fills `appProps.pageProps`
// const appProps = await App.getInitialProps(appContext);
//
// return { ...appProps }
// }
Finally, I used cancellablePromise, React Mutable Ref, and dynamic import to solve that. But, currently I'm facing a performance issue when rendering more than 10 CKEditor with dynamic import, this will make the browser unresponsive. Still find a way to minimize this performance issue.
I was trying to follow the tutorial to create a simple plugin but I'm having the issue mentioned in #7343, because I'm importing the @ckeditor/ckeditor5-ui and @ckeditor/ckeditor5-core packages. I assume the same issue will arise in other packages as well, for anyone working with Next.js.
Could you please provide compiled packages or a workaround for this?
Thanks for your attention.
same issue!
Just wanted to throw my two cents in this thread. I integrated CKEditor into Next using the next/dynamic
component with {ssr:false}
in the options. However, I was still getting weird errors. I was using it in a page, on src/pages/ckeditor.js
just to test. Turns out that utilizing that route breaks CKEditor. Once I renamed that route, everything worked fine.
Is there any answers for ck editor plugin(Font) integration in Nextjs
Just wanted to throw my two cents in this thread. I integrated CKEditor into Next using the
next/dynamic
component with{ssr:false}
in the options. However, I was still getting weird errors. I was using it in a page, onsrc/pages/ckeditor.js
just to test. Turns out that utilizing that route breaks CKEditor. Once I renamed that route, everything worked fine.
Worked for me too! Have you able to get all the options? can we see like (git editor) when we are replying on Git Thread here? I am just seeing Bold and Italic option only. I tried implementing: plugins: [ Essentials, Bold, Italic, Paragraph ], but I get error:
./node_modules/@ckeditor/ckeditor5-clipboard/theme/clipboard.css Global CSS cannot be imported from within node_modules. Read more: https://nextjs.org/docs/messages/css-npm Location: node_modules\@ckeditor\ckeditor5-clipboard\src\dragdrop.js
Just wanted to throw my two cents in this thread. I integrated CKEditor into Next using the
next/dynamic
component with{ssr:false}
in the options. However, I was still getting weird errors. I was using it in a page, onsrc/pages/ckeditor.js
just to test. Turns out that utilizing that route breaks CKEditor. Once I renamed that route, everything worked fine.Worked for me too! Have you able to get all the options? can we see like (git editor) when we are replying on Git Thread here? I am just seeing Bold and Italic option only. I tried implementing: plugins: [ Essentials, Bold, Italic, Paragraph ], but I get error:
./node_modules/@ckeditor/ckeditor5-clipboard/theme/clipboard.css Global CSS cannot be imported from within node_modules. Read more: https://nextjs.org/docs/messages/css-npm Location: node_modules\@ckeditor\ckeditor5-clipboard\src\dragdrop.js
Found it with toolbar options here: https://ckeditor.com/docs/ckeditor5/latest/features/toolbar/toolbar.html#automatic-toolbar-wrapping not sure why those error for plugins! 👍
I have a builded editor, i created following ckeditor 5create online builder But, the embed video only shows on the editor, the source code that is generated when i get it on getData()
is different
When the editor convert the embed to a html code, is failing, getting me just this code when i use getData()
.
<figure class="media"><oembed url="https://www.youtube.com/watch?v=4zAThXFOy2c&feature=emb_title"></oembed></figure>
This is not right at all. It should be like a figure tag, some divs.. a etc.
Take a look how it is when we inspect the html code with the editor opened
This function should return the html source of our editor, but the part of convert embed to an html, is a complet failure
getData()
function is just this:
I have a page like edit/post/post_id
Then i show the post info on other page, like posts/post_id
In this ceneario i have to put the embed script on the Head of my document on the pageposts/post_id
, because is there where the people will see the embed source code converted to an html code.
Assuming you're using Next.js with React, you just have to import and paste the script of your embed converter, in my case is the Embedly
That following code be above of your body and you have to import Head from next/head
Now you go to the step 2, which is create a useEffect with an empty array of dependecies cause you want to him execute some code just one time, when the component is created on client-side.
https://github.com/ckeditor/ckeditor5/issues/7376#issuecomment-743113027 fixed it for me. Thanks.
Just wanted to throw my two cents in this thread. I integrated CKEditor into Next using the
next/dynamic
component with{ssr:false}
in the options. However, I was still getting weird errors. I was using it in a page, onsrc/pages/ckeditor.js
just to test. Turns out that utilizing that route breaks CKEditor. Once I renamed that route, everything worked fine.Worked for me too! Have you able to get all the options? can we see like (git editor) when we are replying on Git Thread here? I am just seeing Bold and Italic option only. I tried implementing: plugins: [ Essentials, Bold, Italic, Paragraph ], but I get error:
./node_modules/@ckeditor/ckeditor5-clipboard/theme/clipboard.css Global CSS cannot be imported from within node_modules. Read more: https://nextjs.org/docs/messages/css-npm Location: node_modules\@ckeditor\ckeditor5-clipboard\src\dragdrop.js
Any news on this issue? Any workaround?
Yes, I'm using one of the prebuild configuations. The problem is, that once I integrate the "WProofreader" plugin, the mentioned error message ("Global CSS cannot be imported from within node_modules") appears.
@tetaplaun Are you using a build ? if not, try make yours here on https://ckeditor.com/ckeditor-5/online-builder/
after that, you can just add the editor with npm
1 - extract the builder
2 - rename the path to ckeditor5
3 - add with npm add file:./ckeditor5
or npm add @file:./ckeditor5
Once you already have your editor, can import him in your component
// When you add the ckeditor5 folder you can import it this way
import Editor from 'ckeditor5-custom-build/build/ckeditor';
import { CKEditor } from '@ckeditor/ckeditor5-react';
export default function CEditor({ htmlData, setData }: any) {
return (
<CKEditor
editor={Editor}
data={htmlData}
onChange={(_event, editor) => {
const data = editor.getData();
console.log(data);
setData(data);
}}
/>
);
}
Remember to import dynamic on your component page
const CEditor = dynamic(() => import('../../components/Editor'), {
ssr: false,
});
const Page() {
const [data, setData] = useState();
return (
<div>
<CEditor
htmlData={'<h1>Hello World</h1>'}
setData={setData}
/>
</div>
)
}
Global CSS cannot be imported from within node_modules
may it help you https://github.com/vercel/next.js/discussions/27953 and https://github.com/bem/next-global-css
Global CSS cannot be imported from within node_modules
may it help you vercel/next.js#27953
Unfortunately, the problem is not solved yet, but thanks for the link! IU'm waiting for an official solution, any such hacks that could break my app in the future are not usefull in production.
The issue's still occured, when I want to use plugins like "Alignment, Image". This only work for "italic and bold" unfortunatly. Anybody fix it or has some working code?
Also looking for a official support from CKEditor team on supporting nextjs and CKEditor source builds without webpack hacks and tons of workarounds.
in my case i used custom build ckeditor version. my reference:
https://github.com/tranvanhuyhoang/nextjs-custom-ckeditor5/tree/master/
Uploaded an example project to my repository. I hope it helps those who are struggling with the same problem.
I don't want to use the Online builder path (custom build) but Building the editor from source (directly inside my project), but I can't configure the webpack in my next.config.js, to solve the css import issue.
and I get the following error:
reasons to use ckeditor5 like this, is because I'm using typescript and that way I don't need to be creating d.ts files for the custom build, because the Custom builds produced by the online builder and DLL versions of packages provided by CKEditor 5 do not provide built-in typings yet. another advantage is to create custom Plugins and Commands. becauese when I import and extend the Commands class in my project (@ckeditor/ckeditor5-core) I keep throwing the css error
I don't want to use the Online builder path (custom build) but Building the editor from source (directly inside my project), but I can't configure the webpack in my next.config.js, to solve the css import issue.
and I get the following error:
reasons to use ckeditor5 like this, is because I'm using typescript and that way I don't need to be creating d.ts files for the custom build, because the Custom builds produced by the online builder and DLL versions of packages provided by CKEditor 5 do not provide built-in typings yet. another advantage is to create custom Plugins and Commands. becauese when I import and extend the Commands class in my project (@ckeditor/ckeditor5-core) I keep throwing the css error
The global CSS issue is old.. but if you consider yourself a luck guy, try to download this library and config your webpack https://www.npmjs.com/package/@zeit/next-sass i don't think will work at all, i have the same issue myself in another project.
See more about because this is a issue ina Next.js project https://github.com/vercel/next.js/discussions/27953
I'm trying to use the Online builder in my application. I downloaded the customized editor file, added it to my application folder, at the same level as node_modules
, then ran the yarn add file:ckeditor5
command, as instructed here.
In development environment, it works perfectly fine. All features are performing according to my needs, and no errors occur. The issue arises when I try to ship this code to production.
The buildspec.yml
file has these commands:
Within the build, the yarn add file:ckeditor5
is executed correctly, with no errors. Before the build I also ran the yarn list ckeditor5-custom-build
command to check if the package installation had any errors:
However, during the build, this error occurs:
After some research, I still can't fathom what I'm doing wrong and why this error only occurs when deploying to production, so I'd like to ask for some help regarding this. The application is deployed to AWS.
This is (part of) the code showcasing how my editor is being used:
import { CKEditor } from '@ckeditor/ckeditor5-react'
import Editor from 'ckeditor5-custom-build/build/ckeditor'
// remaining imports / types
export default function CKEditorComponent({
fillDescription,
initialValue,
disabled = false
}: ICKEditorComponent) {
// rest of my application's code
return (
<CKEditor
editor={Editor}
onChange={(_event, editor) => {
const data = editor.getData()
handleEditorChange(data)
}}
onReady={editor => {
setEditorInstance(editor)
}}
disabled={disabled}
data={initialValue}
config={{
mediaEmbed: {
previewsInData: true
}
}}
/>
)
}
In the build logs, the Module not found
error was traced back to the page tsx file importing my component. This is how it is being imported:
import dynamic from 'next/dynamic'
const CKEditorComponent = dynamic(() => import('@source/components/CKEditorComponent'), {
ssr: false
})
Hey @40fathoms, unfortunately, I couldn't reproduce the issue on this setup. Both the dev and prod build work fine. The only difference I have is the path, not sure why you use @source
. I just have a straight path to the components folder.
import dynamic from 'next/dynamic'
const CKEditorComponent = dynamic(() => import('@source/components/CKEditorComponent'), {
ssr: false // ^^^^^^^
})
Another, very dummy idea, but make sure that the components
folder is copied to your container. Maybe it was dropped and not taken into it.
Hello @Witoso
Unfortunately, I did replace @source
for the straight path to the component, and the issue still happens (@source
is just a tsconfig custom import path I set to make it easier to import files directly from the src
folder).
The components
folder is also working correctly. When I comment out the editor and its imports, the remaining jsx elements within the same component file works just fine.
It works perfectly well in development, but importing the ckeditor5-custom-build/build/ckeditor
module when running yarn build while building at AWS seems to be causing some sort of issue. This error is very weird, I'm still trying to figure out what I'm doing wrong.
But thanks for reaching me out!
Hello everyone 👋!
We published an article in our docs, about the Next.js integration. I want to thank community members that shared examples above.
That said, there's still work in front of us to make this integration smoother. And we aim to fix it in its roots. I invite everyone to check our new installation methods RFC: #15502.
I don't want to use the Online builder path (custom build) but Building the editor from source (directly inside my project), but I can't configure the webpack in my next.config.js, to solve the css import issue.
and I get the following error:
reasons to use ckeditor5 like this, is because I'm using typescript and that way I don't need to be creating d.ts files for the custom build, because the Custom builds produced by the online builder and DLL versions of packages provided by CKEditor 5 do not provide built-in typings yet. another advantage is to create custom Plugins and Commands. becauese when I import and extend the Commands class in my project (@ckeditor/ckeditor5-core) I keep throwing the css error
i have same issue
Solve with this simple step
- Install ckeditor
yarn install @ckeditor/ckeditor5-react @ckeditor/ckeditor5-build-classic
- Wrap ckeditor as a component, create new file
src/components/Editor.js
import ClassicEditor from '@ckeditor/ckeditor5-build-classic'; import CKEditor from '@ckeditor/ckeditor5-react'; const Editor = (props) => { return ( <CKEditor editor={ ClassicEditor } data={props.value} onChange={ (event, editor ) => { const data = editor.getData() props.onChange(data) } } /> ) } export default Editor;
- On
src/pages/Home
, use component Editor like thisimport dynamic from 'next/dynamic' const Editor = dynamic(() => import('../components/Editor'), { ssr: false }) const Home = () => { return ( <Editor value="" onChange={(v)=> console.log(v)} /> ) } export default Home;
why paragraph heading is not working ? i use typescript instead for my nextjs. the changelog is already set H1 or any , but on editor is still small like other words without h1
// components/Editor.tsx
import { FC/* , ChangeEvent */, useEffect} from 'react';
// import dynamic from 'next/dynamic';
import { CKEditor } from '@ckeditor/ckeditor5-react';
import ClassicEditor from '@ckeditor/ckeditor5-build-classic';
// import { EventInfo } from '@ckeditor/ckeditor5-utils';
interface EditorProps {
value: string;
onChange: (data: string) => void;
}
const Editor: FC<EditorProps> = ({ value, onChange }) => {
/* ChangeEvent or ClassicEditor error params */
// const handleChange = (event: ChangeEvent, editor: ClassicEditor) => {
// const data = editor.getData();
// onChange(data);
// };
return (
<CKEditor
editor={ClassicEditor}
data={value}
onChange={(event: any, editor: any) => {
const data = editor.getData();
onChange(data);
}}
/>
);
};
export default Editor;
index.tsx
....
function YogiHome(props: {
profile: any;
}) {
return (
<Editor value="" onChange={(v: any)=> console.log(v)} />
....
@yogithesymbian could you provide a reproducible sample, e.g., on StackBlitz?
I am getting a flickering issue when i have added this line & also when I enter any data into other fields it makes an flickering effect. const ReactQuill = dynamic(() => import('react-quill'), { ssr: false });
Hello everyone, happy to report that we finished the looong work in #15502, and the new installation methods shipped in v42.0.0 make the Next.js integration much, much easier 🥳
Test the new setup with the Next.js integration guide, and let us know what you think!
Brilliant work thank you!
Do you plan to render any/all of the component server side in the future?
CKEditor 5 does not support server-side rendering (yet)
Thanks
📝 Provide a description of the new feature
Provide a guide for integrating CKEditor 5 with Next.js.
[Update 2 from @Witoso]
New installation methods shipped in v42.0.0 work seamlessly with Next.js. Check Next.js integration guide.
[Update]
Hello everyone 👋!
We published an article in our docs, about the Next.js integration. I want to thank community members that shared the examples below.
That said, there's still work in front of us to make this integration smoother. And we aim to fix it in its roots. I invite everyone to check our new installation methods RFC: #15502.
If you'd like to see this feature implemented, add a 👍 reaction to this post.