DEV Community

Cover image for CKEditor 5, Webpacker, VueJS, and you.
Brandon Cordell
Brandon Cordell

Posted on • Edited on

6 1

CKEditor 5, Webpacker, VueJS, and you.

The documentation for using CKEditor 5 with VueJS is pretty good, at least as far as open source technical documentation goes, but it makes the assumption that you're using vue-cli so it falls a bit short if you've set up Webpacker yourself or you're using Rails/Webpacker like I am.

Note: I am building CKEditor from source rather than using the prebuilt package.

The Setup

First we need to add the proper packages to build CKEditor in our project.

yarn add @ckeditor/ckeditor5-vue \
         @ckeditor/ckeditor5-dev-webpack-plugin \ 
         @ckeditor/ckeditor5-dev-utils \
         raw-loader@0.5.1
Enter fullscreen mode Exit fullscreen mode

Next we can prepend a new instance of CKEditorWebpackPlugin to
environment.plugins in config/webpack/environment.js.

// config/webpack/environment.js

const { environment } = require('@rails/webpacker');
// ... existing `require`s
const CKEditorWebpackPlugin = require('@ckeditor/ckeditor5-dev-webpack-plugin');

// ... existing code

environment.plugins.prepend('CKEditorWebpackPlugin', new CKEditorWebpackPlugin({
  addMainLanguageTranslationsToAllAssets: true,
  buildAllTranslationsToSeparateFiles: true,
  language: 'en',
}));

module.exports = environment;
Enter fullscreen mode Exit fullscreen mode

Don't forget to restart your server when your webpack config changes!

If you only use the language property like the documentation shows you'll be met with two errors.

[CKEditorWebpackPlugin] Error: No JS asset has been found during the compilation. You should add translation assets directly to the application from the `translations` directory. If that was intentional use the `buildAllTranslationsToSeparateFiles` option to get rid of the error.
[CKEditorWebpackPlugin] Error: Too many JS assets has been found during the compilation. You should add translation assets directly to the application from the `translations` directory or use the `addMainLanguageTranslationsToAllAssets` option to add translations for the main language to all assets or use the `buildAllTranslationsToSeparateFiles` if you want to add translation files on your own.
Enter fullscreen mode Exit fullscreen mode

Now that the Webpack plugin is set up we need to configure how the CKEditor SVG icons and css are parsed so we'll set up a loader for each. I like to keep my config/webpack/environment.js as clean as possible so we'll be creating small modules to include.

First we'll deal with the SVG icons. We need to use raw-loader to load the SVG icons as text.

Create the following config/webpack/loaders/ckeditor-svg.js

// config/webpack/loaders/ckeditor-svg.js

module.exports = {
  test: /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
  use: 'raw-loader',
};
Enter fullscreen mode Exit fullscreen mode

Let's go ahead and create the CKEditor css loader at
config/webpack/loaders/ckeditor-css.js.

// config/webpack/loaders/ckeditor-css.js

const { styles } = require('@ckeditor/ckeditor5-dev-utils');

module.exports = {
  test: /ckeditor5-[^/\\]+[/\\].+\.css$/,
  use: [{
    loader: 'style-loader',
    options: {
      injectType: 'singletonStyleTag',
      attributes: {
        'data-cke': true,
      },
    },
  }, {
    loader: 'postcss-loader',
    options: styles.getPostCssConfig({
      minify: true,
      themeImporter: {
        themePath: require.resolve('@ckeditor/ckeditor5-theme-lark'),
      },
    }),
  }],
};
Enter fullscreen mode Exit fullscreen mode

Now back in config/webpack/environment.js we can require these files and prepend them to environment.loaders.

// config/webpack/environment.js

const { environment } = require('@rails/webpacker');
// ... existing `require`s
const ckeditorSvgLoader = require('./loaders/ckeditor-svg');
const ckeditorCssLoader = require('./loaders/ckeditor-css');

// ... existing code

environment.loaders.prepend('ckeditor-svg', ckeditorSvgLoader);
environment.loaders.prepend('ckeditor-css', ckeditorCssLoader);

module.exports = environment;
Enter fullscreen mode Exit fullscreen mode

If we try to compile our project now it will fail with the following error (or something similar) for every CKEditor css file:

ERROR in ./node_modules/@ckeditor/ckeditor5-ui/theme/components/<component>/<stylesheet>.css (./node_modules/postcss-loader/src??ref--1-1!./node_modules/mini-css-extract-plugin/dist/loader.js!./node_modules/css-loader/dist/cjs.js??ref--5-1!./node_modules/postcss-loader/src??ref--5-2!./node_modules/@ckeditor/ckeditor5-ui/theme/components/<component>/<stylesheet>.css)
Module build failed (from ./node_modules/postcss-loader/src/index.js):
SyntaxError

(1:1) Unknown word

 > 1 | // extracted by mini-css-extract-plugin
Enter fullscreen mode Exit fullscreen mode

To fix this we'll have to exclude CKEditor's assets for our other loaders. Add the following lines to config/webpack/environment.js.

// config/webpack/environment.js

// ... the rest of the code

// The default value for css.exclude is `/\.module\.[a-z]+$/`
environment.loaders.get('css').exclude = [
  /\.module\.[a-z]+$/,
  /ckeditor5-[^/]+\/theme\/[\w-/]+\.css$/,
];
environment.loaders.get('file').exclude = path.resolve(__dirname, '..', '..', 'node_modules', '@ckeditor');
environment.loaders.get('moduleCss').exclude = /ckeditor5-[^/]+\/theme\/[\w-/]+\.css$/;

module.exports = environment;
Enter fullscreen mode Exit fullscreen mode

Using CKEditor

Add the packages you need.

yarn add @ckeditor/ckeditor5-editor-classic \
         @ckeditor/ckeditor5-essentials \
         @ckeditor/ckeditor5-basic-styles \
         @ckeditor/ckeditor5-link \
         @ckeditor/ckeditor5-paragraph \
         @ckeditor/ckeditor5-theme-lark
Enter fullscreen mode Exit fullscreen mode

For the sake of this article I'll activate CKEditor in my pack so it can be used application-wide.

// app/javascript/packs/application.js

import CKEditor from '@ckeditor/ckeditor5-vue';
import Vue from 'vue/dist/vue.esm';

Vue.use(CKEditor);

// ... the rest of the pack
Enter fullscreen mode Exit fullscreen mode

From here we can use the <ckeditor> component anywhere in our Vue app.

<template>
  <div id="app">
    <ckeditor
      v-model="editorData"
      :config="editorConfig"
      :editor="editor"
    />
  </div>
</template>

<script>
import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';

import BoldPlugin from '@ckeditor/ckeditor5-basic-styles/src/bold';
import EssentialsPlugin from '@ckeditor/ckeditor5-essentials/src/essentials';
import ItalicPlugin from '@ckeditor/ckeditor5-basic-styles/src/italic';
import LinkPlugin from '@ckeditor/ckeditor5-link/src/link';
import ParagraphPlugin from '@ckeditor/ckeditor5-paragraph/src/paragraph';

export default {
  data: () => ({
    editor: ClassicEditor,
    editorData: '<p>Content of the editor.</p>',
    editorConfig: {
      plugins: [
        BoldPlugin,
        EssentialsPlugin,
        ItalicPlugin,
        LinkPlugin,
        ParagraphPlugin,
      ],

      toolbar: {
        items: [
          'bold',
          'italic',
          'link',
          'undo',
          'redo',
        ],
      },
    },
  }),
};
</script>
Enter fullscreen mode Exit fullscreen mode

And that's it. Now go create!

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay