Я пытаюсь реализовать рендеринг на стороне сервера выделенных (токенизированных) блоков кода с помощью Prismjs (примечание: я знаю, как это сделать, используя рендеринг на стороне клиента через useEffect
и refs
, и я получил эту работу, используя prism-react-renderer. Я специально ищу решение для голых Prismjs и SSR).
// codeExamples = array of some code strings
const Code = ({ code, language }) => {
const html = Prism.highlight(code, Prism.languages[language], language);
return (
<pre
data-language={language}
className={`language-${language}`}
>
<code
dangerouslySetInnerHTML={{
__html: html,
}}
/>
</pre>
);
};
export default function Home() {
return codeExamples.map((example, i) => (
<Code
language="javascript"
code={example}
key={i}
></Code>
));
}
В некоторой степени это работает, но я столкнулся с проблемой: блок кода ненадолго перерисовывается, вероятно, из-за ведущего пробела в атрибуте class
:
- 1-й рендер:
class="language-javascript"
- 2-й рендер:
class=" language-javascript
Это вызывает (помимо бессмысленного дорогостоящего повторного рендеринга) неприятный сдвиг макета, временно исправленный путем добавления жестко запрограммированных font-size
в пикселях к элементу <pre>
.
Иногда я получаю предупреждения либо о несоответствии свойств сервера и клиента (невозможно воспроизвести прямо сейчас), либо о Extra attributes from the server: class
- но только при запуске next dev
, а не при запуске next build && next start
.
Проверено на последних версиях Nextjs и Prism.