Skip to content

Astro (static)

Use this when output: "static" (or pages are prerendered). The HMAC secret is only needed on the machine that runs astro build—usually CI, not developers’ laptops with prod keys.

src/
lib/
rendorix/
signUrl.ts # canonical + HMAC — server/build only
pages/
gallery/
[slug].astro # getStaticPaths + signed src per item
content/ # optional: MD with frontmatter asset keys
astro.config.mjs

Keep signing out of client: islands and out of public import.meta.env—only non-secret values like the image host may use PUBLIC_ prefixes.

  1. In GitHub Actions (or your CI), add RENDORIX_HMAC_SECRET and RENDORIX_BASE_URL as encrypted secrets.
  2. Export them before npm run build so Node can read process.env in signUrl.ts during the static build.
  3. Do not add the HMAC secret to Cloudflare Pages build env for a pure static site unless that build is trusted and scoped to non-prod as appropriate.

Local dev: use .env (gitignored) with a dev key and staging distribution, or mock URLs that skip signing if your local edge allows it (not for production testing).

Option A — frontmatter + helper (src/pages/post/[slug].astro). The snippet assumes a blog content collection; adapt getCollection to your own schema.

---
import { getCollection } from "astro:content";
import { signRendorixUrl } from "../../../lib/rendorix/signUrl";
export async function getStaticPaths() {
const posts = await getCollection("blog");
return posts.map((post) => ({
params: { slug: post.slug },
props: {
title: post.data.title,
heroSrc: signRendorixUrl(`/assets/${post.data.coverKey}`, {
p: "hero",
}),
},
}));
}
const { title, heroSrc } = Astro.props;
---
<article>
<h1>{title}</h1>
<img src={heroSrc} alt="" width="1200" height="630" loading="eager" />
</article>

Option B — Markdown / MDX — resolve coverKey in a layout that calls the same helper (keep the helper import on the server build side only).

Stability: the same logical image should map to the same URL string across builds if exp is fixed or derived from content version—otherwise you bust CDN cache unnecessarily (Caching).

Terminal window
# CI
export RENDORIX_BASE_URL="https://img.example.com"
export RENDORIX_HMAC_SECRET="" # from secrets store
npm run build
# Local preview of static output
npm run preview

astro preview serves the built HTML; image requests still go to real CloudFront—use staging credentials and short exp when testing.

  • Rotating images without rebuild: static HTML holds old signed links until you redeploy or use long exp + TTL policy.
  • Per-user images in static HTML is awkward—use Astro (SSR) or a small API the client calls for fresh URLs.