Integrating CKEditor into RemixJS: A Step-by-Step Guide
Tags: remix, ckeditor, webdev, typescript
Published: 2024-02-28 11:56:36

RemixJS, a modern JavaScript framework, offers a robust platform for building web applications. Integrating a rich text editor like CKEditor can enhance its functionality, providing an interactive and user-friendly interface for content creation. In this post, we'll guide you through the process of integrating CKEditor into a RemixJS application.

### **Step 1: Setting Up Your  Remix Project**

Create a new project with the create-remix command:

```jsx
npx create-remix@latest --template ryanflorence/remix-tutorial-template
```

### **Step 2: Installing CKEditor**

CKEditor is available as an npm package. Install it by running:

```bash

npm install --save @ckeditor/ckeditor5-react @ckeditor/ckeditor5-build-classic
```

This command installs both the React component (**`ckeditor5-react`**) and the classic build of CKEditor 5 (**`ckeditor5-build-classic`**).

### **Step 3: Creating the Text Editor Component**

On the same level as the app/ folder create a new folder named components. Create a new file, **`editor.tsx`**, in your components directory. This file will contain your text editor component. Here's a basic setup:

```tsx
// components/editor.tsx
import { CKEditor } from "@ckeditor/ckeditor5-react";
import ClassicEditor from "@ckeditor/ckeditor5-build-classic";

import { Suspense } from "react";

import type { Editor } from "@ckeditor/ckeditor5-core";
import type  ChangeEvent  from "@ckeditor/ckeditor5-utils/src/eventinfo";

interface TextEditorProps {
  data: string;
  onChange: (event: ChangeEvent, editor: Editor) => void;
}

  export function TextEditor({ data, onChange }: TextEditorProps) {

    return (
      <div>

      <Suspense fallback={"<div>Loading</div>"}>
        <CKEditor
          editor={ClassicEditor}
          data={data}
    		  onChange={onChange}
          // onReady={ 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 });
          //   }}
          onBlur={ ( event, editor ) => {
              console.log( 'Blur.', editor );
          } }
          // onFocus={ ( event, editor ) => {
          //     console.log( 'Focus.', editor );
          // } }
        />
      </Suspense>
      </div>
    );
}
```

This component uses CKEditor with the Classic build and includes basic event handling like **`onChange`** and **`onBlur`**.

### **Step 4: Using the Text Editor Component in Your App**

In your route file (for example, **`routes/_index.tsx`**), import and use the **`TextEditor`** component:

```tsx
// app/routes/_index.tsx
import { useState, useEffect } from 'react';
import { Form } from '@remix-run/react';

// CK5 Rich-Text-Editor Types
import type ChangeEvent from "@ckeditor/ckeditor5-utils/src/eventinfo";
import type ClassicEditor from "@ckeditor/ckeditor5-build-classic";

export default function Index(){
    const [TextEditorContent, setTextEditorContent] = useState("");
    const [TextEditorComponent, setTextEditorComponent] = useState<React.ElementType | null>(null);
  
    useEffect(() => {
      async function loadTextEditor() {
        try {
          console.log('Attempting to load TextEditor');
          const { TextEditor } = await import('../../components/editor');
          console.log('TextEditor loaded:', TextEditor);
          setTextEditorComponent(() => TextEditor);
        } catch (error) {
          console.error('Failed to load TextEditor:', error);
        }
      }
      loadTextEditor();
    }, []);

    return (
        <Form>
        <h1>CKEditor + RemixJS</h1>

        <input type='hidden' name="message" value={TextEditorContent} />

        {TextEditorComponent && <TextEditorComponent data={TextEditorContent} onChange={(event: ChangeEvent, editor: ClassicEditor) => {
          const data = editor.getData();
          setTextEditorContent(data);
          console.log({ event, editor, data });
          }} 
          />
        }

      </Form>
    )
}
```

In this setup, **`TextEditor`** is loaded asynchronously, and the **`data`** and **`onChange`** props are used to manage the editor's state.

### Typescript Config

For me it was necessary to add a line of code into the tsconfig.json below the `**target**` line:

```jsx
"module": "es2022",
```

### **Conclusion**

Integrating CKEditor into RemixJS adds powerful text editing capabilities to your web applications. The above steps guide you through a basic setup. Experiment with different configurations and features to tailor the editor to your application's needs.

Remember, CKEditor is a versatile tool. With its wide range of features and customization options, you can create a rich text editing experience that perfectly fits the needs of your users.

**Here you can find the Github-Repo of this tutorial:**

https://github.com/nickfthedev/tutorial-remix-ckeditor

**If you like this article please follow me on X:**

[Nick (@nickfthedev) on X](https://twitter.com/nickfthedev)