CASE STUDY
Web Development12 min read

How We Migrated Pomoco from Webflow to a Custom Next.js 16 Build — And What We Learned

DS

De Studio

Web Development Studio

July 24, 2026
12 min read

Webflow is an excellent starting point — but when a creative studio needs full control over interactions, content architecture, and performance, it hits a ceiling fast. Here is the complete technical story of how we rebuilt Pomoco's website from the ground up using Next.js 16, Sanity CMS, and Vercel — and the key decisions that made it work.

Why Webflow Was No Longer Enough

Webflow solves a real problem: it lets designers build production websites without writing code. For many projects, that is exactly the right trade-off. But for Pomoco — a creative storytelling studio with a distinctive visual identity and a team that publishes content regularly — Webflow's constraints had become friction.

The interaction model was limited. Custom animations and hover behaviours that felt native to Pomoco's brand required workarounds that were brittle and hard to maintain. The content editing experience, while functional, did not map cleanly to how the team actually thought about their pages. And performance, particularly on image-heavy work case studies, was harder to control than it should have been.

One of the most frustrating limitations was ordering. In Webflow CMS, there is no way to drag and drop CMS items to reorder them. If you want your work portfolio displayed in a specific sequence, you are stuck manipulating dates, numbers, or other workaround fields to force the order you want — and every reorder means editing multiple records manually. For a creative studio that constantly refreshes which projects appear first, this was a real operational problem.

The brief was clear: rebuild from scratch with a stack that gives the team full editorial control over every section of every page, lets them reorder content by simply dragging it, loads fast everywhere in the world, and stays maintainable without a developer in the loop for routine content updates.

The stack we chose: Next.js 16 with the App Router, Sanity CMS v5, and Vercel for deployment. Here is exactly how we built it and why every major decision was made.

Why Next.js 16 App Router

Next.js 16 with the App Router gives the best of both worlds — pages are statically generated at build time (SSG) and revalidated every 60 seconds (ISR). This means:

— First load is instant — served from Vercel's edge CDN across every region — Content stays fresh — Sanity updates reflect on the live site within 60 seconds without a full rebuild — No client-side fetching — all data is fetched on the server, so the user never sees a loading state for content

Every page has export const revalidate = 60, which tells Next.js to revalidate the static page in the background every 60 seconds after a request comes in. The user always gets a cached page — it is never slow — but the cache is never stale for more than a minute.

This is the right architecture for a content site where a non-technical team needs to see their changes live quickly, but where performance and SEO cannot be compromised to achieve it.

Why Sanity CMS — and How We Structured It

Sanity gives the team full editorial control without ever touching code. Every section of every page is editable from the Sanity Studio — text, images, ordering, links, everything. But getting Sanity to work well with Next.js ISR required several deliberate decisions.

useCdn: false We disabled Sanity's CDN layer entirely. The reason: when both Sanity's CDN cache and Next.js's ISR cache are active simultaneously, they stack on top of each other. A content update gets caught in Sanity's CDN cache first, then has to wait for Next.js ISR to revalidate as well — resulting in stale content that can take far longer than 60 seconds to surface on the live site. With useCdn: false, Sanity always returns fresh data from the API, and Next.js ISR is the single caching layer controlling freshness.

Singleton Documents Pages like About, Contact, Navbar, Footer, and Home Hero each use a fixed document _id in Sanity — so there is always exactly one document per page, never more. In GROQ, we filter singletons by _id:

*[_type == "aboutPage" && _id == "aboutPage"][0]

This prevents a common Sanity pitfall: if an editor accidentally creates a duplicate document, a query using only _type can return the wrong one. Filtering by _id makes the query deterministic.

We enforce this in Sanity Studio using the Structure Tool plugin, which removes the Create New button for singleton document types — so editors cannot create duplicates even accidentally.

Drag-and-Drop Ordering — The Feature Webflow Does Not Have This was one of the most impactful improvements for the team day-to-day. In Webflow CMS, there is no native drag-and-drop ordering for collection items. To control the display order of a portfolio or a list, teams are forced to use date fields, manual order numbers, or other workaround fields — and every reorder means editing multiple records one by one.

In Sanity, we integrated the @sanity/orderable-document-list plugin, which adds a drag handle to every work item in the Studio. The team simply drags items into the order they want. Under the hood, each item has an orderRank string field that the plugin manages automatically. The GROQ query sorts by orderRank asc — drag in Studio, see it reflected on the live site within 60 seconds. No number fields to update, no date manipulation, no developer required.

Page Architecture — What We Built and How

The site covers six primary sections, each with different content requirements.

Home A clean hero section with a CMS-controlled image or GIF and minimal navigation. The home page uses a custom background colour unique to that page — handled via a CSS custom property set in the page layout rather than a global theme, so it does not bleed into other pages.

Work Listing The work listing page has two notable interactions. First, a category filter — clicking a tag filters the visible work items in real time on the client side, with no page reload. Second, a hover image preview — hovering a category shows that category's representative image in a preview box. Both required careful implementation to avoid the flickering problem described below.

Work Detail Each work item is a statically generated page with a flexible content blocks system (covered in depth below), a hero with title, year, client, keywords, deliverables, and credits, and a related projects slider at the bottom.

About Ten fully CMS-driven sections including a hero, team grid, services list with hover interactions, collaborators section, client logo grid, and a call-to-action — each individually editable in Sanity Studio.

Playlists Curated music playlists displayed as cards with a modal for details. Each card links out to the relevant streaming platform.

Contact Address, business contact details, social links, and office and team photography — all CMS-driven, updated without touching code.

The Content Blocks System — Flexible Work Case Studies

The work detail page uses a flexible block-based content system, similar in concept to Gutenberg or Notion blocks. Each work item can have any combination of content blocks in any order the team chooses.

The block types available:

fullVideo — Full-width YouTube embed fullImageBlock — Single full-width image at natural height, no cropping dualImageFullBleed — Two equal images, edge to edge dualImageHorizontal — Two images with a gap inside the container threeImageHorizontal — Three equal images fourImageHorizontal — Four equal images multisizeImages — One tall image alongside two stacked images, togglable left/right imagesVertical5 — Five images side by side textTemplate — Two-column text layout with large/small size options workAbout — Heading and body paragraph comboBox1/2/3 — Composite layouts mixing images and text in distinct arrangements

Each block also has an optional spacing field (sm, default, lg) so the team can control the breathing room between sections without writing CSS.

This system gives the team the ability to art-direct each case study individually — choosing which layout blocks to use, in which order, with how much space — while keeping the underlying code clean and maintainable. Adding a new case study is entirely a content operation, not a development task.

Solving the Flickering Problem

The services section on the About page and the category hover preview on the Work listing page both involve swapping images on hover. This sounds simple but has a common failure mode that produces a bad user experience.

The naive implementation: change the src prop of an image component when the hovered item changes. The problem: React treats a change in src as a new image, unmounts the old one, and mounts the new one — causing a white flash while the new image loads, even if it was previously loaded and cached by the browser.

Our fix: pre-mount all images simultaneously at page load, positioned on top of each other, and toggle visibility using opacity-0 and opacity-100 via CSS transitions. No component is ever unmounted and remounted. The browser has all images in memory. The crossfade happens purely in CSS.

The result is a smooth, flicker-free image transition that works correctly even when the user hovers rapidly between different items. It requires slightly more DOM nodes on initial load, but the user experience improvement is significant and the performance cost is negligible for the number of images involved.

ISR Caching — The Biggest Technical Challenge

Getting Sanity content to reliably and quickly reflect on the live site was the most significant technical challenge of the project. On the surface, ISR seems straightforward — set revalidate: 60 and content updates within a minute. In practice, several layered caching issues made this harder.

Root cause 1: useCdn: true stacking with ISR Sanity's CDN has its own cache TTL. When Next.js ISR revalidates a page, it fetches fresh data from Sanity — but if Sanity's CDN is active, the 'fresh' data is actually Sanity's cached version, which may itself be stale. The fix: useCdn: false, so every fetch goes directly to Sanity's API and returns genuinely current data.

Root cause 2: Missing route-level revalidate Setting revalidate inside the sanityFetch() helper alone is not sufficient. Next.js requires export const revalidate = 60 to be set at the route or page file level as well. Without it, the page is treated as a static export with no revalidation scheduled.

Root cause 3: Duplicate documents in GROQ queries Sanity's content lifecycle includes draft and published states. If a GROQ query filters only by _type without filtering by _id for singletons, it can return a draft document instead of the published one — or return multiple results when only one is expected. Filtering singletons by both _type and _id makes every query deterministic regardless of draft state.

With all three issues resolved, the live site reflects every Sanity publish within 60 seconds, consistently. The team can update any section of any page and see it live within a minute — with no rebuild, no deployment, and no developer involvement.

The Result — Full Control, Fast Delivery, Zero Code Required

The rebuilt Pomoco website gives the team something Webflow never quite managed: complete editorial control over a site that performs at the standard of a hand-coded product.

Every section of every page is editable in Sanity Studio — text, images, ordering, links, spacing. Work case studies can be created, ordered, and published without writing a line of code. The content blocks system means each case study can be individually art-directed with different layout combinations. Content changes are live within 60 seconds.

Performance is significantly improved over the Webflow version — pages are served from Vercel's edge CDN, images are optimised by Next.js's built-in image pipeline, and there is no client-side data fetching adding latency after the initial page load.

The codebase is clean, maintainable, and well-structured. Adding new pages, new block types, or new sections follows established patterns. Future development work is fast because the architecture is coherent.

This is the case for migrating from Webflow to a custom Next.js build: not for every project, but for studios and businesses that have outgrown what a visual builder can provide and need a platform that matches their ambitions. At De Studio, this is exactly the kind of work we do — and Pomoco is one of our clearest examples of what that looks like in practice.

TagsWeb DevelopmentDesignDe Studio
Keep Reading

Related Posts

AUTOMATION
Automation

July 11, 2026

10 Business Tasks AI Can Now Fully Automate in 2026 — That Required a Full-Time Employee Last Year

Twelve months ago, these tasks sat on someone's job description. Today, AI handles them end-to-end — faster, more consistently, and around the clock. If your business is still paying people to do these things manually, you are funding your competitor's advantage.

Read Post
AUTOMATION
Automation

July 8, 2026

The 2026 Automation Market Shift: Why AI Agents Are Replacing Traditional Workflow Tools

Traditional no-code automation platforms built the first wave of business automation. In 2026, that wave is being replaced by something fundamentally different — AI agents that do not just trigger pre-defined actions but understand context, make decisions, and adapt to outcomes. Here is the full picture of the market shift, what is driving it, and what businesses need to do now.

Read Post
AUTOMATION
Automation

July 3, 2026

Autonomous Development Agents: How AI Is Writing, Testing & Deploying Web Code in 2026

AI development agents no longer just autocomplete lines of code — they write entire features, run test suites, fix failing tests autonomously, open pull requests, and trigger deployments. The developer's role is shifting from writing code to reviewing and directing the code that AI produces. Here is the complete picture of what autonomous development looks like in 2026 and what it means for every business that builds software.

Read Post
Let's Work Together

Ready To Transform Your Digital Presence

Let's build something remarkable together. Book a free discovery call and find out how we can help you design and develop a product your users will love.