hastToReact()

Преобразует корневой HAST-узел в элементы React. Низкоуровневая функция, когда нужен полный контроль над конвейером компиляции.

import { hastToReact } from "@unifast/react";

Сигнатура

function hastToReact(
  hast: HastRoot,
  options: HastToReactOptions,
): unknown

Параметры

hast

СвойствоТипПо умолчаниюОписание
type"root"Идентификатор типа узла
childrenHastNode[]Дочерние узлы дерева

options

Конфигурация создания React-элементов

СвойствоТипПо умолчаниюОписание
createElementCreateElementФункция React createElement
FragmentunknownКомпонент React Fragment
components?ComponentMapОтображение имён HTML-тегов в пользовательские React-компоненты

Использование

import { createElement, Fragment } from "react";
import { compile } from "@unifast/node";
import { hastToReact } from "@unifast/react";
import type { HastRoot } from "@unifast/core";

const result = compile(md, { outputKind: "hast" });
const hast: HastRoot = JSON.parse(result.output as string);

const element = hastToReact(hast, {
  createElement,
  Fragment,
  components: {
    pre: ({ children, ...props }) => <pre className="code-block" {...props}>{children}</pre>,
    a: ({ children, ...props }) => <a target="_blank" rel="noopener" {...props}>{children}</a>,
  },
});

Примеры

Базовое использование

import { createElement, Fragment } from "react";
import { compile } from "@unifast/node";
import { hastToReact } from "@unifast/react";
import type { HastRoot } from "@unifast/core";

const result = compile("# Hello, **world**!", { outputKind: "hast" });
const hast: HastRoot = JSON.parse(result.output as string);
const element = hastToReact(hast, { createElement, Fragment });

function Page() {
  return <div>{element}</div>;
}

С HAST, подсвеченным через Shiki

import { createElement, Fragment } from "react";
import { compile } from "@unifast/node";
import { createShikiTransformer } from "@unifast/shiki";
import { hastToReact } from "@unifast/react";
import type { HastRoot } from "@unifast/core";

const transformer = await createShikiTransformer({
  themes: ["github-dark"],
  langs: ["typescript"],
});

const result = compile(md, { outputKind: "hast" });
const hast: HastRoot = JSON.parse(result.output as string);
const highlighted = transformer.transform(hast);
const element = hastToReact(highlighted, { createElement, Fragment });

Серверный рендеринг

import { createElement, Fragment } from "react";
import { renderToString } from "react-dom/server";
import { compile } from "@unifast/node";
import { hastToReact } from "@unifast/react";
import type { HastRoot } from "@unifast/core";

const result = compile(md, { outputKind: "hast" });
const hast: HastRoot = JSON.parse(result.output as string);
const element = hastToReact(hast, { createElement, Fragment });
const html = renderToString(element);

console.log(html);
// Отрендеренная HTML-строка для SSR

Поведение

  • Переименование свойств: HTML-атрибуты переименовываются в соответствующие React-аналоги (class в className, for в htmlFor и т. д.)

  • Парсинг стилей: CSS-строки стилей разбираются в объекты стилей React

  • Массивы className: HAST-массивы className объединяются через пробел

  • Булевы атрибуты: true отрисовывает атрибут, false/null/undefined опускает его

  • Сырые узлы: отрисовываются как инлайн-HTML — используйте плагин sanitize (из @unifast/node) при обработке недоверенного входа

  • Комментарии и doctype: игнорируются (возвращается null)