Reputation: 33
I'm experiencing an issue with the 'Highlight' component from 'react-highlight' when using NextJS in both development and production modes.
In development mode, the component renders properly with formatted styles. However, in production mode, it only displays plain text without the expected formatting.
I'm relatively new to NextJS, so I'm not sure what could be causing this difference. Do you have any idea why this might be happening? Any help would be greatly appreciated.
Header.tsx
'use client'
import "./Header.scss";
import { CodeBlock } from '../CodeBlock/CodeBlock';
import { codeSnipetsHeader, codeSnipetsHeader2 } from "./data";
import { useEffect, useRef } from "react";
import { motion } from "framer-motion";
import { usePathname } from 'next/navigation';
export function Header(): JSX.Element {
const pathname: string = usePathname();
/*Using useRef and ++ to regenerate <Header/> and play the animation each time the pathname changes. **/
const ref = useRef<number>(0);
useEffect(() => {
ref.current++;
}, [pathname]);
let codeSnipetstoShow = codeSnipetsHeader2;
if (pathname.length < 2) { codeSnipetstoShow = codeSnipetsHeader; }
return (
<header>
<motion.div key={ref.current} className="group" exit={{ opacity: 0 }} transition={{ duration: 1 }}>
{codeSnipetstoShow.map((value, index): JSX.Element => (
<motion.div key={index}
initial={{ opacity: 0 }}
animate={{ opacity: 1 - (index * 0.2) }}
transition={{ duration: index + 1 }}
>
<CodeBlock language="typescript" text={value.text} fontSize={value.fontSize} margin={value.margin} />
</motion.div>
))}
</motion.div>
</header>
);
}
CodeBlock.tsx
import { CSSProperties } from "react";
import Highlight from 'react-highlight';
import { motion } from 'framer-motion';
import './CodeBlock.scss';
interface CodeBlockProps {
text: string;
margin?: string;
fontSize: number;
language: "typescript" | "javascript" | "java" | "php";
}
/**
* @param text The text to be displayed as a code block
* @param margin Margin as top | right | bottom | left (in pixels)
* @param fontSize Display the text with the requested font size (in pixels)
* @param language The format (language to be used) for formatting
* @returns A code block that displays lines of code with color and formatting
**/
export function CodeBlock(props: CodeBlockProps): JSX.Element {
const marginStyle: CSSProperties = props.margin ? { margin: props.margin } : {};
const finalStyle: CSSProperties = { ...marginStyle, fontSize: props.fontSize };
return (
<motion.div className='codeblock' style={finalStyle}>
<Highlight language={props.language}>
{props.text}
</Highlight>
</motion.div>
);
}
See pictures: Dev Mode Prod Mode
I tryed to use dynamic import without success. I tryed to modify my css and split but without success.
I guess it's something related to Static Rendering maybe ? Not sure
Upvotes: 3
Views: 1085
Reputation: 33
I fixed it by uninstall 'react-highlight' package and instead use directly the library of Highlight, the code
CodeBlock.tsx
'use client'
import { CSSProperties, useEffect } from "react";
import { motion } from 'framer-motion';
import './CodeBlock.scss';
import hljs from './highlight.js_11.7.0.min.js';
interface CodeBlockProps {
text: string;
margin?: string;
fontSize: number;
language: "typescript" | "javascript" | "java" | "php";
}
/**
* @param text The text to be displayed as a code block
* @param margin Margin as top | right | bottom | left (in pixels)
* @param fontSize Display the text with the requested font size (in pixels)
* @param language The format (language to be used) for formatting
* @returns A code block that displays lines of code with color and formatting
**/
export function CodeBlock(props: CodeBlockProps): JSX.Element {
const marginStyle: CSSProperties = props.margin ? { margin: props.margin } : {};
const finalStyle: CSSProperties = { ...marginStyle, fontSize: props.fontSize };
useEffect(() => {
(async () => {
// @ts-ignore
await hljs.highlightAll();
})();
}, []);
return (
<motion.div className='codeblock' style={finalStyle}>
<pre key={Math.floor(Math.random() * 4)}>
<code>{props.text}</code>
</pre>
</motion.div >
)
}
I don't changed Header.tsx
at this point.
I don't know how type hljs.highlightAll();
so i used // @ts-ignore
Now it work as expected in production mode too. I expect something is not working anymore in the package 'react-highlight'.
Upvotes: 0