Add social preview thumbnails for shared conversations (#2309)
* Add social preview thumbnails for shared conversations
Shared conversation links (/r/{id}) now render an OpenGraph card like
model pages do, showing the first user prompt (clamped to 3 lines), the
model name and app branding.
- /r/[id]/thumbnail.png renders a 1200x648 PNG via satori + resvg. The
element tree is built as plain objects (no satori-html): user text is
never parsed as HTML, which would allow server-side fetches of
attacker-controlled <img> URLs and renders escaped entities literally.
- User text is sanitized before rendering: control/bidi/zero-width chars
stripped, emoji removed, scripts the bundled Inter font cannot render
(CJK, Arabic, ...) collapsed into an ellipsis with a fallback chain of
prompt -> title -> generic card. og:description keeps all scripts.
- /r/[id] now serves the preview tags itself and continues to the
view-only conversation client-side instead of 302-redirecting:
crawlers such as facebookexternalhit request with Accept: */*, which
/conversation/[id] cannot serve (its +server.ts captures non-HTML
GETs with a 405). Logged-in share import is unchanged.
- /conversation/[id] also emits the tags for share ids for crawlers
that scrape it directly with Accept: text/html.
- Thumbnails are only ever rendered for shared conversations (public
snapshots); private conversation ids cannot reach the endpoint.
* Match share thumbnails to the model thumbnail style
- Drop the yellow eyebrow text and all non-monochrome colors; use the
same black background asset as ModelThumbnail (vendored and inlined
as a data URI so rendering needs no network call).
- Fix the stretched logo: the source svg declares height=55 against a
575x100 viewBox, so its intrinsic size was ambiguous and renderers
stretched it to 575x55. Pin the intrinsic size to the viewBox and
render it larger (64px) in a centered 'Continue the chat on' row,
mirroring the model cards.
- Center the prompt and keep the model id legible over the light streak
with a translucent pill.
* Left-aligned share thumbnail composition with hanging quote
- Content block on the left: hanging opening quote, left-aligned prompt
(3-line clamp), short divider, 'Continue the chat on <logo>' line and
a bordered pill with the model id. Monochrome throughout.
- Replace the background with a generated 1200x648 black canvas whose
diagonal light streak sits on the right, leaving the text area dark
(rendered from blurred SVG ellipses with resvg, no external asset).
- Bump the HuggingChat logo to 48px so it reads clearly at preview size.
---------
Co-authored-by: Claude <noreply@anthropic.com>