Overview
Agency website for a media production company offering video production, live streaming, online conferences, KOL / PR campaigns, and event organization. Beyond the standard service-and-portfolio surface, the site has a server-side Google Analytics integration — using the GA4 Data API to pull real engagement metrics into the page itself instead of just feeding them to a dashboard.
What I built
Public agency site
- Service pages for video production, live streaming, online conferences, Zoom events, KOL / PR campaigns, and event organization
- Portfolio section with project showcases and an event-media gallery
- Blog and FAQ for inbound content marketing
- "Join with us" recruiting / partner page
- Heavy reveal-on-scroll motion via react-intersection-observer + Framer Motion
Server-side GA integration
- Used @google-analytics/data + googleapis to fetch GA4 metrics directly from the server
- Powers data-driven sections of the site (engagement, traffic patterns, portfolio reach) without exposing the GA frontend SDK
- Service-account auth means the credentials never touch the browser
Companion CMS
- Separate NMW CMS admin app for content authoring with SunEditor rich text
- Powers blog, portfolio, and service-page copy without redeploying
Tech stack
- Frontend: Next.js 15, React 19, Tailwind CSS v4
- UI primitives: Radix UI accordion / popover / select
- Animations: Framer Motion + react-intersection-observer for scroll-triggered reveals
- Carousels: Embla, Slick, react-snap-carousel
- Editor: SunEditor for the admin's rich-text authoring
- Analytics integration: @google-analytics/data + googleapis for server-side GA4 reads
- UX feedback: Sweetalert2 for confirmations
My role
Built the public agency site and the admin CMS that feeds it. The GA Data API integration was the most interesting piece — using analytics as content instead of just measurement. Configured the service-account auth, mapped the GA4 dimension / metric API onto the site's data needs, and added caching so the page didn't re-fetch on every render.
What I learned
Server-side GA integration is one of those features that sounds simple and turns out to be subtle. The GA Data API is quota-limited and slow, so calling it on every request is a non-starter — you need a server cache (or ISR) and a sensible TTL. I also learned that service-account auth on Vercel / Lambda means handling the credentials JSON as an env var instead of a file, and I built a small wrapper to normalize that across environments. The other lesson was that an agency site lives or dies on its portfolio loading speed — a media production company can't have its own showcases be slow.



