Website · Subscription raffles

Mi Primer PremioPublic website for a monthly subscription raffle platform

A static Astro site for a monthly raffle platform: plans read from the API at build time, a direct path into the app and structured data.

Technologies

  • Astro 7
  • React 19
  • TypeScript
  • WebGL (GLSL)
  • lucide-react
  • sharp
  • JSON-LD
  • Google Analytics 4
  • Microsoft Clarity
  • Docker + nginx
  • Railway
Mi Primer Premio home page, with La Vecina celebrating and the announcement of four raffles every month
  • 4

    plans read from the API

  • 5

    URLs in the sitemap

  • 4

    entity types in the JSON-LD

  • 5

    animated WebGL backgrounds

My role

Development of the public website at Azirgo SAS: home page, legal pages, structured data, analytics and deployment.

The problem

The raffle platform runs in its own app, with its own API and sign-in. What it lacked was the front door: a site that explains in seconds how the four monthly raffles work, shows the plans at the same price the app charges and takes people straight to subscribing with the plan already chosen, without prices and copy drifting out of sync every time the business changes a plan.

What I built

  • A single-page home with a banner slider, community, this month's raffles, plans, how it works, winners, FAQ and a closing call to join the WhatsApp group.
  • A plans section that reads the platform's four plans from its API at build time, with the price, the raffles included and the monthly equivalent calculated in whole cents.
  • A “Choose plan” button that opens the app's sign-in with that plan already selected.
  • Four standalone, indexable pages: terms and conditions, raffle rules (with the month's prize table), privacy policy and contact.
  • Structured data in a single @graph: Organization, WebSite, a Product with its Offer for each plan and an online Event for each raffle.
  • Animated WebGL backgrounds - five variants: smoke, aurora, fog, beams and vapour - and a shower of coins over the raffles section.
  • GA4 and Microsoft Clarity analytics loaded once the page has finished loading, and a sitemap.xml generated from the list of real routes.
  • A Docker image that builds the site and serves it with nginx, with long caching for the versioned files.

How it's structured

A static-output Astro site, with the home page as a React island. Everything that repeats lives in shared data modules, so the header, the footer, the legal pages and the JSON-LD all read from the same source.

  • Routes: / (home), /bases-del-sorteo/, /terminos/, /privacidad/, /contacto/ and /sitemap.xml.
  • Home: slider, community, this month's raffles, plans, prize banner, how it works, winners, FAQ and the WhatsApp call to action, reachable through anchors from the header.
  • planes.ts: requests the plans from the platform API at build time, orders them from shortest to longest and attaches the site's own copy and image to each.
  • sorteos.ts: a single list feeds the home page cards, the JSON-LD Events and the prize table in the raffle rules.
  • marca.ts and enlaces.ts: brand details, the app link and navigation, shared by the React components and the Astro pages.
  • Handoff to the app: “Subscribe now” opens the app and “Choose plan” opens its sign-in with the plan's id.
  • Deployment: a Docker build stage on Node and an nginx runtime that serves dist/ with immutable caching for hashed bundles, one month for images and no caching for the HTML.

A very visual home page that still loads fast

The home page is built on large illustrations and animated backgrounds, so every heavy piece has its own rule to keep it from slowing down the first screen.

  • The first slider image is preloaded with high priority, in its desktop or mobile version depending on screen width.
  • The 19 original PNG images are converted to WebP with sharp by a script, with a weight ceiling per file.
  • GA4 and Clarity set up their queues as soon as the HTML is read, but their scripts are requested when the browser is idle after load, or earlier if the visitor interacts.
  • The WebGL backgrounds pause off screen and drop resolution and frame rate on modest devices.
  • The HTML is not cached, so every deploy shows up immediately, while hashed bundles are cached for a year.

Inside the site

  • Mi Primer Premio: The four plans, with prices read from the platform API
    The four plans, with prices read from the platform API.
  • Mi Primer Premio: This month's raffles over an animated WebGL background
    This month's raffles over an animated WebGL background.

Technical decisions

  • Astro with static output and the home page as a React island: the HTML comes out of the build complete - copy, prices and JSON-LD - and React only takes over afterwards for the slider, the FAQ and the animated backgrounds.
  • Plans are requested from the API during the build rather than in the browser, so prices arrive already written into the HTML. If the API fails, the site falls back to the backup plans instead of breaking the deploy.
  • Each plan is matched to its design by subscription type, not by name or slug: the API has plans whose slug says “annual” and that bill monthly.
  • In the JSON-LD each Offer carries the number of months it covers, so $15.99 every six months is not indexed as a monthly price, and the declared price is exactly the one on the card.
  • Whatever the business has not confirmed yet is not invented: empty fields are left out of the schema and, on the pages, show a visible pending marker instead of passing as real data.
  • Published images carry the version in their filename, because nginx serves them with a one-month cache: new artwork gets a new URL instead of waiting for the cache to expire.

Challenges

  • Keeping five WebGL backgrounds smooth on modest phones: they render at half resolution (a third on devices with few cores or little memory), at 30 or 20 frames per second, only while the section is on screen and never when reduced motion is on.
  • Publishing illustrations with the lettering painted into the image without WebP eating the letters: a 100 KB ceiling per file, with separate allowances for the lettered banners and the vertical artwork.
  • Placing a transparent header over the slider without the logo covering the headline on 320 px screens: the extra space is added by the script that generates the WebP files, stretching the edge of the artwork, without touching the originals.

Result

The site is live: home page, plans with the prices from the API, raffle rules and legal pages, all static and served by nginx, with the plan and raffle structured data crawlable and GA4 and Clarity analytics running.

Need something like this?

Tell me what you're building and I'll come back with scope, stack and a realistic timeline.