Moving a Webflow site to Next.js is not a one-click file conversion. It is a controlled migration of five connected systems: routes, content, visual styles, browser behavior, and production services. Treat it as a redesign and you may lose working forms, indexed URLs, or analytics. Treat it as a systems migration and you can preserve the site people already use while gaining a conventional React codebase.
This guide explains the work in the order it should happen. It also separates what a converter can automate from what still needs a product decision.
Start with the real reason for moving
Write down the outcome before choosing a tool. Common goals include:
- owning the source code in a Git repository;
- adding application logic that is awkward in a visual builder;
- using a React component system across marketing and product pages;
- deploying through an existing Vercel or Cloudflare account;
- integrating a different CMS, authentication provider, or form backend;
- letting an engineering team review every change.
The migration is successful when those goals are met and the existing site still works. Pixel similarity alone is not a useful acceptance test.
Know what Webflow export does and does not contain
Webflow's native code export can provide HTML, CSS, JavaScript, and assets on eligible Workspace plans. Its own documentation says that CMS data and functionality, user accounts, ecommerce, localized content, site search, password protection, and form processing are not included as working systems. Exported Collection pages can also be empty. Read the current Webflow code export documentation before planning the cutover.
That distinction matters because a page can look complete in a screenshot while missing its operational dependencies.
| Webflow concern | What may transfer visually | What must be rebuilt or verified |
|---|---|---|
| Static pages | Layout, copy, images, CSS | Routes, metadata, responsive behavior |
| Interactions | Generated scripts and attributes | Timing, triggers, reduced-motion behavior |
| Forms | Form markup | Submission endpoint, spam controls, success/error states |
| CMS | Collection templates | Data source, queries, slugs, pagination, previews |
| Ecommerce | Product presentation | Cart, checkout, tax, inventory, webhooks |
| Search | Search interface | Index and search service |
| Localization | Primary-locale markup | Locale routing, alternate URLs, translated content |
Do this inventory before estimating the work. A five-page brochure site and a five-page shell backed by 2,000 CMS entries are different projects.
Step 1: create a migration inventory
Crawl the public site and record every URL that can be reached by users or search engines. Include URLs from the XML sitemap, navigation, CMS collections, search results, campaign links, and analytics landing-page reports.
For each route, record:
- current URL;
- intended Next.js URL;
- page type: static, CMS, utility, or transactional;
- title, description, canonical, and index status;
- form, script, embed, or third-party dependency;
- owner and acceptance status.
Do not restrict the list to pages visible in the main navigation. Old campaign pages often continue receiving backlinks and conversions.
Step 2: choose the rendering model per route
Next.js does not require every route to render the same way. Decide based on the page's data and update frequency:
- Static generation fits marketing pages and documentation that change only when you deploy.
- Dynamic rendering fits personalized or request-dependent pages.
- Revalidation fits CMS content that should update without rebuilding the entire site.
- Client-side fetching fits interactions that genuinely depend on the visitor, but it should not be the default for essential page copy.
This decision affects caching, preview behavior, hosting cost, and what a crawler receives in the first response. Document it instead of letting the converter make an accidental global choice.
Step 3: rebuild routes before polishing components
Create the route tree first. In the App Router, a directory represents a route segment and page.tsx provides the page. Dynamic CMS paths normally use a segment such as [slug].
The first checkpoint is deliberately plain: every old URL should return one of three intentional responses.
200with the correct page;- a permanent redirect to its closest replacement;
404or410because the content has no replacement.
Avoid redirecting every missing URL to the homepage. It hides gaps during testing and gives visitors an unrelated destination.
Step 4: preserve the visual system, not the generated clutter
A direct export often contains class names and wrappers optimized for the builder's runtime. A maintainable Next.js result should identify repeated design decisions:
- typography scale and font files;
- spacing rhythm;
- colors and semantic tokens;
- container widths;
- breakpoints;
- buttons, cards, navigation, footers, and form controls.
Start by preserving appearance. Refactor repeated sections into components only after screenshots match. Refactoring too early makes it harder to tell whether a mismatch came from extraction or abstraction.
Keep global styles small. Page-specific exceptions should stay close to the component that owns them. If imported CSS is required temporarily, label it as migration code so it does not quietly become the permanent architecture.
Step 5: handle assets and fonts explicitly
Download assets into a controlled location or configure the external image hosts you intend to keep. Check:
- image dimensions and aspect ratios;
- SVG view boxes and embedded colors;
- poster images for videos;
- font weights actually used on the page;
- file-name collisions;
- absolute asset URLs embedded in CSS;
- lazy loading below the fold.
Self-hosted fonts remove a runtime dependency, but their licenses must allow it. When fonts change, compare line wrapping—not just the font family—because a small metrics difference can shift every section below a heading.
Step 6: replace forms as a complete workflow
A form is not finished when the fields render. Define:
- the server endpoint;
- validation on both client and server;
- rate limiting or bot protection;
- where submissions are stored or forwarded;
- the reply-to and notification behavior;
- loading, success, duplicate, and failure states;
- privacy and consent copy;
- observability for failed deliveries.
Submit test data in production before changing DNS. Use a synthetic address that your team can identify and delete.
Step 7: migrate CMS content with stable identifiers
Pick the destination CMS or data source before writing the template route. Preserve each item's original slug unless there is a documented reason to change it. Keep a mapping from the Webflow item ID to the destination ID; titles are not reliable identifiers.
Run the content migration twice: once as a dry run and once for the cutover. A good importer is idempotent, reports validation errors per item, and can resume without creating duplicates.
Pay special attention to rich text. Embedded assets, heading levels, internal links, tables, and code blocks often need transformation rather than plain copying.
Step 8: reproduce metadata page by page
Next.js supports static metadata, dynamic generateMetadata, and file conventions for items such as robots.txt, sitemaps, icons, and Open Graph images. The official Next.js metadata guide explains how these produce the corresponding head elements.
For every indexable route, verify:
- one descriptive title;
- one useful meta description;
- the intended canonical URL;
- an index/follow decision;
- Open Graph title, description, and image;
- appropriate structured data that matches visible content;
- inclusion in the XML sitemap.
Do not globally copy the homepage metadata onto every route. It makes distinct pages look identical to search engines and link previews.
Step 9: build the redirect map before DNS changes
When paths change, create one-to-one permanent redirects from old URLs to the most relevant new URLs. Google recommends permanent server-side redirects for site moves and advises avoiding redirect chains. Its site migration documentation also recommends updating internal links, canonicals, and sitemaps.
Next.js can define redirects in configuration. Its current documentation explains that the permanent option uses a method-preserving 308 response; see the Next.js redirect guide.
Test the final destination, not only the first response:
curl -I https://example.com/old-path
curl -IL https://example.com/old-path
The first command shows the redirect status and Location. The second reveals chains and the final response.
Step 10: test behavior at realistic viewport sizes
Compare the old and new sites on narrow mobile, wide mobile, tablet, laptop, and a large desktop. Test the states that static screenshots miss:
- navigation open and closed;
- keyboard focus;
- hover and touch behavior;
- sliders at their first and last item;
- forms with valid and invalid input;
- reduced-motion preference;
- long CMS titles and missing optional images;
- a slow network and disabled third-party scripts.
Run accessibility checks, but also navigate the page with only a keyboard. Automated tools cannot decide whether the focus order makes sense.
Step 11: rehearse the cutover
Deploy the new site to a production-like preview and connect a temporary hostname. Run the entire checklist there. Lower DNS TTL in advance if your provider and change window make that useful.
At cutover:
- freeze Webflow content changes or record the final delta;
- run the final content import;
- deploy the exact reviewed commit;
- change DNS or the production domain assignment;
- verify SSL, the homepage, top landing pages, forms, and redirects;
- submit the new sitemap in Search Console;
- monitor errors, conversions, and indexed pages.
Keep the old environment available during the rollback window. A rollback plan should state who can trigger it and which conditions justify it.
Definition of done
A Webflow-to-Next.js migration is complete when:
- every known URL has an intentional response;
- visual checks pass across breakpoints;
- forms and integrations succeed in production;
- CMS records and slugs are reconciled;
- titles, canonicals, structured data, robots rules, and sitemap entries are correct;
- analytics receives expected events without double-counting;
- performance and accessibility have been tested on representative pages;
- redirects have no loops or unnecessary chains;
- the team can build, deploy, and roll back from documented instructions.
That is more work than exporting markup, but it is also what turns a visual copy into a production site your team can operate.