Skip to content

Point og:image rasterizing at the shared og-svg renderer - #86

Open
alcor wants to merge 4 commits into
mainfrom
og-svg-renderer
Open

Point og:image rasterizing at the shared og-svg renderer#86
alcor wants to merge 4 commits into
mainfrom
og-svg-renderer

Conversation

@alcor

@alcor alcor commented Aug 1, 2026

Copy link
Copy Markdown
Member

Points og:image rasterizing at the shared og-svg renderer, and removes the local rasterizer that could never be reached.

The bug

metadata.js built the rasterizer URL as a path:

if (!info.i.startsWith("http")) info.i = "/.netlify/functions/rasterize/" + info.i

But functions/rasterize.js read event.rawQuery — the query string, never the path. Probed against production to confirm:

URL form Result
/.netlify/functions/rasterize/svg:<b64> — as this code built it 502
/.netlify/functions/rasterize?<b64> — as the function read it 200 image/jpeg, 8707 bytes

The rasterizer worked fine. Nothing ever called it correctly, so i:-with-SVG links have been silently producing no preview image.

There was a second failure layered on top. By this point decodeURL has already run, and this repo's version does atob() with no try/catch. A payload that is not valid base64 throws, which the outer try swallows — killing all metadata for that page, not just the image.

The fix

renderUrl() builds an og-svg URL from the SVG markup decodeURL has already produced.

The payload is encoded as base64url, which stays URL-safe with no percent-encoding. That matters because Cloudflare caps URLs at 16KB, and percent-encoding raw markup is substantially more expensive — for the same test SVG, base64url produced a 346-character URL where percent-encoding produced 557.

Verified

Rendered against the live renderer:

200 PNG 600x315  len=346  markup -> base64url
200 PNG 400x200  len=301  unicode markup (via utoa)

The unicode case matters because btoa alone throws on non-Latin-1 input; this reuses the existing utoa helper.

Removed

functions/rasterize.js, the sharp dependency it needed, and the [functions] block that existed only to mark sharp as an external module. sharp appeared nowhere else in the repo.

Note on output format

og-svg returns PNG; the old rasterizer produced JPEG. Since no caller ever reached it successfully, there is no existing behaviour to stay compatible with, and every crawler accepts PNG.

Note on the base

This branch is rebased onto current main (25aa3cd). The working copy it was authored in predated that commit, which had removed the devDependencies block from package.json — rebasing rather than merging avoids silently re-adding netlify-cli. The resulting diff to package.json is only the removal of sharp.

🤖 Generated with Claude Code

alcor and others added 2 commits July 31, 2026 06:14
The old call built '/.netlify/functions/rasterize/' + svg as a path, but
rasterize.js only ever read the query string, so every request 502'd.
It also put unescaped SVG markup straight into a URL path.

decodeURL has already base64-decoded the value by this point, so what we
hold is SVG markup; it is re-encoded as base64url, which stays URL-safe
with no percent-encoding and so fits more into Cloudflare's 16KB URL cap.

Removes functions/rasterize.js and the sharp dependency it needed, plus
the [functions] block that existed only to mark sharp external.

Renderer: https://github.com/arfct/og-svg

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The old call built '/.netlify/functions/rasterize/' + svg as a path, but
rasterize.js only ever read the query string, so every request 502'd.
It also put unescaped SVG markup straight into a URL path.

decodeURL has already base64-decoded the value by this point, so what we
hold is SVG markup; it is re-encoded as base64url, which stays URL-safe
with no percent-encoding and so fits more into Cloudflare's 16KB URL cap.

Removes functions/rasterize.js and the sharp dependency it needed, plus
the [functions] block that existed only to mark sharp external.

Renderer: https://github.com/arfct/og-svg

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@alcor alcor self-assigned this Aug 1, 2026
alcor added 2 commits August 4, 2026 05:46
In-progress editor chrome rework on the og-svg-renderer branch:
- Relocate the doc-title metadata form from the page body into #formatbar,
  and add a params field plus a contenteditable #url-preview.
- Turn 'show preview' from a menu link into a PREVIEW button in the toolbar.
- Sketch a ShareForm class in bitty-menu.js for redirect.app share links.
  Incomplete: parse() still references undefined 'object' and 'dashspaces'.

Committed to preserve work ahead of moving this repo out of Dropbox.
The same og:image rasterizing change was committed independently on both
sides (ce065c4 locally, 0fde9b3 on origin), so the branches diverged 2/4.
Everything auto-merged except package.json.

package.json: both sides dropped the sharp dependency. Only origin touched
devDependencies (removing netlify-cli); we left it untouched, so the
conflict was textual, not semantic. Resolved to origin s version.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant