I am working on a blog site and struggling to find the way to display the raw content of ckeditor in react js tried setInnerHtml <- (bad formating) ? How to display the content in the exact same format as present in the editor. Working with CKeditor5
look for a library called react-html-parser it would the problem :
https://www.npmjs.com/package/react-html-parser
and this youtube tutorial shows how to use ckeditor with react html parser library
use this package react-html-parser for showing html
HtmlParser(editorState) < this function will render html
I came up with the following solution using Next.js 13.4.19, and the interweave library. This piece of code will display content EXACTLY as it appears in the editor. I believe you can use any html rendering library of your choice. This solution should work with any other popular framework like React. The TRUE trick here is to:
- Download or copy all styles from official CKEditor 5 docs and place them in
content.module.css
- you can name this file anything you want, just make sure that it hasmodule
part - Make CKEditor export HTML instead of Markdown (I haven't tested this solution with Markdown, so let me know if this works).
- IMPORTANT: Wrap the content in a container with
ck-content
class - otherwise CSS won't be applied - import this stylesheet and tell
interweave
(or any other library of your choice) to apply it to the components that haveclass
attribute WITHOUT creating a new React component as it's simpler.
The following code presents an SSR component, hence the polyfill();
at the beginning. Please note, that in the case of images, you have to handle the proper source filling yourself as the content might come from an external source, CMS for example. The simplest solution, I believe, would be to just get the attribute from the node and paste it into the component.
import { Markup, Node } from "interweave";
import { polyfill } from 'interweave-ssr';
import Image from "next/image";
import styles from "@/app/styles/richtext.module.scss"
import React from "react";
polyfill();
function transform(node: HTMLElement, children: Node[]): React.ReactNode {
const cls = node.getAttribute("class")
if (node.tagName == "img") {
const imgUrl = computeImageSource() // YOU HANDLE THIS YOURSELF
return (
<Image
src={imgUrl || ""}
alt={node.getAttribute("alt") || "none provided"}
width={0}
height={0}
sizes="100vw"
layout="responsive"
loading='eager'
/>
)
} else if (cls) {
node.setAttribute("class", cls.split(" ").map(c => styles[c]).join(" "))
return undefined;
}
}
export default function Content({ data }: { data: any }) {
// console.log(data)
return (
<section>
<Markup content={data} transform={transform} className={styles["ck-content"]} />
</section>
);
}
The line cls.split(" ").map(c => styles[c]).join(" ")
is important as it tells Next.js to apply appropriate CSS classes from the stylesheet.
import parse from "html-react-parser";
return {content && parse(content)}
note that parse must not get undefiend or null which can occure error when content is rendered.
© 2022 - 2024 — McMap. All rights reserved.