Ckeditor5-react: convert uploaded image to base64

Created on 12 May 2020  ยท  11Comments  ยท  Source: ckeditor/ckeditor5-react

๐Ÿ“ Provide detailed reproduction steps (if any)

I start working on a custom editor but i found out that i need to upload an image to server so i decided to convert the image to Base64 so i used this : https://ckeditor.com/docs/ckeditor5/latest/features/image-upload/base64-upload-adapter.html
after that, I keep getting an error

I just wanna how can I solve the problem and convert image to base64

โœ”๏ธ Expected result

I was expecting to convert Image in client-side to Base64 and send it back to the backend

โŒ Actual result

I keep getting an error :

[](Uncaught CKEditorError: ckeditor-duplicated-modules: Some CKEditor 5 modules are duplicated. Read more: https://ckeditor.com/docs/ckeditor5/latest/framework/guides/support/error-codes.html#error-ckeditor-duplicated-modules

at Module.<anonymous> (http://localhost:3000/27.bundle.js:74179:8)
at Module../node_modules/@ckeditor/ckeditor5-upload/node_modules/@ckeditor/ckeditor5-utils/src/version.js (http://localhost:3000/27.bundle.js:74187:30)
at __webpack_require__ (http://localhost:3000/app.bundle.js:791:30)
at fn (http://localhost:3000/app.bundle.js:151:20)
at Module../node_modules/@ckeditor/ckeditor5-upload/node_modules/@ckeditor/ckeditor5-utils/src/emittermixin.js (http://localhost:3000/27.bundle.js:72106:66)
at __webpack_require__ (http://localhost:3000/app.bundle.js:791:30)
at fn (http://localhost:3000/app.bundle.js:151:20)
at Module../node_modules/@ckeditor/ckeditor5-upload/node_modules/@ckeditor/ckeditor5-utils/src/observablemixin.js (http://localhost:3000/27.bundle.js:72968:71)
at __webpack_require__ (http://localhost:3000/app.bundle.js:791:30)
at fn (http://localhost:3000/app.bundle.js:151:20))

๐Ÿ“ƒ Other details

  • CKEditor version: 2.1.0
  • Installed CKEditor plugins: โ€ฆ

CkEditor.js:

import ClassicEditorBase from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';
import BalloonToolbar from '@ckeditor/ckeditor5-ui/src/toolbar/toolbarview';
import Font from '@ckeditor/ckeditor5-font/src/font';
import Essentials from '@ckeditor/ckeditor5-essentials/src/essentials';
import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold';
import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic';
import Underline from '@ckeditor/ckeditor5-basic-styles/src/underline';
import Strikethrough from '@ckeditor/ckeditor5-basic-styles/src/strikethrough';
import List from '@ckeditor/ckeditor5-list/src/list';
import Link from '@ckeditor/ckeditor5-link/src/link';
import Autoformat from '@ckeditor/ckeditor5-autoformat/src/autoformat';
import Indent from '@ckeditor/ckeditor5-indent/src/indent';
import Alignment from '@ckeditor/ckeditor5-alignment/src/alignment';
import RemoveFormat from '@ckeditor/ckeditor5-remove-format/src/removeformat';
import BlockQuote from '@ckeditor/ckeditor5-block-quote/src/blockquote';
import MediaEmbed from '@ckeditor/ckeditor5-media-embed/src/mediaembed';
import Base64UploadAdapter from '@ckeditor/ckeditor5-upload/src/adapters/base64uploadadapter';


// import EasyImage from '@ckeditor/ckeditor5-easy-image/src/easyimage';
// import Image from '@ckeditor/ckeditor5-image/src/image';
// import ImageCaption from '@ckeditor/ckeditor5-image/src/imagecaption';
// import ImageStyle from '@ckeditor/ckeditor5-image/src/imagestyle';
// import ImageResize from '@ckeditor/ckeditor5-image/src/imageresize';
// import ImageToolbar from '@ckeditor/ckeditor5-image/src/imagetoolbar';
// import ImageUpload from '@ckeditor/ckeditor5-image/src/imageupload';
// import UploadAdapter from '@ckeditor/ckeditor5-adapter-ckfinder/src/uploadadapter';
// import CKFinder from '@ckeditor/ckeditor5-ckfinder/src/ckfinder';

// import Heading from '@ckeditor/ckeditor5-heading/src/heading';
// import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
// import PasteFromOffice from '@ckeditor/ckeditor5-paste-from-office/src/pastefromoffice';
// import Table from '@ckeditor/ckeditor5-table/src/table';
// import TableToolbar from '@ckeditor/ckeditor5-table/src/tabletoolbar';
// import PageBreak from '@ckeditor/ckeditor5-page-break/src/pagebreak';

export default class ClassicEditor extends ClassicEditorBase {
}

// Plugins to include in the build.
ClassicEditor.builtinPlugins = [
    BalloonToolbar,
    Font,
    Essentials,
    Link,
    Bold,
    Italic,
    Underline,
    Strikethrough,
    List,
    // Autoformat, // __
    Indent,
    RemoveFormat,
    Alignment,
    BlockQuote,
    // MediaEmbed,
    Base64UploadAdapter


    // CKFinder,
    // EasyImage,
    // Image,
    // ImageCaption,
    // ImageStyle,
    // ImageToolbar,
    // UploadAdapter,
    // ImageUpload,
    // ImageResize
];

// Editor configuration.
ClassicEditor.defaultConfig = {
    toolbar: {
        items: [
            'undo',
            'redo',
            '|',
            'fontFamily',
            'fontSize',
            'fontColor',
            'fontBackgroundColor',
            '|',
            'bold',
            'italic',
            'underline',
            'strikethrough',
            "blockquote",
            'removeFormat',
            '|',
            'alignment',
            'numberedList',
            'bulletedList',
            '|',
            'indent',
            'outdent',
            '|',
            // 'imageupload',
            "link",
            // "mediaembed"
        ]
    },
    image: {
        // toolbar: [
        //     'imageStyle:full',
        //     'imageStyle:side',
        //     '|',
        //     'imageTextAlternative'
        // ],
        styles: [
            // This option is equal to a situation where no style is applied.
            'full',

            // This represents an image aligned to the left.
            'alignLeft',
            'alignCenter',
            // This represents an image aligned to the right.
            'alignRight'
        ],
        resizeUnit: 'px'
    },
    table: {
        contentToolbar: [
            'tableColumn',
            'tableRow',
            'mergeTableCells'
        ]
    },
    fontSize: {
        options: [
            10,
            11,
            12,
            13,
            14,
            15,
            16,
            17,
            18,
            20,
            22,
            24
        ]
    },
    fontFamily: {
        options: [
            'Arial',
            'sans-serif',
            'Comic Sans MS',
            'Courier New',
            'Georgia',
            'Lucida Sans Unicode',
            'Tahoma',
            'Geneva',
            'Times New Roman',
            'Trebuchet MS',
            'Verdana',
            'Muli'
        ]
    },
    // This value must be kept in sync with the language defined in webpack.config.js.
    language: 'de'
};
import CKEditor from '@ckeditor/ckeditor5-react';
import ClassicEditor from './CkEditor';

export const CollapseEditEditor = () => {
return(
<CKEditor
                editor={ClassicEditor}
                onChange={(el, sd) => {console.log(sd)}}
                data="<p>Hello from CKEditor 5!</p>"
            />
)
}

package.json

{
  "name": "test",
  "version": "1.0.0",
  "homepage": ".",
  "dependencies": {
    "@babel/polyfill": "^7.8.3",
    "@ckeditor/ckeditor5-font": "^15.0.0",
    "@ckeditor/ckeditor5-page-break": "^15.0.0",
    "@ckeditor/ckeditor5-react": "^2.1.0",
    "@ckeditor/ckeditor5-remove-format": "^15.0.0",
    "@ckeditor/ckeditor5-ui": "^15.0.0",
    "@ckeditor/ckeditor5-upload": "^19.0.0",
    "@ckeditor/ckeditor5-word-count": "^15.0.0",
    "react-router": "5.1.2",
    "react-router-config": "5.1.1",
    "react-router-dom": "^5.1.2",
    "webpack-babel-env-deps": "^1.6.3"
  },
  "scripts": {
    "dev": "webpack-dev-server --config ./webpack.dev.js --open --host localhost",
    "build": "webpack --config ./webpack.prod.js --mode production"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": [
    ">0.2%",
    "not dead",
    "not op_mini all"
  ],
  "devDependencies": {
    "@babel/core": "^7.8.3",
    "@babel/plugin-proposal-class-properties": "^7.8.3",
    "@babel/plugin-proposal-export-default-from": "^7.2.0",
    "@babel/plugin-proposal-export-namespace-from": "^7.2.0",
    "@babel/plugin-proposal-object-rest-spread": "^7.8.3",
    "@babel/plugin-proposal-optional-chaining": "^7.8.3",
    "@babel/plugin-syntax-dynamic-import": "^7.8.3",
    "@babel/plugin-syntax-jsx": "^7.8.3",
    "@babel/plugin-transform-modules-commonjs": "^7.8.3",
    "@babel/plugin-transform-react-jsx-source": "^7.8.3",
    "@babel/preset-env": "^7.8.3",
    "@babel/preset-react": "^7.8.3",
    "babel-loader": "^8.0.6",
    "babel-plugin-styled-components": "^1.10.7",
    "clean-webpack-plugin": "^3.0.0",
    "css-loader": "^3.4.2",
    "file-loader": "^5.0.2",
    "html-webpack-plugin": "^3.2.0",
    "react-hot-loader": "^4.12.19",
    "sass-loader": "^8.0.2",
    "style-loader": "1.1.3",
    "webpack": "4.41.5",
    "webpack-cli": "3.3.10",
    "webpack-dev-server": "^3.10.1",
    "webpack-manifest-plugin": "^2.2.0",
    "webpack-merge": "^4.2.2",
    "@ckeditor/ckeditor5-dev-utils": "^12.0.0",
    "@ckeditor/ckeditor5-dev-webpack-plugin": "^8.0.0",
    "@ckeditor/ckeditor5-editor-classic": "^15.0.0",
    "@ckeditor/ckeditor5-adapter-ckfinder": "^15.0.0",
    "@ckeditor/ckeditor5-alignment": "^15.0.0",
    "@ckeditor/ckeditor5-autoformat": "^15.0.0",
    "@ckeditor/ckeditor5-basic-styles": "^15.0.0",
    "@ckeditor/ckeditor5-block-quote": "^15.0.0",
    "@ckeditor/ckeditor5-ckfinder": "^15.0.0",
    "@ckeditor/ckeditor5-core": "^15.0.0",
    "@ckeditor/ckeditor5-easy-image": "^15.0.0",
    "@ckeditor/ckeditor5-essentials": "^15.0.0",
    "@ckeditor/ckeditor5-heading": "^15.0.0",
    "@ckeditor/ckeditor5-image": "^15.0.0",
    "@ckeditor/ckeditor5-indent": "^15.0.0",
    "@ckeditor/ckeditor5-link": "^15.0.0",
    "@ckeditor/ckeditor5-list": "^15.0.0",
    "@ckeditor/ckeditor5-media-embed": "^15.0.0",
    "@ckeditor/ckeditor5-paragraph": "^15.0.0",
    "@ckeditor/ckeditor5-paste-from-office": "^15.0.0",
    "@ckeditor/ckeditor5-table": "^15.0.0",
    "@ckeditor/ckeditor5-theme-lark": "^15.0.0"
  }
}

question

Most helpful comment

I did more than 3 times and it didn't work ... but now it is working ๐Ÿ‘

thanks a lot for the help

All 11 comments

Hi! Your CKEditor 5 packages are in version 15.0.0 which is quite old. If you've installed Base64UploadAdapter package, it was installed in the latest version, which is 19.0.0. All CKEditor 5 packages should have the same version, so I recommend bumping your packages from 15.0.0 to the latest one - 19.0.0. After that, your problem should disappear.

i did as you said but i still getting the same error "ckeditor-duplicated-modules"
this is my package.json now :

{
  "name": "test",
  "version": "1.0.0",
  "homepage": ".",
  "dependencies": {
    "@babel/polyfill": "^7.8.3",
    "@ckeditor/ckeditor5-font": "^19.0.0",
    "@ckeditor/ckeditor5-page-break": "^19.0.0",
    "@ckeditor/ckeditor5-react": "^2.1.0",
    "@ckeditor/ckeditor5-remove-format": "^19.0.0",
    "@ckeditor/ckeditor5-ui": "^19.0.0",
    "@ckeditor/ckeditor5-upload": "^19.0.0",
    "@ckeditor/ckeditor5-word-count": "^19.0.0",
    "react-router": "5.1.2",
    "react-router-config": "5.1.1",
    "react-router-dom": "^5.1.2",
    "webpack-babel-env-deps": "^1.6.3"
  },
  "scripts": {
    "dev": "webpack-dev-server --config ./webpack.dev.js --open --host localhost",
    "build": "webpack --config ./webpack.prod.js --mode production"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": [
    ">0.2%",
    "not dead",
    "not op_mini all"
  ],
  "devDependencies": {
    "@babel/core": "^7.8.3",
    "@babel/plugin-proposal-class-properties": "^7.8.3",
    "@babel/plugin-proposal-export-default-from": "^7.2.0",
    "@babel/plugin-proposal-export-namespace-from": "^7.2.0",
    "@babel/plugin-proposal-object-rest-spread": "^7.8.3",
    "@babel/plugin-proposal-optional-chaining": "^7.8.3",
    "@babel/plugin-syntax-dynamic-import": "^7.8.3",
    "@babel/plugin-syntax-jsx": "^7.8.3",
    "@babel/plugin-transform-modules-commonjs": "^7.8.3",
    "@babel/plugin-transform-react-jsx-source": "^7.8.3",
    "@babel/preset-env": "^7.8.3",
    "@babel/preset-react": "^7.8.3",
    "babel-loader": "^8.0.6",
    "babel-plugin-styled-components": "^1.10.7",
    "clean-webpack-plugin": "^3.0.0",
    "css-loader": "^3.4.2",
    "file-loader": "^5.0.2",
    "html-webpack-plugin": "^3.2.0",
    "react-hot-loader": "^4.12.19",
    "sass-loader": "^8.0.2",
    "style-loader": "1.1.3",
    "webpack": "4.41.5",
    "webpack-cli": "3.3.10",
    "webpack-dev-server": "^3.10.1",
    "webpack-manifest-plugin": "^2.2.0",
    "webpack-merge": "^4.2.2",
    "@ckeditor/ckeditor5-dev-utils": "^12.0.0",
    "@ckeditor/ckeditor5-dev-webpack-plugin": "^8.0.0",
    "@ckeditor/ckeditor5-editor-classic": "^19.0.0",
    "@ckeditor/ckeditor5-adapter-ckfinder": "^19.0.0",
    "@ckeditor/ckeditor5-alignment": "^19.0.0",
    "@ckeditor/ckeditor5-autoformat": "^19.0.0",
    "@ckeditor/ckeditor5-basic-styles": "^19.0.0",
    "@ckeditor/ckeditor5-block-quote": "^19.0.0",
    "@ckeditor/ckeditor5-ckfinder": "^19.0.0",
    "@ckeditor/ckeditor5-core": "^19.0.0",
    "@ckeditor/ckeditor5-easy-image": "^19.0.0",
    "@ckeditor/ckeditor5-essentials": "^19.0.0",
    "@ckeditor/ckeditor5-heading": "^19.0.0",
    "@ckeditor/ckeditor5-image": "^19.0.0",
    "@ckeditor/ckeditor5-indent": "^19.0.0",
    "@ckeditor/ckeditor5-link": "^19.0.0",
    "@ckeditor/ckeditor5-list": "^19.0.0",
    "@ckeditor/ckeditor5-media-embed": "^19.0.0",
    "@ckeditor/ckeditor5-paragraph": "^19.0.0",
    "@ckeditor/ckeditor5-paste-from-office": "^19.0.0",
    "@ckeditor/ckeditor5-table": "^19.0.0",
    "@ckeditor/ckeditor5-theme-lark": "^19.0.0"
  }
}

and I checked the node_modules and I found out that I have in the ckeditor5-upload a node_modules folder which it is repeating the same library that is already installed in my main node_modules
Bildschirmfoto 2020-05-12 um 14 06 04

webpack.common.js:

const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ManifestPlugin = require('webpack-manifest-plugin');
const {CleanWebpackPlugin} = require('clean-webpack-plugin');
const { styles } = require( '@ckeditor/ckeditor5-dev-utils' );
const CKEditorWebpackPlugin = require( '@ckeditor/ckeditor5-dev-webpack-plugin' );


module.exports = {
    entry: {
        app: './src/index.js'
    },
    output: {
        path: path.resolve(__dirname, 'build'),
        filename: '[name].bundle.js',
    },
    optimization: {
        splitChunks: {
            chunks: 'all',
        },
    },
    plugins: [
        new CleanWebpackPlugin(),
        new webpack.HotModuleReplacementPlugin(),
        new HtmlWebpackPlugin({
            template: './public/index.html',
            filename: './index.html',
            favicon: './public/favicon.png'
        }),
        new ManifestPlugin({
            fileName: 'manifest.json',
            basePath: './public/',
            seed: {
                name: 'Manifest'
            }
        }),
        new CKEditorWebpackPlugin( {
            // The UI language. Language codes follow the https://en.wikipedia.org/wiki/ISO_639-1 format.
            language: 'de'
        } ),
    ],

    module: {
        rules: [
            {
                test: /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
                use: [ 'raw-loader' ]
            },
            {
                test: /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/,
                use: [
                    {
                        loader: 'style-loader',
                        options: {
                            injectType: 'singletonStyleTag',
                            attributes: {
                                'data-cke': true
                            }
                        }
                    },
                    {
                        loader: 'postcss-loader',
                        options: styles.getPostCssConfig( {
                            themeImporter: {
                                themePath: require.resolve( '@ckeditor/ckeditor5-theme-lark' )
                            },
                            minify: true
                        } )
                    }
                ]
            },
            {
                test: /\.(jsx|js)$/,
                loader: 'babel-loader',
                exclude: [
                    /node_modules\/(?!(inoport-frontend)\/).*/,
                ],
                options: {
                    presets: ['@babel/preset-env', '@babel/preset-react'],
                    plugins: ['@babel/plugin-syntax-dynamic-import', '@babel/plugin-proposal-class-properties']
                }
            },
            {
                test: /\.(css|less|scss)$/,
                exclude: /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/,
                use: ['style-loader', 'css-loader', 'sass-loader']
            },
            {
                test: /\.(ttf|eot|svg|woff|woff2|png|jpg)$/,
                exclude: /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
                loader: 'file-loader'
            }
        ]

    }
};

@Mgsy Hello,
do you have another idea, how could I solve the problem?

@AhmadYoussef, did you try to remove node_modules and install the packages again?

I did more than 3 times and it didn't work ... but now it is working ๐Ÿ‘

thanks a lot for the help

I did more than 3 times and it didn't work ... but now it is working ๐Ÿ‘

thanks a lot for the help

@AhmadYoussef Can you please tell how it worked for you after deleting node modules more than 3 times.

@muzamilar as I remember that the npm was installing the library from the cache. Therefore I just deleted node modules and package-lock.json and I am not sure if I forced clearing the cache in npm.
but in general, you need to make sure that @ckeditor libraries have the same version, and version "19.0.0" works fine with me.

@AhmadYoussef, I deleted node modules, package-lock.json and cleared
cache in npm. but still it is showing the same error. When I created the
new react project and added this custom build, it is working fine.

my package.json file

{
"name": "elit",
"version": "0.1.0",
"private": true,
"dependencies": {
@./ckeditor5-build-classic": "^27.1.0",
*
@./ckeditor5-react": "^3.0.2",
@./sparkline": "^0.3.10",
@./fontawesome-svg-core": "^1.2.28",
@./free-solid-svg-icons": "^5.12.1",
@./react-fontawesome": "^0.1.8",
@./core": "^4.11.3",
@./icons": "^4.9.1",
@./lab": "^4.0.0-alpha.45",
@./react-datatable": "^1.1.66",
@./kendo-date-math": "^1.5.1",
@./kendo-react-buttons": "^3.14.0",
@./kendo-react-dateinputs": "^3.14.0",
@./kendo-react-dropdowns": "^3.14.0",
@./kendo-react-intl": "^3.14.0",
@./kendo-react-tooltip": "^3.14.0",
@./react-chart.js": "^1.0.0-rc.3",
@./jest-dom": "^4.2.4",
@./react": "^9.3.2",
@./user-event": "^7.1.2",
@.**/react": "^17.0.2",
"apexcharts": "^3.26.0",
"array-move": "^3.0.1",
"axios": "^0.21.1",

On Wed, May 26, 2021, 7:53 PM Ahmad Youssef @.*>
wrote:

@muzamilar https://github.com/muzamilar as I remember that the npm was
installing the library from the cache. Therefore I just deleted node
modules and package-lock.json and I am not sure if I forced clearing the
cache in npm.
but in general, you need to make sure that @ckeditor
https://github.com/ckeditor libraries have the same version, and
version "19.0.0" works fine with me.

โ€”
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/ckeditor/ckeditor5-react/issues/150#issuecomment-848812994,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/ATHSHRG35AVWACOTFB6RCJ3TPT77RANCNFSM4M6YAGRA
.

@muzamilar I am not sure what is the problem. therefore I made for you a small example
https://codesandbox.io/s/ckeditor-5-forked-lk89x

@muzamilar I am not sure what is the problem. therefore I made for you a small example
https://codesandbox.io/s/ckeditor-5-forked-lk89x

Thank you @AhmadYoussef. In seperate project it is working fine i tested that.

@muzamilar I am not sure what is the problem. therefore I made for you a small example
https://codesandbox.io/s/ckeditor-5-forked-lk89x

@AhmadYoussef image upload is not working in the example that you have given above and i created one where onchange event is not working. It is not a custom build plugin.

Was this page helpful?
0 / 5 - 0 ratings