Skip to content
Glossia Documentación
⌘K
Español
English Deutsch Español Français 日本語 한국어 Português (Brasil) 简体中文
Iniciar sesión
⌘K
esc

Social images

Daily dashboard previews, browser rendering, storage, and traffic limits.

Dashboard pages advertise a 1200 × 630 image through Open Graph and Twitter large-image metadata. Public projects include their name, section, and uploaded logo. Public accounts receive a section-specific preview. Private accounts and personal settings use generic Glossia branding.

Image identity and lifetime

The image digest includes the displayed content, project logo revision, template, styles, fonts, brand asset, dependency lockfile, and current day in Coordinated Universal Time. Changing any of these creates a new address. Sorting the attributes and signing at midnight keeps the complete address stable throughout the day.

The signed payload cannot be changed by a visitor. It is valid for two days, but only the current day's payload may generate a missing image. Yesterday's stored images remain readable. Query parameters never become object-store keys.

Successful images are persisted under og/images/<digest>.jpg in the configured Amazon Simple Storage Service-compatible bucket. Only an explicit missing-object response starts generation. Storage failures return an uncacheable temporary failure, without starting Chrome. An upload must succeed before a newly rendered image is served.

Rendering and limits

Rendering uses Carta with BrowseChrome, the same stack as Tuist's image renderer. The supervised pool contains two browsers. Each render has a 15-second deadline; each application instance permits at most twelve new renders per minute. Stored-image requests do not consume that allowance.

Cachex combines concurrent requests for the same image and retains up to 100 images for five minutes. A nonblocking PostgreSQL advisory lock prevents different application replicas from rendering the same image simultaneously. Other replicas receive a temporary failure and can retry once the object exists.

The template pairs a Noora section badge with Glossia's warm background, serif heading, gradient accent, and understated footer. Source Serif 4 and Inter are bundled locally so previews do not depend on a font service. Fonts and raster logos are embedded. The document's content security policy blocks scripts and external resources. Logos are loaded only from the application's avatar storage prefix and are limited to five million bytes, matching project uploads.

Response behavior

Result Status Cache behavior
Stored or newly persisted image 200 Public, one day, immutable
Invalid, expired, or altered signature 404 No storage
Yesterday's image missing from storage 404 No storage
Browser busy, render failure, or storage unavailable 503 No storage; retry after 60 seconds
Origin request allowance exceeded 429 No storage; retry interval in response

The origin permits thirty requests per minute per client address, including invalid requests.

Cloudflare

The social-images-rate-limit.yaml resource in the infrastructure repository matches GET and HEAD requests under /og/, including verified crawlers. It permits twenty requests per ten seconds per client address and Cloudflare location. Exceeding the limit blocks requests for ten seconds. The general public-page challenge rules exclude this path so image crawlers never need to solve a browser challenge.

Cloudflare's default cache behavior caches .jpg responses and honors origin cache headers. Keep the signed query string in the default cache key. Do not apply an overriding cache duration that caches error responses or ignores no-store. The deterministic signature avoids one cache entry per page request.

Deploy the infrastructure resource alongside the application. Ensure the origin is reachable only through the trusted ingress, since forwarded client addresses are trusted by the existing request limiter. The browser pool and render budget also bound distributed misses and direct-origin requests.

Local configuration

Set GLOSSIA_OG_IMAGES=true to enable the browser pool in development. Install Google Chrome or Chromium, build assets with mix assets.build, and configure the existing object-storage environment variables:

  • GLOSSIA_S3_ACCESS_KEY_ID
  • GLOSSIA_S3_SECRET_ACCESS_KEY
  • GLOSSIA_S3_ENDPOINT
  • GLOSSIA_S3_REGION
  • GLOSSIA_S3_BUCKET

Run mix ecto.setup and mix phx.server. With storage configured, seeds give the public dev/glossia project a logo. Inspect the og:image metadata on a dashboard page to get its signed image address.