band website

Client

4Watty

Role

Fullstack — content migration, data model, frontend and deployment.

Year

2026

Stack

Next.js 16, React 19, Payload CMS 3, PostgreSQL, TypeScript, Tailwind CSS v4, S3, Python, Docker

Next.js 16React 19Payload CMS 3PostgreSQLTypeScriptTailwind CSS v4S3PythonDocker

Project

4Watty is an East-Bohemian rock band. Its website offers gigs and tickets, news, photo galleries, the band line-up, a playlist and a booking contact. The old WordPress site was ageing and the band wanted something easy to manage that would not lose years of content.

I carried over the whole archive. Python extractors read the WordPress XML export and the NextGEN galleries, importers fill Payload CMS and a backfill restores the legacy paths. A redirect generator from the old WordPress URLs made sure the site did not lose discoverability. News that never existed on the old site I backfilled by importing Facebook posts, through two paths, API and scraping.

The Payload data model knows concerts (upcoming and past are derived from the date, with ticket links), galleries with a grid driven by tile spans, the band line-up, tracks with audio and news. Homepage sections are async server components reading through the Payload Local API, so there is no extra network hop between the CMS and the site.

Media is stored on S3 with an automatic fallback to local disk. Need to move off WordPress without losing content or SEO? That is my job.

4Watty — screenshot 1
4Watty — screenshot 2
4Watty — screenshot 3
4Watty — screenshot 4

Technology

The site is built on Next.js 16 with Turbopack, React 19 and strict TypeScript. Payload CMS 3 with PostgreSQL through Drizzle holds the content, Tailwind CSS v4 and shadcn/ui the interface. Media goes to S3 (Hetzner Object Storage), the migration scripts are Python, Sentry tracks errors and deployment runs in Docker and GitHub Actions.

What I built

WordPress migration — Python extractors for the WordPress XML export and NextGEN galleries, followed by CMS importers and a legacy-path backfill.

A redirect generator from the old WordPress URLs so the band kept its discoverability through the migration.

Facebook post import through two paths — API and scraping — to backfill news that never existed on the old site.

The CMS data model — concerts split automatically into upcoming and past, galleries with a tile-span-driven grid, band members, tracks with audio, news, and hero, about and contact globals.

Homepage sections as async server components reading straight through the Local API with caching helpers — no extra network hop between the CMS and the site.

S3 media storage with an automatic fallback to local disk until the credentials are filled in.

Czech date formatting, cookie consent, a form builder for booking enquiries, an SEO plugin, Sentry, and seed scripts for content and navigation.

Let's talk about your project!