Most tutorials focus on fetching WordPress posts into Next.js via the REST API. This covers maybe 20% of the migration. The critical 80% that determines if your organic traffic survives involves URLs, redirects, metadata, sitemaps, and image handling. Neglect these, and your impressions will crater weeks after launch, even if the migration appears successful on the surface. This guide provides a comprehensive checklist for migrating from WordPress to Next.js, specifically targeting the App Router. It's designed to preserve your SEO, regardless of your new backend – be it headless WordPress, another headless CMS, or static files.

The One Rule That Saves Rankings

Every decision during a migration boils down to a single, non-negotiable principle:

Nothing about how Google already sees your pages should change, except the parts you deliberately improve.

This means replicating your existing URL structure, metadata, and sitemap faithfully. Any deviation is a risk you must consciously accept and mitigate.

URL Structure: The Bedrock of Your SEO

Your URL structure is not just an address; it's a signal to search engines about your content hierarchy and a familiar path for users. Changing it is the fastest way to break your SEO.

Replicate Existing URLs

Your new Next.js application must serve content at the exact same URLs your WordPress site used. If your WordPress site has `/blog/my-awesome-post/`, your Next.js app must also serve content from `/blog/my-awesome-post/`. This typically means configuring your Next.js routing to match your WordPress permalink structure. For example, if your WordPress permalinks are set to 'Post name', your Next.js `app/page.js` or dynamic routes must mirror this. If you are using a headless WordPress setup, the WP REST API will likely provide slugs that you can use to construct these URLs. Ensure the API response includes the full slug and any necessary parent slugs (like `/blog/` if your posts are in that category).

Handling URL Changes Deliberately

If a URL *must* change (e.g., consolidating content, renaming a section), you are obligated to implement permanent redirects (301 redirects) from the old URL to the new one. This is not optional. Next.js's `next.config.js` file provides a `redirects` function for this purpose. You'll need to maintain a comprehensive list of old URLs and their corresponding new URLs. For a large site, this list can be extensive. ```javascript // next.config.js async function redirects() { return [ // Example: If /old-post-slug/ is now /new-post-slug/ { source: '/old-post-slug/', destination: '/new-post-slug/', permanent: true }, // Example: If /category/old-category/ is now /topics/new-category/ { source: '/category/old-category/', destination: '/topics/new-category/', permanent: true }, // ... more redirects ] } module.exports = { // ... other Next.js config async redirects } ``` This mapping should ideally be generated from your WordPress site *before* the migration, perhaps by exporting a list of all your post and page URLs along with their permalinks.

Metadata: The Hidden SEO Signals

Beyond the visible content, WordPress handles crucial SEO metadata: meta titles, meta descriptions, canonical tags, Open Graph tags for social sharing, and schema markup.

Meta Titles and Descriptions

These are critical for click-through rates from search results. Your Next.js application must dynamically generate these for each page, mirroring the content from WordPress. If you're using headless WordPress, fetch these fields from the WordPress REST API alongside your post content. In Next.js App Router, you can set metadata using the `metadata` object in your page or layout files. For dynamic content, you'll fetch this data and return it. ```javascript // app/blog/[slug]/page.js async function getPostData(slug) { // Fetch data from your headless CMS (e.g., WordPress REST API) const res = await fetch(`https://your-wp-api.com/posts?slug=${slug}`); const post = await res.json(); return post; } export async function generateMetadata({ params }) { const post = await getPostData(params.slug); return { title: post.meta_title || post.title.rendered, description: post.meta_description || post.excerpt.rendered, // ... other metadata like openGraph, twitter, etc. }; } export default async function PostPage({ params }) { const post = await getPostData(params.slug); return (

{post.title.rendered}

); } ```

Canonical Tags

Canonical tags tell search engines which is the master version of a page when duplicate content exists. Ensure your Next.js app correctly implements canonical tags, pointing to the primary URL for each piece of content.

Open Graph and Twitter Cards

These control how your content appears when shared on social media. Fetch and include the relevant image URLs, titles, and descriptions from your headless CMS.

Schema Markup

Structured data (like JSON-LD) helps search engines understand your content better. If your WordPress site used schema markup (e.g., for articles, products, events), replicate this in your Next.js app. Again, fetch this data from your CMS or construct it based on the content type.

Sitemaps: Guiding Search Engine Crawlers

A sitemap is crucial for search engines to discover all your content. WordPress plugins like Yoast SEO or Rank Math generate these automatically. Your Next.js application needs to generate a dynamic sitemap. The Next.js App Router supports generating sitemaps directly. You can create a `sitemap.ts` or `sitemap.xml/route.ts` file in your `app` directory. ```typescript // app/sitemap.ts import { MetadataRoute } from 'next'; async function getAllPosts() { // Fetch all post slugs/URLs from your headless CMS const res = await fetch('https://your-wp-api.com/posts?_fields=slug,modified'); const posts = await res.json(); return posts; } export default async function sitemap(): Promise { const posts = await getAllPosts(); const postEntries = posts.map((post) => ({ url: `https://your-domain.com/blog/${post.slug}`, lastModified: new Date(post.modified), changeFrequency: 'weekly' as const, priority: 0.7, })); // Add other routes like pages, index, etc. const routes = [ { url: 'https://your-domain.com', lastModified: new Date(), changeFrequency: 'daily', priority: 1.0 }, { url: 'https://your-domain.com/about', lastModified: new Date(), changeFrequency: 'monthly', priority: 0.8 }, // ... add all static pages ]; return [...routes, ...postEntries]; } ``` Ensure your sitemap includes all important URLs: posts, pages, categories, tags, and any other indexable content. Regularly update it to reflect new content and changes.

Image Optimization: Performance and SEO

WordPress often handles image optimization through plugins. Next.js has built-in image optimization capabilities with the `next/image` component.

Replicate Image Sources

Ensure your new application can still access your existing image assets. If using headless WordPress, images are typically served from the same WP media library. Configure `next/image` to point to your WordPress media URL.

The "So What?" Perspective

Developer Impact

Developers must meticulously replicate WordPress's URL structure in Next.js App Router routes. Implement 301 redirects for any changed URLs using `next.config.js`. Fetch and dynamically set meta titles, descriptions, canonicals, OG tags, and schema markup from your headless CMS using `generateMetadata` or page component data fetching. Configure `next/image` to optimize existing WordPress media assets.

Security Analysis

This migration doesn't introduce new direct security vulnerabilities but relies on secure API connections to headless WordPress or other CMS. Ensure API keys are managed securely and that data fetching prevents injection attacks. The primary security consideration is maintaining the integrity of redirects and metadata to prevent SEO poisoning or phishing attempts masquerading as legitimate site changes.

Founders Take

Preserving SEO is paramount for maintaining organic traffic and customer acquisition channels during a site migration. A botched migration can lead to significant revenue loss. Prioritize a detailed audit of existing URLs, metadata, and redirects. Allocate resources for meticulous implementation and testing of these elements in Next.js to protect your domain authority and search rankings.

Creators Insights

Creators need to ensure that their content's discoverability isn't harmed. This means replicating post URLs, ensuring meta descriptions and titles appear correctly in search results, and that social sharing previews (Open Graph tags) function as before. If your content relies on specific schema markup for rich results, ensure that is also transferred to the new Next.js site.

Data Science Perspective

For data professionals, the migration involves ensuring that the data fetching layer in Next.js accurately mirrors WordPress's content structure and metadata. This includes fetching custom fields and SEO-specific data like meta titles/descriptions from the WordPress REST API. The key is to maintain data consistency and integrity for all SEO-critical fields to prevent data loss or misinterpretation by search engines.

Sources synthesised

Share this article