Site Stack
The actual architecture behind this website: app shell, CMS, analytics, API routes, delivery controls, and the shared visual system.
What powers this website?
sandiutomo.com runs on Next.js App Router, Sanity for structured content, Supabase for Core Web Vitals history, Umami and server-side GTM for analytics, and Vercel for hosting, cron, cache, and edge controls.
How the site is wired
High-level public-site architecture. DNS, repository workflow, secrets, CI, vendor internals, and deeper observability paths are intentionally left outside this diagram.
Tools by operating area
App shellThe rendering layer, route system, and visual foundation users touch first.4
- Next.js 16App Router. Server and client components, route-level layouts, API routes, and cron.
- React 18Client islands for interactive surfaces: nav, dashboards, vinyl, music state.
- Tailwind CSS 4 + PostCSSUtility layer. Route CSS files handle layout-specific overrides.
- Geist + Geist Pixel SquareType system. Pixel Square used on side routes for the operating-console register.
Why Next.js App Router
Route layouts, server components, metadata, and API routes match the site shape without extra framework glue.
- Trade-off
- Client-side motion and dashboards still need careful island boundaries to protect first render.
- Used for
- all public routes and API endpoints
Content & dataStructured editorial content and lightweight performance history storage.2
- Sanity CMSHeadless CMS powering /now and /uses with live data and static fallbacks.
- Supabase (PostgreSQL)Stores daily Core Web Vitals snapshots for the /insights dashboard.
Why Sanity CMS
Structured content keeps /now and /uses editable without turning every update into a code deploy.
- Trade-off
- Adds a hosted CMS dependency, so the app keeps static fallbacks for important public pages.
- Used for
- /now, /uses, and future editorial surfaces
Why Supabase
PostgreSQL is enough for daily Core Web Vitals history, cron snapshots, and lightweight dashboard queries.
- Trade-off
- It is intentionally not the source of truth for long-form content or analytics events.
- Used for
- /insights Core Web Vitals history
AnalyticsTraffic quality, Core Web Vitals, event routing, and measurement experiments.6
- Google Tag Manager Server-SideServer-side tagging endpoint for routing browser events through a controlled first-party measurement layer.
- StapeManaged server-side GTM hosting used for the tagging server container.
- GA4 · Mixpanel · Amplitude · PostHog · ClarityLoaded via GTM Web Container; events forwarded through sGTM for server-side distribution.
- UmamiLoaded directly (not through GTM) for independent privacy-first analytics.
- Google PageSpeed InsightsDaily Lighthouse + CrUX field data via Vercel cron. Desktop and mobile strategies.
- Vercel Speed InsightsReal-user Core Web Vitals collected at the edge.
Why Umami
Privacy-friendly analytics gives public traffic context without the weight and tracking posture of larger suites.
- Trade-off
- It is best for directional traffic quality, not deep product analytics or identity-level journeys.
- Used for
- /insights traffic, referrers, source grouping, and top pages
Why GTM Server-Side + Stape + GA4
Server-side tagging keeps browser instrumentation lighter and gives more control over enrichment, consent handling, and vendor delivery.
- Trade-off
- It adds a tagging-server dependency and requires stricter QA because event mapping can fail away from the browser.
- Used for
- first-party event collection and GA4 delivery
Why PageSpeed + Supabase
PageSpeed gives lab and field Core Web Vitals signals, while Supabase keeps daily snapshots for the public trend view.
- Trade-off
- The dashboard is only as current as the cron run and does not replace deeper RUM debugging.
- Used for
- /insights Core Web Vitals dashboard
IntegrationsExternal sources that keep public pages live without duplicating records.3
- Discogs APILoads the live vinyl record collection on /music.
- Last.fm APIPulls the currently playing or last played track for the music card.
- GitHub GraphQL APIFetches contribution calendar and activity for /works.
Why Discogs API
Discogs is the canonical source for the vinyl collection, so /music can show real records instead of duplicated data.
- Trade-off
- The page needs fallbacks because third-party APIs can rate-limit, fail, or return slowly.
- Used for
- /music collection panels
ExperimentationSmall controlled tests that should never block first render.1
- StatsigFeature gates and hero CTA A/B experiments. Initialized at idle time to protect first render.
Delivery & securityHosting, cache behavior, scheduled jobs, edge controls, and public safety rails.3
- VercelHosting, preview deployments, cron jobs, immutable asset caching, and edge network.
- Content Security PolicyStrict CSP via vercel.json covering script, connect, font, image, frame, and worker sources.
- Next.js ProxyIP-based analytics block applied before the app renders.
Why Vercel
The site needs fast static delivery, preview deployments, cron jobs, and simple edge controls in one place.
- Trade-off
- Platform primitives are convenient, but deeper workloads should stay portable behind API boundaries.
- Used for
- hosting, previews, cron, headers, and proxy rules