You built a site in Next.js. It looks great. The client wants WordPress. These two platforms solve different problems, and you can't just rename files. But if your Next.js site is deployed to a public URL, you can get a working WordPress theme out of it in under 60 seconds.
Why Next.js sites end up needing WordPress
Next.js is a React framework. It's built for developers. The people who end up maintaining a site after launch are usually not developers. That gap is why this situation comes up so often.
- Client content editing. There's no built-in CMS in Next.js. You need a headless CMS (Contentful, Sanity, Prismic) or you write your own admin. WordPress gives clients a familiar editing interface without any setup work.
- Plugin ecosystem. WooCommerce, contact forms, SEO plugins, booking systems — these are WordPress-native. Replicating them in a headless Next.js setup takes significant development work.
- Hosting handoff. Many clients don't want to manage a Vercel or AWS account. They're on a shared WordPress host already. Moving the site there simplifies the handoff.
- Design is done, CMS isn't. Sometimes you build a Next.js site as a design prototype and the client decides they need WordPress's editing capabilities after seeing it. The design is solid. The platform isn't what they want.
Why you can't just copy Next.js files to WordPress
Next.js generates React components. WordPress is PHP. They don't share a runtime, a template format, or a build system.
A Next.js page is a .tsx file that exports a React component. WordPress expects a .php file that outputs HTML directly. There's no automatic translation between the two.
Additionally, Next.js bundles its own JavaScript runtime (React, React DOM, the Next.js client) into your deployed site. That runtime is what makes your pages work. WordPress doesn't include or know about any of that.
The exception is the rendered output. When Next.js serves a page, it sends HTML to the browser. That HTML is standard. The browser doesn't care how it was generated. The HTML a Next.js server produces looks the same as HTML a PHP server produces from the browser's perspective. That rendered output is what you can work with.
Three approaches
Rebuild in WordPress manually
Recreate your Next.js design in WordPress PHP templates. Write header.php, front-page.php, functions.php. Translate each React component to HTML in PHP template files. Re-implement your CSS.
Time: 20-60 hours. You're rewriting every component. If you used styled-components, CSS Modules, or Tailwind, you need to decide how to handle styles in PHP templates. Every section needs to be rebuilt. This is a complete recreation of the work, not a migration.
Next.js static export + manual assembly
Next.js has a static export option. Add output: 'export' to your next.config.js and run npm run build. Next.js generates plain HTML files into an out directory.
Those HTML files are your starting point. From there, you need to convert them into WordPress templates by adding PHP functions (wp_head(), wp_footer(), body_class(), the loop), structuring a valid theme folder, and wiring up the template hierarchy.
Time: 4-12 hours. This is the most reliable manual path. You get clean HTML to work with instead of React components. But you still need to know WordPress theme structure and you'll spend time on the PHP integration work.
Caveat: not all Next.js sites can export statically. If you use getServerSideProps, dynamic API routes, or server-side authentication, those pages won't export to static HTML. You'll get build errors. App Router sites with server components have additional constraints.
URL capture via StaticToWP
If your Next.js site is deployed to any public URL, you can convert it in about 60 seconds. StaticToWP renders your deployed page in a real browser, captures the fully computed HTML and CSS, bundles all assets, and generates a complete WordPress theme zip.
This approach bypasses the React-to-PHP problem entirely. The browser handles React. By the time the page is rendered, all React components have been converted to standard HTML elements. The capture happens at that point. The WordPress theme contains standard HTML, not React components.
This is the same method that works for Framer to WordPress, v0, Lovable and Bolt to WordPress, and any other tool that deploys to a URL.
What the rendered Next.js output looks like
Next.js does server-side rendering by default (Pages Router) or React Server Components (App Router). Either way, the HTML that reaches the browser is standard. It includes your layout, your components' rendered output, and all the metadata Next.js added.
Next.js also injects hydration scripts — JavaScript that connects the server-rendered HTML back to React in the browser. In a WordPress context, you don't need those scripts. The HTML stands on its own. StaticToWP strips Next.js-specific hydration scripts and keeps the HTML and CSS that make the page look correct.
Step-by-step: Next.js to WordPress
- Deploy your Next.js site to a public URL. Vercel is the obvious choice. Netlify works too. Any host that serves your Next.js app publicly works. If you're on localhost, deploy a preview build first.
- Paste the URL into StaticToWP. Go to StaticToWP and enter your Next.js site URL. The tool loads the page in a headless browser and captures the fully rendered output.
- Download the theme zip. You get a
wp-theme.zipcontaining WordPress template files, your CSS (inlined and bundled), and any local assets. - Upload to WordPress. Go to Appearance → Themes → Add New → Upload Theme, upload the zip, and activate it.
- Set your homepage. In Settings → Reading, set "Your homepage displays" to "A static page" and select your front page.
- Verify the result. Your Next.js design should render in WordPress with typography, layout, and styles intact.
What transfers and what doesn't
What transfers cleanly
- Layout and typography. All CSS renders in the browser before capture. Font sizes, line heights, spacing, colors — everything that CSS controls transfers.
- CSS Modules and styled-components. Both generate scoped class names and inject CSS into the page. By the time the browser renders the page, those styles are standard CSS. They transfer as-is.
- Tailwind CSS. If your Next.js site uses Tailwind, see the Tailwind to WordPress guide for specifics. Short version: it works.
- Google Fonts and self-hosted fonts. Font URLs carry over. Fonts bundled with your Next.js app get included in the theme's assets folder.
- CSS animations and keyframes. All keyframe animations are CSS. They transfer and play in WordPress without React.
- Responsive layouts. Media queries are standard CSS. Your Next.js breakpoints work in WordPress unchanged.
- Static images. Images from
/publicare bundled into the theme. External image URLs (from a CMS or CDN) remain as references in the HTML.
What needs work after migration
- React state and interactivity. Any component that uses
useState,useReducer, or React context for UI state won't carry its behavior over. The initial rendered HTML transfers, but click handlers, toggle states, and conditional rendering based on client state need to be rebuilt with vanilla JavaScript or simple scripts. - Next.js API routes. Your
/apiroutes don't exist in WordPress. Any frontend code calling those routes needs to be repointed to a WordPress equivalent. For contact forms, use WPForms or Gravity Forms. For custom data, use WordPress's REST API with a custom plugin. - Dynamic routes.
/blog/[slug]in Next.js becomes WordPress's post template system. For a blog, WordPress handles this automatically. For custom post types, you need to set up the WordPress taxonomy structure. - Image optimization. Next.js's
next/imagecomponent handles lazy loading and format conversion server-side. In WordPress, the images render as standard<img>tags. Add a caching plugin and an image optimization plugin to recover that performance. - Server components and streaming. App Router server components render to HTML before reaching the client. That HTML transfers fine. But server-side data fetching (database queries, authenticated API calls) stops working. You need WordPress equivalents for any data that was fetched server-side.
- Middleware and auth. Any Next.js middleware or authentication logic doesn't transfer. Use WordPress plugins (WooCommerce, WP Members, Simple Membership) for equivalent functionality.
The headless alternative
Some teams want to keep Next.js as the frontend and use WordPress only as the CMS. This is called headless WordPress. Your Next.js app fetches content from WordPress's REST API or GraphQL (via WPGraphQL) and renders it.
This is a legitimate approach but it's a different project. You keep Next.js running on Vercel, add WordPress on a separate host, and build API queries between them. It preserves the Next.js frontend but means maintaining two systems.
The URL capture approach is for teams that want a standard WordPress theme, not a headless setup. Both are valid. The right choice depends on whether the client needs to edit content in WordPress or just run it as a backend.
SEO when moving from Next.js to WordPress
Next.js handles SEO well with its metadata API or next-seo. When you move to WordPress, carry that work over.
- Match your URL structure. If Next.js used
/blog/post-nameslugs, keep the same structure in WordPress. Set permalink structure to "Post name" under Settings → Permalinks. - Set up 301 redirects. For any URLs that change, add 301 redirects. The Redirection plugin handles this cleanly.
- Re-enter meta titles and descriptions. Your Next.js
<title>and<meta name="description">tags are in the captured HTML, but they're static strings. Install Yoast SEO or Rank Math and re-enter them so WordPress manages them dynamically. - Submit your sitemap. WordPress generates an XML sitemap automatically (or via your SEO plugin). Submit it in Google Search Console. Remove the old Next.js sitemap URL if one was submitted previously.
FAQ
Does this work with Next.js App Router sites?
Yes. App Router generates standard HTML for the initial page render. The capture happens at the browser level, after the page has fully rendered. Whether your Next.js app uses the App Router or the Pages Router doesn't change what the browser receives.
My Next.js site fetches data from an external API. Will that data appear in WordPress?
It depends on when the fetch happens. If data is fetched server-side (during SSR or as a React Server Component), it's included in the initial HTML. The capture gets it. If data is fetched client-side after the page loads, the capture waits for the page to settle before taking the snapshot, so most client-side fetched content is included too.
I use TypeScript and have type-safe components. Does any of that help with the conversion?
No. TypeScript is a development tool. It compiles away before deployment. The deployed site is JavaScript and HTML. The capture operates on the HTML output, not the TypeScript source.
What about Next.js's built-in font optimization?
Next.js preloads fonts and inlines font-display CSS. By the time the page renders, those fonts are loaded. The capture includes the font CSS and font file references. In WordPress, the fonts load normally. They won't have Next.js's specific preload optimization, but they'll work correctly. Add a caching plugin to recover the performance difference.
Can I convert a Next.js site that's behind a login?
No. The URL needs to be publicly accessible without authentication. If your Next.js app has a public marketing page and a private dashboard, convert the public pages. The private dashboard needs to be rebuilt in WordPress using appropriate plugins.
Will the WordPress theme be fast?
The theme bundles CSS into a single file with no render-blocking external dependencies. JavaScript is served locally. Add W3 Total Cache or WP Super Cache for page-level caching, and a CDN for static assets. Core Web Vitals performance is comparable to a well-configured WordPress theme built from scratch.