Private media delivery — draft images stay gated until you publish
Uploads now return canonical /api/media paths instead of world-readable Supabase URLs. Aveiro signs at read time for live visitors, gated draft previews, and social platform fetch — unpublishing or deleting an asset revokes access.
Site and org media no longer rely on world-readable Supabase URLs. Content stores canonical /api/media paths; Aveiro signs them at read time so draft images stay private, unpublishing revokes visitor access, and social platforms fetch through revocable share grants.
What changed
Previously, every upload returned a Supabase public URL and that absolute link was persisted into MDX, settings, ads, and social drafts. Anyone holding the URL could fetch the bytes — including images on sites that were never published.Media now flows through /api/media/<key> with authorization carried in the URL:
Published pages sign media for visitors while the site is live; unpublish revokes standing access.
Draft previews sign only for org members who already have site access — otherwise references stay bare and resolve to 404.
Social publishing mints a per-asset share grant so Instagram, LinkedIn, and similar platforms can fetch server-side without a session; deleting the file revokes the grant.
Stored values stay unsigned so one reference works for visitors on a custom domain and for members in the editor. Legacy Supabase URLs in older content are still recognised — no migration required.
For agents and API callers
Upload responses (POST …/media/upload, social direct upload) now return a canonical publicUrl like /api/media/site-media/{siteId}/…. Persist that path in <Media src> or page metadata — not the signed displayUrl from list responses.Details: Site media API, Social media API. Dashboard behaviour: Media library.
Also in this release
Email campaigns rewrite media to absolute share-grant URLs at send time. Stored HTML keeps canonical /api/media paths; inbox fetches never rely on a browser session.
Campaign previews use session cookies on bare paths instead — the iframe is on our origin and cannot sign HTML composed on the client.
Site settings and collection listings now sign logo, favicon, default OG cover, and folder thumbnails on read.
Dashboard editor and settings sign page MDX, metadata, site settings, and site-list covers on read so images no longer break in the editor; saves canonicalize grants back to bare paths before storing.
Newsletter editor and social thumbnails use the same read-sign / write-canonicalize round-trip — member-facing surfaces that still stored bare /api/media paths.
API and form validators accept canonical /api/media paths alongside https:// URLs, so attaching a library image to a social post no longer fails with "Invalid url".
Member preview URLs quantize expiry windows so media-library thumbnails cache correctly in next/image.
Template gallery sites — visitor media access is gated by whether your site is still published, not by who uploaded the file. Cloning copies MDX and settings verbatim, including /api/media/… paths that may still point at the template source; those images load on your live site and stop when you unpublish.
Template gallery thumbnails — the marketplace, site wizard, and template submit panel sign thumbnail URLs on read (next/image refetches without cookies). Approved template submissions count as live for media delivery even when the source site is unpublished or in coming-soon mode; thumbnail writes canonicalize signed round-trips.
Dashboard home and showcase gallery — Recent Sites cover thumbnails and public showcase cards sign on read with member or visitor grants; showcase covers stay root-relative on the platform origin.
Shop product images — attach from the media library (canonical /api/media paths, not only https:// URLs) and sign on every read: product editor hydration, live product pages, the Products block, and Product Showcase blocks grounded on the site being viewed (visitor grant on a published site; member grant in draft preview).
Product page MDX — visitors get the published snapshot (unpublished edits no longer leak to the storefront); <Media> and <Carousel> in the MDX body sign on read.
Draft preview default OG image — the site-wide social cover in Settings → SEO resolves in the editor preview head.
Slug change in Settings → Site — the editor URL stays on the site id; saving a new preview slug refreshes in place instead of navigating to a broken path.
Frametic failed renders can be dismissed per browser; the assets grid reserves placeholder slots so finished renders do not jump the layout on load.
Assets expand preview — the Studio → Assets enlarge dialog now renders signed display URLs like grid tiles, so full-size previews no longer show a broken image.
AI generation results — image generation and completed video jobs return signed member URLs for immediate preview in the composer; persisted content still canonicalizes on save.
Dashboard home post thumbnails — top Instagram and Threads rows sign social asset thumbnails on read.
AI video reference images — library picks are resolved to short-lived Supabase signed URLs the provider can fetch before a job starts;
Campaign block marker — canonicalize-on-save and sign-on-read now reach the base64 block marker at the top of campaign HTML, not just the rendered body. Image blocks no longer 404 one by one as stored grants expire; welcome emails use the same round trip. missing references fail before credits are reserved.