PortfolioCase Study

Team Project — Next.js 15 + Sanity CMS

Subud World Association

2026

A website rebuild for the Subud World Association — an international spiritual organisation active in 54+ countries. The original WordPress site was migrated to a headless CMS architecture using Next.js 15 and Sanity. I worked as part of a team, contributing to several pages. This was my first time working with a headless CMS, a monorepo setup, and real-time visual editing.

Team ProjectHeadless CMSWordPress Migration
Subud World Association

Subud World Association website — rebuilt from WordPress to Next.js 15 + Sanity for live content editing.

Technical Implementation

Frontend

  • Next.js 15 with App Router
  • React Server Components
  • TypeScript
  • Tailwind CSS
  • Incremental Static Revalidation

CMS & Content

  • Sanity v5 headless CMS (first time)
  • Sanity Studio for content editing
  • Real-time Visual Editing (Presentation Tool)
  • Live Content API
  • GROQ query language

Tooling & Architecture

  • pnpm monorepo with workspaces
  • Separate site and studio packages
  • On-demand publishing (no rebuilds)
  • Team collaboration via Git
  • Migrated from WordPress

Key Features

Headless CMS

All content — pages, news, organisational structure — is managed through Sanity Studio by editors without touching code.

Real-time Visual Editing

Sanity's Presentation Tool lets editors preview changes live, overlaid directly on the site, before publishing.

On-Demand Publishing

Content goes live instantly via Incremental Static Revalidation — no rebuild or redeployment needed.

Structured Content Schemas

Custom Sanity schemas model the organisation's content: pages, news posts, people, resources, and global settings.

Monorepo Architecture

Site and Studio are separate pnpm workspace packages — developed and deployed independently but coordinated from a single repo.

WordPress Migration

Content and structure were migrated from an existing WordPress site, preserving the organisation's information architecture.

Development Process

First Headless CMS Project

This was my first time working with a headless CMS. The concept of content as structured data — separate from the presentation layer — was completely new. I had to learn Sanity's data model, GROQ query language, and how the Studio connects to the Next.js frontend.

New Concepts I Learned

GROQ: Sanity's query language for fetching typed, structured content from the dataset.

Content schemas: defining document types in TypeScript that become editable fields in the Studio.

Draft vs published: how Sanity handles live previews of unpublished changes via the Presentation Tool.

Working in a Team on a Real Client Site

The project was built collaboratively — multiple developers working on different sections of the site simultaneously. I contributed to specific pages while teammates handled others. Coordinating on shared schemas and components required communication before writing code.

Team Workflow

Agreed on schema shapes early to avoid conflicts in shared content types.

Used Git branches for page-level feature work and reviewed each other's changes.

Non-technical editors could update content independently via Sanity Studio.

Monorepo Setup with pnpm Workspaces

The project used a pnpm monorepo — a new pattern for me. Managing two packages (Next.js site + Sanity Studio) from one repo, running both dev servers in parallel, and understanding how the workspace structure works were all part of the learning.

Monorepo Structure

site/ — Next.js 15 frontend, fetches content from Sanity via GROQ.

studio/ — Sanity Studio, deployed separately as the content editing interface.

Single `pnpm dev` command runs both servers in parallel via `--parallel` flag.

Challenges & Solutions

Learning GROQ from Scratch

Challenge: GROQ is Sanity's own query language with its own syntax — joins, projections, filtering, and references all work differently to SQL or REST.

Solution: Used Sanity's Vision tool in the Studio to write and test queries live against the dataset before integrating them into the Next.js pages.

Configuring Visual Editing

Challenge: Sanity's Presentation Tool requires coordinated setup on both the Next.js side (draft mode route, live URL) and the Studio side.

Solution: Followed the Sanity documentation step by step, tested the overlay system end to end, and iterated until live previews worked correctly.

Contributing to an Existing Team Codebase

Challenge: Joining a codebase mid-build meant understanding existing conventions and schema decisions before making changes.

Solution: Read the existing schemas and components first, aligned with teammates on patterns, and kept my contributions focused on agreed-upon pages.

Planned Enhancements

Internationalisation

Subud is active in 54+ countries — multi-language content support in Sanity would make the site accessible to the full global membership.

Member Portal

An authenticated section for Subud members to access internal resources and announcements not visible to the public.

Event Management

A structured events content type for world congresses and zone-level gatherings, with calendar integration.