ogee: link previews for single-page apps, drawn at the edge
Every page gets its own title, description and a preview card in your brand, on WhatsApp, X, LinkedIn, Slack, iMessage, Discord, Google and AI search.
ogee (oh-jee): OG at the edge. Also the S-shaped curve on old arches.
npx @virusdev/ogee check https://your-site.com/some-pageThe problem
Apps built with React, Vue, Svelte or Vite, and anything made with Lovable, Bolt or v0, send the same index.html for every URL. The bots behind link previews and AI search don't run JavaScript, so they only ever see that one file. Share /pricing, /blog/my-post or /products/42 and they all show your home page's preview, or nothing at all.
The fix
ogee sits in front of your site, as a Cloudflare Worker, a fetch handler on any server or edge runtime, or a build step for any static host. For every page it:
- Writes the right <head>: Title, description, canonical URL, Open Graph and Twitter tags, and JSON-LD.
- Draws a preview card: In your colors, fonts and logo, with the page's own picture when it has one. In milliseconds, then cached.
- Serves sitemap.xml and llms.txt: For search engines and AI tools.
- Gives crawlers words: Optionally writes the page's text into the HTML, so crawlers see words, not an empty <div id="root">.
You don't change your app's code. If anything goes wrong, the page is served exactly as before.
Quick start
Set up
npx @virusdev/ogee init https://your-site.comOpens your site in a headless browser and reads your colors (shadcn and Tailwind tokens too), fonts, logo and pages with their real headlines. It works out where you're hosted and sets ogee up to match.
Look at your cards
npx @virusdev/ogee renderDraws every card into .ogee/cards/, with a gallery page to look at.
Put them live
npx @virusdev/ogee deployWith the Worker. On Vercel, Netlify or GitHub Pages, add ogee build after your app's build instead: vite build && npx @virusdev/ogee build dist
Built for coding agents
ogee doesn't ask for an AI API key. The coding agent you already use is the designer: ogee collects the evidence and renders whatever the agent writes, and the agent looks at the result and fixes it.
Run `npx @virusdev/ogee inspect --for-agent` and make our link previews look great.
inspect saves screenshots of your site on desktop and phone, the brand values it found, the cards as they look now, and an AGENT.md with the whole workflow. Every command takes --json.
npx @virusdev/ogee skillCards
Four built-in templates, colored by your brand: minimal, glow, split and bold. Or write your own: a template is a function that returns HTML.
import { esc, fitTitle, type Template } from "@virusdev/ogee";
export const brand: Template = (card) => `
<div style="display:flex;align-items:flex-end;width:100%;height:100%;
padding:72px;background:${card.colors.background}">
<div style="font-size:${fitTitle(card.title)}px;color:${card.colors.foreground}">
${esc(card.title)}
</div>
</div>`;- No headless browser: Cards are drawn by takumi, as WebAssembly in the Worker and in Node for ogee build: flexbox, gradients, blur, blend modes, masks, SVG filters and custom fonts.
- The page's own picture: Give a page an image and the built-in templates frame it beside the title: tall frames for flyers and phone screens, wide ones for photos and screenshots.
- Plates for the rest: Designs the renderer can't draw (WebGL, backdrop-filter, layered photography) become a plate, rendered once with a real browser. The text is still drawn per page on top.
- Never a missing glyph: init adds a tiny fallback font with currency signs like ₵ ₦ € £ and letters like ɛ ɔ ŋ, plus anything else your site uses.
Where it runs
Already behind Cloudflare
ogee runs on a route in front of your site. Nothing else changes.
npx @virusdev/ogee deployAlready on Workers
Let ogee read pages from the same Worker that serves your static assets. virusofficial.dev, and this page, run exactly this way.
createWorker(config, { fetchOrigin: (req, env) => env.ASSETS.fetch(req) })Any static host
Netlify, Vercel, GitHub Pages, Cloudflare Pages, S3: ogee build writes each page's HTML, its card, sitemap.xml and llms.txt into your build folder.
vite build && npx @virusdev/ogee build distAny server or edge runtime
Node, Bun, Deno, Hono, Vercel or Netlify edge functions: the same behavior as a plain (Request) => Response handler.
createHandler(config, { origin: "http://localhost:4173" })On Lovable, Bolt or another host you can't add a build step to: put your domain on Cloudflare, point it at the Worker, and pass --origin to init.
FAQ
Why not just use Next.js or Astro?
If you can, server rendering solves this too. ogee is for the many apps that are already single-page apps, and for people who don't control the framework.
Does it slow my site down?
Barely. The page and its route lookup are fetched at the same time, and the <head> is rewritten as the HTML streams through. Fixed routes add nothing; a route that calls your API is cached for 5 minutes and capped at 3 seconds.
What if my API is down?
The page is served unchanged after 3 seconds at most. ogee never breaks a page.
Does every visitor get the rewritten HTML?
Yes, people and bots alike: it's the same app with a better <head>, which is what search engines expect.
Can I see what a page will say?
npx @virusdev/ogee meta /pricing prints its tags.
Can I trust what's on npm?
Every version is built and published by GitHub Actions from a tagged commit, never from a laptop. The Provenance section on the npm page links to the exact commit; check it with npm audit signatures.
Commands
- ogee check <url>: Grade a link's preview and explain what's wrong
- ogee init <url>: Set up: brand, logo, fonts, pages, and how it runs for your host
- ogee inspect --for-agent: Screenshots and brand data for a coding agent
- ogee render [paths…]: Draw cards into .ogee/cards/, with a gallery
- ogee plate <file.html>: Render a background image with a real browser
- ogee meta <path>: Print the tags for one page
- ogee build [dir]: Write every page's HTML, card, sitemap and llms.txt into a built site
- ogee dev: Run the Worker locally in front of your live site
- ogee deploy: Deploy with wrangler
- ogee skill: Install the Claude Code skill