Skip to content

Astro (SSR)

Use this with output: "server" and an adapter (Node, Cloudflare, etc.). Signing runs on each request (or inside a cached server handler) so you can use short exp and per-request variants without rebuilding the whole site.

This rendorix-web repo uses @astrojs/cloudflare—use Wrangler secrets and runtime env (see Wrangler configuration) for HMAC material when deployed to Cloudflare; nodejs_compat is already common for Node APIs on Workers.

Pattern 1 — sign in the .astro frontmatter (runs on the server per request):

---
import Layout from "../layouts/Layout.astro";
import { signRendorixUrl } from "../lib/rendorix/signUrl";
const cover = signRendorixUrl("/assets/hero.jpg", { p: "hero" });
---
<Layout>
<img src={cover} alt="" width="1200" height="630" />
</Layout>

Pattern 2 — API route — keep signing in one module and call it from src/pages/api/rx-url.ts (or the endpoint style your adapter uses) if the browser must fetch a fresh URL after load (unusual for images; more common for other client flows).

Use the same pattern as any src/pages/api/*.ts route: read runtime env or Cloudflare bindings, return JSON, and never expose secrets to the client.

  • Import signRendorixUrl only from server entrypoints (.astro frontmatter, src/pages/api/*, server actions).
  • Read RENDORIX_HMAC_SECRET from the adapter env (Cloudflare dashboard / Wrangler, or process.env on Node hosts).
  • Never pass the secret through define:vars or client scripts.
  • Pass src={signedUrl} on <img> or into your <picture> helpers.
  • For framework islands (React, Vue, etc.), pass the already signed string as a prop from the parent .astro page—the island must not sign itself.

Adapter and host notes (e.g. Cloudflare, Node)

Section titled “Adapter and host notes (e.g. Cloudflare, Node)”
HostNotes
Cloudflare Workers / Pages FunctionsCPU and wall-clock limits apply; keep signing cheap (HMAC only). Web Crypto may differ from Node crypto—test parity with your verifier.
Node (standalone server)import { createHmac } from "node:crypto" in signUrl.ts is typical.
DockerInject secrets at runtime; rotate without rebuilding the image when possible.
  • TTFB includes SSR work—signing is cheap; data fetching before sign may not be—profile the page.
  • HTML cacheability drops when responses vary per cookie; image URLs can still hit the CDN well if the same asset + preset repeats across users (SSR strategies).