NP@naman-parashar-s-team / OG imagePublic
OG image
A JS snippet on QuikRun, callable at quik.run/r/og-image.
JS· node:20· 3 runs· 0 forks· updated 13h ago
OG image.js
export default async function handler(req, env) {// ---------- Inputs (escaped + clamped, tasteful on-brand defaults) ----------const q = req.query || {};const pick = (v, fallback) =>typeof v === "string" && v.trim() ? v.trim() : fallback;const title = clamp(pick(q.title, "Run one file at the edge."), 88) || "QuikRun";const subtitle = clamp(pick(q.subtitle, "Snippets that ship. No servers, no cold starts."),92);const kicker = clamp(pick(q.kicker, "SSR / OG IMAGE"), 28).toUpperCase();const badge = clamp(pick(q.badge, "quik.run/r/…"), 32);const light = pick(q.theme, "").toLowerCase() === "light";// ---------- Canvas ----------const W = 1200;const H = 630;const PAD = 84;// ---------- Palette ----------const P = light? {BG0: "#f7f7f4",BG1: "#ffffff",SURFACE: "#ffffff",HAIRLINE: "#e4e4de",TEXT: "#111214",MUTED: "#6b6f76",INK0: "#0b0b0c",INK1: "#33363c",ACCENT: "#c8e400",ONACC: "#0b0b0c",DOT: "#0b0b0c",}: {BG0: "#0e0f12",BG1: "#0b0b0c",SURFACE: "#111214",HAIRLINE: "#23252a",TEXT: "#eaeaea",MUTED: "#6b6f76",INK0: "#ffffff",INK1: "#cbced4",ACCENT: "#E6FF55",ONACC: "#0b0b0c",DOT: "#6b6f76",};const SANS ="system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif";const MONO = "ui-monospace, 'SF Mono', Menlo, Consolas, monospace";// ---------- Vertical anchors ----------const subtitleBaseline = H - PAD - 18;const lastTitleBaseline = subtitleBaseline - 84;const HEADER_FLOOR = 176; // title block must clear the wordmark rowconst maxTitleWidth = W - PAD * 2 - 24;// ---------- Fit the title: pick the largest tier that fits W and H ----------const tiers = [116, 104, 92, 80, 66];let titleSize = tiers[tiers.length - 1];let titleLines = [title];let titleLead = Math.round(titleSize * 1.04);let firstTitleBaseline = lastTitleBaseline;let kickerY = HEADER_FLOOR;for (let t = 0; t < tiers.length; t++) {const size = tiers[t];// 800-weight sans averages ~0.60 of the em across mixed case.const perChar = size * 0.6;const lines = wrap(title, maxTitleWidth, perChar).slice(0, 3);const lead = Math.round(size * 1.04);const first = lastTitleBaseline - (lines.length - 1) * lead;const ky = first - size - 30;const widest = Math.max(...lines.map((l) => l.length * perChar));const fitsW = widest <= maxTitleWidth;const fitsH = ky - 14 >= HEADER_FLOOR;if ((fitsW && fitsH) || t === tiers.length - 1) {titleSize = size;titleLines = lines;titleLead = lead;firstTitleBaseline = first;kickerY = ky;break;}}const titleTspans = titleLines.map((line, i) =>`<tspan x="${PAD}" y="${Math.round(firstTitleBaseline + i * titleLead)}">${esc(line)}</tspan>`).join("");// Highlighter underline under the last title line (brand signature).const lastLine = titleLines[titleLines.length - 1] || "";const underlineW = Math.min(maxTitleWidth,Math.max(88, Math.round(lastLine.length * titleSize * 0.6 * 0.42)));const underlineY = Math.round(lastTitleBaseline + titleSize * 0.22);// ---------- Masked dot grid, top-right only ----------let dots = "";const step = 40;for (let y = step; y < H * 0.62; y += step) {for (let x = Math.round(W * 0.46); x < W; x += step) {dots += `<circle cx="${x}" cy="${y}" r="1.5"/>`;}}const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${W}" height="${H}" viewBox="0 0 ${W} ${H}" preserveAspectRatio="xMidYMid meet" role="img" aria-label="${esc(title)}"><defs><linearGradient id="bg" x1="0" y1="0" x2="0.4" y2="1"><stop offset="0%" stop-color="${P.BG0}"/><stop offset="100%" stop-color="${P.BG1}"/></linearGradient><radialGradient id="glow" cx="85%" cy="12%" r="70%"><stop offset="0%" stop-color="${P.ACCENT}" stop-opacity="${light ? 0.22 : 0.2}"/><stop offset="42%" stop-color="${P.ACCENT}" stop-opacity="0.05"/><stop offset="100%" stop-color="${P.ACCENT}" stop-opacity="0"/></radialGradient><linearGradient id="ink" x1="0" y1="0" x2="0.55" y2="1"><stop offset="0%" stop-color="${P.INK0}"/><stop offset="100%" stop-color="${P.INK1}"/></linearGradient><linearGradient id="accentBar" x1="0" y1="0" x2="1" y2="0"><stop offset="0%" stop-color="${P.ACCENT}" stop-opacity="0.95"/><stop offset="100%" stop-color="${P.ACCENT}" stop-opacity="0.35"/></linearGradient><radialGradient id="dotFade" cx="82%" cy="14%" r="60%"><stop offset="0%" stop-color="#ffffff" stop-opacity="1"/><stop offset="100%" stop-color="#ffffff" stop-opacity="0"/></radialGradient><mask id="dotMask"><rect width="${W}" height="${H}" fill="url(#dotFade)"/></mask></defs><rect width="${W}" height="${H}" fill="url(#bg)"/><g fill="${P.DOT}" opacity="${light ? 0.16 : 0.28}" mask="url(#dotMask)">${dots}</g><rect width="${W}" height="${H}" fill="url(#glow)"/><!-- Hairline frame + corner ticks --><rect x="24.5" y="24.5" width="${W - 49}" height="${H - 49}" rx="30" fill="none" stroke="${P.HAIRLINE}" stroke-width="1"/><g stroke="${P.ACCENT}" stroke-width="2" stroke-linecap="round" opacity="0.9"><path d="M24.5 58 L24.5 42 Q24.5 24.5 42 24.5 L58 24.5"/><path d="M${W - 58} ${H - 24.5} L${W - 42} ${H - 24.5} Q${W - 24.5} ${H - 24.5} ${W - 24.5} ${H - 42} L${W - 24.5} ${H - 58}"/></g><!-- Wordmark --><g transform="translate(${PAD}, ${PAD - 8})"><rect x="0" y="0" width="56" height="56" rx="16" fill="${P.ACCENT}"/><rect x="4.5" y="4.5" width="47" height="47" rx="12" fill="none" stroke="#0b0b0c" stroke-opacity="0.12" stroke-width="1"/><text x="28" y="41" text-anchor="middle" font-family="${MONO}" font-size="35" font-weight="700" fill="${P.ONACC}">q.</text><text x="76" y="26" font-family="${MONO}" font-size="24" font-weight="600" letter-spacing="0.02em" fill="${P.TEXT}">QuikRun</text><text x="76" y="48" font-family="${MONO}" font-size="12.5" font-weight="500" letter-spacing="0.28em" fill="${P.MUTED}">EDGE SNIPPETS</text></g><!-- Kicker --><g transform="translate(${PAD}, ${Math.round(kickerY)})"><rect x="0" y="-10" width="34" height="6" rx="3" fill="url(#accentBar)"/><text x="48" y="-3" font-family="${MONO}" font-size="15" font-weight="600" letter-spacing="0.26em" fill="${P.ACCENT}">${esc(kicker)}</text></g><!-- Title --><text font-family="${SANS}" font-size="${titleSize}" font-weight="800" letter-spacing="-0.028em" fill="url(#ink)">${titleTspans}</text><rect x="${PAD}" y="${underlineY}" width="${underlineW}" height="7" rx="3.5" fill="${P.ACCENT}" opacity="0.92"/><!-- Subtitle --><text x="${PAD}" y="${subtitleBaseline}" font-family="${SANS}" font-size="26" font-weight="400" letter-spacing="-0.005em" fill="${P.MUTED}">${esc(subtitle)}</text><!-- Status pill --><g transform="translate(${W - PAD - pillW(badge)}, ${subtitleBaseline - 32})"><rect x="0" y="0" width="${pillW(badge)}" height="46" rx="23" fill="${P.SURFACE}" stroke="${P.HAIRLINE}" stroke-width="1"/><circle cx="28" cy="23" r="4.5" fill="${P.ACCENT}"/><circle cx="28" cy="23" r="8" fill="none" stroke="${P.ACCENT}" stroke-opacity="0.35" stroke-width="1.5"/><text x="46" y="29" font-family="${MONO}" font-size="17" font-weight="500" font-variant-numeric="tabular-nums" fill="${P.TEXT}">${esc(badge)}</text></g></svg>`;return new Response(svg, {status: 200,headers: {"content-type": "image/svg+xml; charset=utf-8","cache-control": "public, max-age=3600, s-maxage=86400",},});// ---------------- helpers ----------------function esc(s) {return String(s).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");}function clamp(s, n) {s = String(s).replace(/\s+/g, " ").trim();return s.length > n ? s.slice(0, n - 1).trimEnd() + "…" : s;}// Approximate pill width from label length (mono ~10.2px/char at 17px).function pillW(label) {return Math.max(210, Math.min(360, Math.round(72 + label.length * 10.2)));}// Greedy word wrap with a hard-break fallback for over-long single words.function wrap(text, maxWidth, perChar) {const maxChars = Math.max(1, Math.floor(maxWidth / perChar));const lines = [];let line = "";for (let word of String(text).split(/\s+/)) {// Hard-break words that cannot fit on a line by themselves.while (word.length > maxChars) {if (line) {lines.push(line);line = "";}lines.push(word.slice(0, maxChars - 1) + "‐");word = word.slice(maxChars - 1);}const test = line ? line + " " + word : word;if (test.length > maxChars && line) {lines.push(line);line = word;} else {line = test;}}if (line) lines.push(line);return lines.length ? lines : [""];}}
Fork this and make it yours
Describe a change in plain English and QuikRun deploys it to your own URL.