highlight.js
highlight.js copied to clipboard
highlight.js , ckededitor5 , next.js Element previously highlighted. To highlight again, first unset `dataset.highlighted`.
I'm using Next.js and ckeditor for generating content . code is :
'use client'
import React, { useEffect, useRef } from 'react'
import Box from '@mui/material/Box'
import DOMPurify from 'dompurify'
import hljs from 'highlight.js'
import '@/common/components/Editor/Content.css'
import 'highlight.js/styles/ascetic.css'
interface ParseContentProps {
content: string
}
export const ParseContent = ({ content }: ParseContentProps) => {
const contentRef = useRef<HTMLDivElement>(null)
const sanitizedContent = DOMPurify.sanitize(content)
useEffect(() => {
const codeBlocks = contentRef.current?.querySelectorAll('pre code')
codeBlocks?.forEach((block) => {
hljs.highlightElement(block as HTMLElement)
})
}, [sanitizedContent])
return (
<div className="ck-content">
<Box
ref={contentRef}
dangerouslySetInnerHTML={{
__html: sanitizedContent,
}}
/>
</div>
)
}
But it doesn't highlight anything and keep giving error :
Element previously highlighted. To highlight again, first unset `dataset.highlighted`. <code class="language-javascript hljs" data-highlighted="yes">…</code>
if I use
'use client'
import React, { useEffect, useRef } from 'react'
import Box from '@mui/material/Box'
import DOMPurify from 'dompurify'
import hljs from 'highlight.js'
import '@/common/components/Editor/Content.css'
import 'highlight.js/styles/ascetic.css'
interface ParseContentProps {
content: string
}
export const ParseContent = ({ content }: ParseContentProps) => {
useEffect(() => {
hljs.highlightAll()
}, []) // Dependency on sanitizedContent to re-run on change
return (
<div className="ck-content">
<pre>
<code className="language-javascript">{'let a=5;'}</code>
</pre>
</div>
)
}
It starts working , not sure what is causing the first example not working does it have something to do with SSR ? not sure what I need to change , first one seems fine to me , Is this a highligh.js bug ?
Element previously highlighted.
There is no reason to highlight an element twice.
does it have something to do with SSR
That would make sense, if it was highlighted server-side it does not need to be re-highlighted on the client - it's already highlighted.
@joshgoebel yes but the real problem is not the warning . highlight doesnt work in first case ,I guess it only do it on server side and completely ignore client side . what's the solution here ?
the output is really weird , if I refresh the page , no highlight
but if I change the route from another page to this one highlight start working
I figure out that the error about previously highlited was not about SSR but about reactStrictMode , which according to documents :
React 18 enables Strict Mode, which triggers an additional render cycle during development to help identify side effects
If I disable it in next.config.js , no warning will be shown . But the main problem still remains, when I refresh the page there is no highlighting , but if I move between pages I have highlighting
I would suggest modifying your first example to do exactly what is suggested:
first unset
dataset.highlighted.
So write custom Javascript to do that (unset it) BEFORE you call highlightAll... then everything should just work.
is this issue still open? I would like to help. Please assign it to me
yes but the real problem is not the warning . highlight doesnt work in first case ,I guess it only do it on server side and completely ignore client side . what's the solution here ?
This sounds like a problem with your config/framework/server-side generation, etc. So far I've heard or seen nothing that sounds like a library bug. If someone can provide a jsfiddle that shows this issue (without React or other confounding factors).
Here is how the library behaves:
- When Highlight.js highlights an element (
highlightElement) it marks the element as highlighted viadataset.highlighted - It will refuse to highlight any element already flagged with
dataset.highlighted
This is the current expected behavior of the library, and considered correct.
If you're doing something [React, etc] on the client-side that somehow replaces ALL of the block's HTML content - but does NOT remove dataset.highlighted then you will need to remove that manually - before asking Highlight.js to re-highlight the block.
The advice above to disable reactStrictMode sounds like good advice - or perhaps it has a hook to add behavior to it - in which case you might need to add code there to unset dataset.highlighted.
is this issue still open? I would like to help.
What do you think the fix is? It's not clear yet to me that anything needs to be changed.
Closing for inactivity.