Migrating staffbase.com to Storyblok & Symfony
A full-stack migration of Staffbase's entire marketing website from WordPress to a headless CMS: the most complex, highest-stakes project of 8 years.
- PHP
- Symfony
- Storyblok
- Tailwind CSS
- Upsun
- Twig
- Varnish
Making the case
The migration didn’t start in 2024. It started in 2022, when I first flagged that WordPress was becoming a business risk.
The symptoms were already there: slow load times, unpredictable bugs, occasional outages, and development that got slower with every year of accumulated custom code. None of it was catastrophic. That was the problem. The site worked, we kept shipping what marketing asked for, and from the outside everything looked fine.
That’s what makes it hard to argue for replacing something that still functions. When a team reliably delivers, the cost of delivering becomes invisible. My manager at the time came from digital marketing rather than engineering, and the reasonable question from that side of the table was: it works, why change it?
So the argument had to change. Not “the codebase has problems” but “this will cost us money, and here is roughly when.” Not a technical complaint but a business risk: staffbase.com is the shop window and the first touchpoint for most prospects, and we were maintaining it in a permanently reactive mode, firefighting instead of building.
It took two years. A new CMO joined in 2023, and by then the symptoms had grown visible without needing a technical background: pages too slow to load, outages nobody could schedule around, and a development pace that couldn’t keep up with what marketing wanted to ship. The case I had been making finally matched what everyone else could see. The budget was approved.
The platform had served us well for years (I’d built a great deal of it by hand), but a monolithic CMS was no longer the right tool. Content management was developer-dependent. The codebase had accumulated years of custom code. And as Staffbase scaled, we needed something that could grow with us: a clear separation between content and presentation, self-service publishing for marketing, and a foundation built to last.
The answer was a headless architecture: Storyblok as the CMS, PHP/Symfony as the application layer, Twig for templating, and Tailwind CSS powering the entire frontend styling system. We partnered with SensioLabs, Symfony specialists, as the external engineering agency. Symfony at this depth was new territory for our team, and SensioLabs brought us up to speed on the framework while we worked side by side on implementation.
What I brought to that partnership wasn’t Symfony expertise, at least not at first. It was years of knowing staffbase.com’s actual content, its edge cases, and the ways the old system had quietly shaped how marketing worked. That context made me the natural bridge between SensioLabs’ framework expertise and what Staffbase actually needed from the new architecture: I made sure their recommendations landed correctly against our real content model and workflows, not just textbook Symfony patterns. The goal from the start was for the web team to come out the other side able to own and extend the Symfony application ourselves, with SensioLabs as a partner rather than a permanent dependency. By go-live, that’s where we were. We worked independently day to day, and called on SensioLabs only for the occasional edge case where their deeper framework knowledge filled a gap.
What we built
The scope was substantial. The migration covered the full staffbase.com estate: all product pages, and a lot of other content types. We launched with English (default), German, and Japanese. French and Spanish were added later, well after go-live. That was a good proof point that the new architecture made expanding to additional languages straightforward rather than a fresh engineering effort.


DNS (Route53 and Cloudflare, Terraform-managed) was already part of Staffbase’s standing infrastructure; for this migration, that meant adapting existing DNS settings for go-live rather than building that layer from scratch. What was new was the application hosting itself: Upsun for the Symfony application, and a VarnishCache layer in front of it for performance. That let the team focus its energy on the application layer and content migration, rather than also standing up DNS infrastructure from zero.
My role
Early on, my contribution was mostly making sure SensioLabs’ Symfony expertise stayed grounded in our reality: flagging where a textbook pattern would break against our actual content model, or where marketing’s workflow needed something the framework didn’t assume by default. As the project went on, I also contributed directly to implementation, and reviewed code across both the Staffbase team and SensioLabs’ work, though SensioLabs, as the framework experts, had merge authority on much of the more technical work themselves. We ran it as a genuinely agile, iterative collaboration: constant feedback loops, including on already-merged PRs, rather than a single gate of final sign-off.
Together with my manager, I helped manage the agency relationship: aligning on scope and approach, coordinating the GitHub repository structure (codeowners, branch strategy, CI/CD), and helping maintain the quality bar across releases. When the navigation needed to be fully rebuilt in late 2025 (a structural overhaul under a tight external deadline), I coordinated the implementation directly: reviewing code, giving implementation feedback, and signing off before it went live.

I also invested in making the editorial knowledge transfer stick. SensioLabs ran the initial Storyblok editorial workshops for the marketing team, covering page building, component usage, and how content publishing would change. I documented the workshops thoroughly in Confluence so the material could be reused, and followed up afterward with additional onboarding and enablement sessions for various marketing colleagues as they ramped up. The goal was for marketing to publish independently, without raising a ticket to the web team for every content change. That goal was met.
What made this hard
The complexity wasn’t in any single piece; it was in the accumulation. Multiple languages in production simultaneously, with more added later. A component library that needed cleaning up and streamlining from what existed, then rebuilding to be functionally solid on the new architecture. A VarnishCache layer that needed to be understood and configured correctly or you’d introduce subtle caching bugs that only appeared in production. Integrations with Iframely for rich embeds, CookieYes for consent management, and a range of marketing tools that all had opinions about how they were implemented.
The highest-stakes moment was go-live: switching primary domains on a live commercial website that generates significant demand for a B2B SaaS company. There was no tolerance for downtime, missed redirects, or broken tracking. The coordination required (across the web team, SensioLabs, marketing, and infrastructure) was among the most demanding of my 8 years at Staffbase.
The outcome
I led the migration from initial scoping in late 2024 through go-live in July 2025 and stabilization through the rest of the year, delivering a faster, more stable site with a far better editor experience than WordPress, a better developer experience for the team, and an architecture built to scale. Marketing self-publishes in Storyblok, and the number of web support tickets driven by content management, which had been significant, dropped materially. By go-live, the web team was running the Symfony application independently, calling on SensioLabs only for the rare edge case: proof that the knowledge transfer had actually worked, not just the migration itself. And the new setup proved its value quickly: adding French and Spanish after launch was straightforward, exactly as the architecture intended. It was also the first step in unifying Staffbase’s fragmented web properties onto one technical system.


What replaced 8 years of accumulated WordPress was built to last, with strong outside expertise and close collaboration.