Дайте URL страницы или текстовый бриф — free-LLM в JSON-mode подбирает SEO-title, SEO-description, шаблон и палитру, а серверный SVG-композитор рендерит OG-превью 1200×630 и растеризует его через resvg-js. Никаких внешних image-gen API; на VPS не сохраняются ни URL, ни брифы — только хэш в audit.
Как это работает
Простая идея. Раньше OG-превью рисовали в Photoshop руками. Теперь так: вы говорите «вот URL» или «вот короткий бриф», нейросеть читает и решает, как этот контент назвать в одну строку и какие цвета взять. А обычный код, без всякой магии, по этому решению собирает SVG-картинку из готовых блоков и превращает её в PNG. Получается: смысл придумывает LLM, картинку рендерит детерминированная программа — поэтому результат всегда одинаковый при одинаковых входных данных и стоит ноль.
- Браузер отправляет URL или бриф на VPS обычным JSON-запросом. Никакой авторизации.
- Если был URL — сервер скачивает страницу (лимит 250 KB и 8 сек), вытаскивает из HTML title, meta description, og-теги и плоский текст.
- Метаданные + бриф уходят free-LLM из OpenRouter в JSON-режиме. Просим вернуть один JSON-объект: SEO-title, SEO-description, ключ шаблона из трёх возможных, четыре hex-цвета палитры и три строки copy (eyebrow / headline / footnote).
- Ответ парсится и валидируется библиотекой Zod. Если поле невалидное (например, hex-цвет с буквой Z) — один автоматический retry с подсказкой об ошибке. Дальше — fallback-модель.
- SVG-композитор берёт выбранный шаблон и подставляет в него LLM-овский текст и цвета. Никаких внешних шрифтов или картинок — только geometry и системные шрифты.
- resvg-js (open-source, без браузера) растеризует SVG в PNG 1200×630. Вы получаете оба файла, ничего не сохраняется на сервере.
Стек и ограничения
- LLM: free-модель из живого ранкинга OpenRouter,
response_format: json_object, retry-on-validation + fallback-модель. - Schema: Zod. Жёсткие лимиты: title ≤60, description ≤155, headline 3–72, hex-цвета только в формате
#RRGGBB. - Шаблоны:
headline-bold,split-mark,quote-frame— три фиксированные SVG-композиции. - URL fetch: только http/https, лимит 250 KB и 8 сек, content-type должен быть HTML.
- Rasterizer: @resvg/resvg-js 2.x — open-source rust-Rasterizer, без браузера.
- Stateless: ни URL, ни брифы не сохраняются. В audit пишется только sha256 от входа, выбранный шаблон, размеры SVG/PNG, время каждой стадии и id запроса.