Содержание:
Как исправить ошибку dangerouslySetInnerHTML в Next.js
Введение
В процессе разработки на Next.js 14 я столкнулся с неочевидной проблемой гидратации при использовании dangerouslySetInnerHTML
. В этой статье заметке я разберу причины возникновения ошибки и покажу решение, к которому я пришёл во время отладки.
Симптомы проблемы
При использовании dangerouslySetInnerHTML
в Next.js 14 у меня возникли две ошибки в консоли:
Первая ошибка указывает на несоответствие контента между серверным и клиентским рендерингом в dangerouslySetInnerHTML
.
Вторая ошибка сигнализирует о проблеме гидратации из-за несоответствия между серверным и клиентским UI.
При проверке Chrome DevTools можно заметить, что HTML-документ от сервера содержит идентичный текст тому, который отображается после гидратации на клиенте. Это делает ошибку достаточно странной для восприятия.
Проблемный код
Ошибка возникала в следующем фрагменте кода:
<p dangerouslySetInnerHTML={{ __html: text }} />
Где text
представляет собой HTML-строку, типичную для WYSIWYG-редакторов.
Причина возникновения ошибок
Корень проблемы кроется в спецификации HTML. В переменной text
могут содержаться теги <p>
, которые мы пытаемся обернуть в родительский тег <p>
.
Согласно спецификации HTML, элемент <p>
имеет Phrasing content model, и сам тег <p>
не входит в эту модель контента - см. спецификация. Это означает, что вложение параграфов друг в друга недопустимо по стандарту HTML.
Решение проблемы
Исправить ошибку можно простой заменой тега-обёртки на более подходящий (в моём случае <div>
):
<div dangerouslySetInnerHTML={{ __html: text }} />
Заключение
Формулировка ошибки, которую видно в Next.js на самом деле сбивает с толку, потому как ошибка “нарушение вложенности тегов” сюда подходила бы лучше и не заставила бы тратить время впустую на понимание причин.