{"id":24811,"date":"2026-10-14T16:37:47","date_gmt":"2026-10-14T14:37:47","guid":{"rendered":"https:\/\/pagepro.co\/blog\/?p=24811"},"modified":"2026-11-04T13:12:21","modified_gmt":"2026-11-04T12:12:21","slug":"seo-migration-from-drupal","status":"publish","type":"post","link":"https:\/\/pagepro.co\/blog\/seo-migration-from-drupal\/","title":{"rendered":"SEO Migration from Drupal"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\" id=\"what-this-means-for-your-team\">What this means for your team<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/pagepro.co\/blog\/replatform-your-website\/\">A Drupal migration is a rebuild<\/a>, and every rebuild carries SEO risk. The risk concentrates in three places: missing redirects, metadata lost in the content scripts, and staging settings left on at launch. Plan the SEO steps into the project from the start: the inventory and redirect map belong in the first sprint, and someone on your team should own Search Console for the first month after launch.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">On Pagepro&#8217;s Nexity process, the first four weeks deliver a production-ready foundation, with content migrated, redirects in place and editors trained; Drupal estates with many languages and integrations take longer, as the timeline section of the <a href=\"https:\/\/pagepro.co\/blog\/migration-from-drupal-to-headless-cms\/\">Drupal to headless CMS guide<\/a> shows.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/pagepro.co\/case-studies\/learn-squared\">Learn Squared<\/a>, the e-learning platform Pagepro moved off Drupal 7 to Next.js, described what the move did for its team.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">We&#8217;ve absolutely seen an increase in development velocity with the Pagepro team, through initial development and even into the initial weeks of our first SLA\u2026 the turnaround time from ideation to feature launch has been a marked improvement upon our previous development solution.<\/p>\n<cite>Andrew Hawryluk, Co-founder, Learn Squared<\/cite><\/blockquote>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"seo-migration-from-drupal-checklist\">SEO migration from Drupal checklist<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A <strong>Drupal SEO migration checklist<\/strong> keeps the SEO work in the right order while developers rebuild the site. Each step below has its own section. For choosing the target platform, the frontend stack and the project timeline, see the guide to <a href=\"https:\/\/pagepro.co\/blog\/migration-from-drupal-to-headless-cms\/\">migration from Drupal to a headless CMS<\/a>; this article covers how to keep your rankings through that move.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Benchmark:<\/strong> Record traffic, rankings, indexed pages and <a href=\"https:\/\/pagepro.co\/blog\/web-vitals-how-to-measure-and-improve-them\/\">Core Web Vitals<\/a> before anything changes.<\/li>\n\n\n\n<li><strong>Inventory:<\/strong> Export every URL, path alias, existing redirect, Metatag value and hreflang tag from Drupal.<\/li>\n\n\n\n<li><strong>Map content:<\/strong> Decide where each content type, field and taxonomy term lives on the new platform, including its SEO fields.<\/li>\n\n\n\n<li><strong>Map redirects:<\/strong> Pair every old URL with its new address in a redirect spreadsheet.<\/li>\n\n\n\n<li><strong>Migrate SEO data:<\/strong> Make the migration scripts carry titles, descriptions, canonicals, alt text and structured data.<\/li>\n\n\n\n<li><strong>Test staging:<\/strong> Crawl the staging site, test every redirect and check performance and accessibility.<\/li>\n\n\n\n<li><strong>Launch:<\/strong> Switch over, run smoke tests in the first 24 hours and submit the new sitemap.<\/li>\n\n\n\n<li><strong>Monitor:<\/strong> Review Search Console daily and fix errors as they appear.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Pagepro runs this checklist on Nexity, its own Next.js and Sanity framework for migrations, built from 20+ real projects with zero drops in Google rankings across all of them.<\/p>\n\n\n\n<div class=\"wp-block-code-mind-cta c-cta-block\" style=\"background-color:#00141F;color:#FFFFFF\"><div class=\"c-cta-block__content\"><p class=\"c-cta-block__title\">Don\u2019t let your migration tank your rankings.<\/p><div class=\"c-cta-block__action\"><a href=\"https:\/\/pagepro.co\/contact\" class=\"c-cta-block__button ga-cta ga-cta-consultation theme-bg-3\">Protect My Traffic<\/a><\/div><\/div><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"benchmark-traffic-and-rankings\">Benchmark traffic and rankings<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Before you move away from Drupal, record a baseline of organic traffic and keyword positions. You need to know exactly where your organic traffic comes from if you want to protect it, and with a pre-launch snapshot your team can spot a dip in days rather than months.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Top-performing pages:<\/strong> List every URL that drives high session volume and note its conversion rate, so you can review these pages first on staging and at launch.<\/li>\n\n\n\n<li><strong>High-ranking keywords:<\/strong> Log your current positions in a rank tracker, which makes it easier to trace visibility changes after the move.<\/li>\n\n\n\n<li><strong>Inbound backlinks:<\/strong> Document which Drupal URLs attract external links, so the redirect map protects that authority.<\/li>\n\n\n\n<li><strong>Indexed pages and Core Web Vitals:<\/strong> Note the number of indexed pages in Search Console and the current Core Web Vitals, so you can compare like for like after launch.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Without these benchmarks, diagnosing a post-migration traffic drop turns into guesswork.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"collect-urls-aliases-and-metadata-from-drupal\">Collect URLs, aliases and metadata from Drupal<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Crawl the existing Drupal site to list every indexable URL with its status code, canonical tag and metadata, then export the data Drupal holds behind those pages. A crawl alone misses part of the picture: it finds the aliases that are still linked, but not the <code>\/node\/<\/code> system paths, old redirects or pages nothing links to anymore.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Path aliases:<\/strong> Export every alias, including those <a href=\"https:\/\/www.drupal.org\/project\/pathauto\">Pathauto<\/a> generated from patterns, so each <code>\/node\/123<\/code> path is paired with the address visitors and search engines actually use.<\/li>\n\n\n\n<li><strong>Existing redirects:<\/strong> Export the entries stored by the <a href=\"https:\/\/www.drupal.org\/project\/redirect\">Redirect module<\/a>. Old redirects have to point to the new final addresses too, or they turn into chains after launch.<\/li>\n\n\n\n<li><strong>Metatag output:<\/strong> Record the titles, descriptions, canonical tags and Open Graph values the <a href=\"https:\/\/www.drupal.org\/project\/metatag\">Metatag module<\/a> renders for each content type, including the default patterns, not only the values editors typed.<\/li>\n\n\n\n<li><strong>Hreflang and language versions:<\/strong> On multilingual sites, export the language of every node and its translations, so the new platform can reproduce the same <a href=\"https:\/\/developers.google.com\/search\/docs\/specialty\/international\/localized-versions\">hreflang annotations<\/a>.<\/li>\n\n\n\n<li><strong>Structured data and image alt text:<\/strong> Extract schema.org markup and alt attributes, so rich results and image search traffic survive.<\/li>\n\n\n\n<li><strong>Canonical conflicts:<\/strong> Flag pages with missing canonicals or canonicals pointing to other URLs, and fix them on the new site rather than carrying the conflict over.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The aliases sit in the database. On Drupal 8.8 and later they are in the <code>path_alias<\/code> table, so a query such as <code>drush sql:query \"SELECT path, alias, langcode FROM path_alias\"<\/code> lists every alias with its system path and language; on Drupal 7 the table is <code>url_alias<\/code>, with <code>source<\/code>, <code>alias<\/code> and <code>language<\/code> columns. Export the Redirect module&#8217;s entries the same way from its own table, or with a Views data export if you prefer a CSV.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This inventory is the reference for every later step: the content mapping, the redirect spreadsheet and the staging crawl all check against it.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"how-to-map-drupal-content-architecture\">How to map Drupal content architecture<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">For SEO, content mapping has one job: every page keeps its address or gets a redirect, keeps its metadata, and keeps its place in the internal link structure. Planning the content model itself is covered in the <a href=\"https:\/\/pagepro.co\/blog\/migration-from-drupal-to-headless-cms\/\">Drupal to headless CMS guide<\/a>; here the focus is the SEO fields.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"map-content-types-and-seo-fields\"><span class=\"underline-accent\">Map content types and SEO fields<\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Map each Drupal content type and field to its place on the new platform, and give every content type explicit SEO fields. On a headless CMS such as Sanity, that means a slug field that holds the old path alias, <a href=\"https:\/\/pagepro.co\/blog\/seo-best-practices-for-sanity-cms\/\">a group of SEO fields for the title, description and canonical<\/a> that Metatag used to render, and <a href=\"https:\/\/www.sanity.io\/docs\/studio\/schema-types\">reference fields<\/a> for taxonomy terms and related content.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Field-level translation:<\/strong> Standardize legacy inputs so metadata translates cleanly; for example, the node title maps to <code>article.title<\/code>, <code>body.summary<\/code> to <code>article.excerpt<\/code>, <code>field_image<\/code> to <code>article.featuredImage<\/code>, and <code>field_tags<\/code> to references to tag documents.<\/li>\n\n\n\n<li><strong>Taxonomy terms:<\/strong> Keep each term as its own document or record with its own URL, so category pages that rank keep their address and their internal links.<\/li>\n\n\n\n<li><strong>Multilingual content:<\/strong> Keep one record per language version with its own URL, so hreflang pairs can be rebuilt one to one.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"preserve-taxonomy-and-internal-links\"><span class=\"underline-accent\">Preserve taxonomy and internal links<\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Search engines use internal links to understand page hierarchy and spread link equity across your domain. Drupal body content often contains absolute URLs and <code>\/node\/123<\/code> paths that point straight at the old site, and those links break or route through redirects after the move.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Update contextual links:<\/strong> Replace old absolute and <code>\/node\/<\/code> links in body content with their final URLs during the migration, so internal navigation never depends on redirects.<\/li>\n\n\n\n<li><strong>Replicate structural navigation:<\/strong> Keep the header, footer and sidebar link structure close to the Drupal layout, so the site hierarchy search engines know stays intact.<\/li>\n\n\n\n<li><strong>Eliminate orphan pages:<\/strong> Make sure every migrated page gets at least one internal link, or it cannot be crawled efficiently.<\/li>\n<\/ul>\n\n\n\n<div class=\"wp-block-code-mind-cta c-cta-block\" style=\"background-color:#00141F;color:#FFFFFF\"><div class=\"c-cta-block__content\"><p class=\"c-cta-block__title\">Upgrade your tech without losing a single keyword position.<\/p><div class=\"c-cta-block__action\"><a href=\"https:\/\/pagepro.co\/contact\" class=\"c-cta-block__button ga-cta ga-cta-consultation theme-bg-3\">Plan Safe SEO Migration<\/a><\/div><\/div><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"seo-migration-from-drupal-and-redirects\">SEO migration from Drupal and redirects<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">When URLs change, permanent redirects are your main defense against lost traffic. Google treats <a href=\"https:\/\/developers.google.com\/search\/docs\/crawling-indexing\/301-redirects\">301 and 308 redirects<\/a> the same way, as a signal that the new address should become the canonical one, so either status works as long as every old URL points straight to its final destination.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"build-a-redirect-spreadsheet\"><span class=\"underline-accent\">Build a redirect spreadsheet<\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">A redirect spreadsheet shows where each current page will live on the new site. Combine the crawl, the exported path aliases and Redirect module entries, Search Console and analytics data, so every URL with traffic or inbound links is accounted for.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Legacy Drupal URL:<\/strong> The exact old path, from the alias export, the crawl and analytics.<\/li>\n\n\n\n<li><strong>New destination URL:<\/strong> The most relevant new page for that content, never a blanket redirect to the homepage.<\/li>\n\n\n\n<li><strong>Redirect type:<\/strong> A permanent redirect, 301 or 308, with no intermediate hops.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">On a Next.js frontend, the map becomes entries in <a href=\"https:\/\/nextjs.org\/docs\/app\/api-reference\/config\/next-config-js\/redirects\">next.config.js redirects<\/a>, which answer permanent redirects with a 308, or a redirect list managed in the CMS for large sites. Google recommends that you <a href=\"https:\/\/developers.google.com\/search\/docs\/crawling-indexing\/site-move-with-url-changes\">keep redirects for at least a year<\/a>, and longer is better for pages with backlinks.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Scale decides where the redirects live. On Vercel, <code>next.config.js<\/code> holds up to 1,024 redirects, enough for many smaller sites. For a Drupal site with thousands of aliases, Vercel&#8217;s <a href=\"https:\/\/vercel.com\/docs\/routing\/redirects\/bulk-redirects\">bulk redirects<\/a> load many thousands of simple redirects from a CSV or JSON file, and the <a href=\"https:\/\/nextjs.org\/docs\/app\/guides\/redirecting\">Next.js redirecting guide<\/a> describes a redirect map checked in Proxy with a Bloom filter for dynamic cases. Either way, Vercel <a href=\"https:\/\/vercel.com\/docs\/routing\/redirects\">processes redirects at the edge across all regions<\/a>, before any page renders.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"carry-seo-data-through-the-content-migration\">Carry SEO data through the content migration<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The content migration is where SEO data most often gets lost, because scripts move the visible text and skip the fields around it. Whatever the destination, the scripts have to carry titles, descriptions, canonicals, alt text, structured data and language versions alongside the content.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Drupal to a current Drupal version:<\/strong> The core <a href=\"https:\/\/www.drupal.org\/docs\/core-modules-and-themes\/core-modules\/migrate-module\">Migrate API<\/a> with the Migrate Drupal module moves content, taxonomy and configuration from Drupal 7 into Drupal 11, and Metatag values can be mapped in the same run.<\/li>\n\n\n\n<li><strong>Drupal to a headless CMS:<\/strong> Content usually leaves through JSON:API or straight from the database, as the <a href=\"https:\/\/pagepro.co\/blog\/migration-from-drupal-to-headless-cms\/\">Drupal to headless guide<\/a> describes; the SEO addition is to map Metatag values, aliases and alt text into the new SEO fields in the same script.<\/li>\n\n\n\n<li><strong>Rich text and media:<\/strong> Strip unrecognized HTML from body fields, keep image file names and alt text, and update file paths, so images keep their image search traffic.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">On a Next.js frontend, the migrated SEO fields feed the page head through <a href=\"https:\/\/nextjs.org\/docs\/app\/api-reference\/functions\/generate-metadata\">generateMetadata<\/a>, where <code>alternates.canonical<\/code> sets the canonical URL and <code>alternates.languages<\/code> outputs the hreflang tags for each language version. For the structured data side, see <a href=\"https:\/\/pagepro.co\/blog\/importance-of-structured-data-in-cms-migration\/\">structured data in CMS migration<\/a>.<\/p>\n\n\n\n<div class=\"wp-block-code-mind-newsletter c-newsletter-block\"><p class=\"c-newsletter-block__title c-newsletter__header\">Sign up for newsletter!<\/p><p class=\"c-newsletter-block__desc c-newsletter__header\">Every month, we send a selection of news from the tech industry to your email inbox.<\/p><form method=\"post\" class=\"c-newsletter-block__form js-newsletter-form c-newsletter__action\" name=\"newsletter-block-form\"><input name=\"newsletter-email\" id=\"newsletter-email\" type=\"text\" class=\"c-newsletter-block__input js-newsletter-input\" placeholder=\"Email\"\/><input name=\"newsletter-campaign\" id=\"newsletter-campaign\" type=\"hidden\"\/><div class=\"c-newsletter-block__group\"><input name=\"consent\" type=\"checkbox\" class=\"js-newsletter-consent\"\/><label for=\"consent\">I accept the <a href=\"https:\/\/pagepro.co\/privacy-policy\">Privacy Policy<\/a> and agree to process my personal data by Pagepro for marketing purposes.<\/label><\/div><input type=\"submit\" class=\"c-newsletter-block__button js-newsletter-sub ga-newsletter-form-content\" value=\"Sign up\"\/><p class=\"theme-size-1 js-message-valid is-hidden is-invalid\"><\/p><\/form><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"what-to-test-before-launch\">What to test before launch<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Test the staging site against the inventory before it goes live. Search engines process structural changes quickly, so an error exposed in the first post-launch crawl can cost rankings right away.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"run-crawl-and-redirect-tests\"><span class=\"underline-accent\">Run crawl and redirect tests<\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Run a full crawl of staging with a tool like Screaming Frog or Sitebulb and compare it with the pre-migration inventory.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Redirect validation:<\/strong> Request every old URL and confirm it returns a single permanent redirect to the right destination, with no loops or chains.<\/li>\n\n\n\n<li><strong>Metadata parity:<\/strong> Compare titles, descriptions, canonicals and hreflang on staging with the Metatag export, page by page for the top pages.<\/li>\n\n\n\n<li><strong>Internal links:<\/strong> Find any links still pointing to old Drupal paths and update them to their final URLs.<\/li>\n\n\n\n<li><strong>URL variants:<\/strong> Request mixed-case, trailing-slash, language-prefixed and query-string versions of your top URLs, plus their <code>\/node\/<\/code> and <code>\/taxonomy\/term\/<\/code> system paths, and confirm each one lands on the right page in one hop.<\/li>\n\n\n\n<li><strong>Indexing directives:<\/strong> Confirm which noindex tags and robots.txt rules are for staging only, so they are removed at launch.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"check-performance-and-accessibility\"><span class=\"underline-accent\">Check performance and accessibility<\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Page speed is a ranking factor, and a new frontend can make it better or worse. Measure the new templates with PageSpeed Insights and Lighthouse during development, on staging and right after launch, and compress images, lazy-load media and test mobile layouts before the switch.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"seo-migration-from-drupal-launch-risks\">SEO migration from Drupal launch risks<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Watch for these launch mistakes in the first days. The first five come from how Drupal builds and resolves URLs, which the new platform may handle differently.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Letter case:<\/strong> The <a href=\"https:\/\/www.drupal.org\/project\/redirect\">Redirect module<\/a> matches paths case-insensitively, so links with different capitalization may have worked for years, while Vercel&#8217;s CDN <a href=\"https:\/\/vercel.com\/docs\/routing\/redirects\">treats paths as case-sensitive<\/a>; any variant the new site does not resolve becomes a 404.<\/li>\n\n\n\n<li><strong>Trailing slashes:<\/strong> Next.js by default <a href=\"https:\/\/nextjs.org\/docs\/app\/api-reference\/config\/next-config-js\/trailingSlash\">redirects <code>\/about\/<\/code> to <code>\/about<\/code><\/a>, so a redirect that targets the slash version adds a second hop; pick one convention and map to it.<\/li>\n\n\n\n<li><strong>Language prefixes:<\/strong> Drupal&#8217;s <code>\/en\/<\/code> and <code>\/de\/<\/code> prefixes have to survive in the new routes, or every hreflang pair breaks at once.<\/li>\n\n\n\n<li><strong>Query-string URLs:<\/strong> Paginated views such as <code>?page=2<\/code> and filtered listings are indexed URLs too; redirect or canonicalize them deliberately.<\/li>\n\n\n\n<li><strong>System paths:<\/strong> <code>\/node\/123<\/code> and <code>\/taxonomy\/term\/45<\/code> paths that search engines or other sites still use need redirects of their own.<\/li>\n\n\n\n<li><strong>Redirect chains:<\/strong> An old Redirect module entry that now points to a redirected URL adds a hop, slows the page and wastes crawl requests; point every old URL straight to its final address.<\/li>\n\n\n\n<li><strong>Staging directives left on:<\/strong> A noindex tag or a blocking robots.txt rule copied from staging can remove the new site from search.<\/li>\n\n\n\n<li><strong>Lost metadata and hreflang:<\/strong> Pages that lose their titles, canonicals or hreflang pairs can drop even when their redirects are correct.<\/li>\n\n\n\n<li><strong>Orphaned pages:<\/strong> Pages that lost their internal links during the rebuild are crawled less and rank worse.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"plan-first-24-hour-smoke-tests\"><span class=\"underline-accent\">Plan first 24-hour smoke tests<\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Write smoke tests as code so they run the moment the new site is live.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Run full post-launch crawls:<\/strong> Crawl the live site to confirm it is accessible to search engines and that no legacy pages were missed.<\/li>\n\n\n\n<li><strong>Validate priority URLs automatically:<\/strong> A script that requests every priority URL can confirm 200 responses, canonical tags and structured data.<\/li>\n\n\n\n<li><strong>Audit robots.txt:<\/strong> Check that the live robots.txt does not block pages, JavaScript or CSS and that it references the new XML sitemap.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">To compare the new platform with your Drupal site on your own content before committing, Pagepro offers to rebuild part of your website with your real content in 48 hours, with no cost and no commitment.<\/p>\n\n\n\n<div class=\"wp-block-code-mind-cta c-cta-block\" style=\"background-color:#00141F;color:#FFFFFF\"><div class=\"c-cta-block__content\"><p class=\"c-cta-block__title\">Keep every backlink and ranking intact.<\/p><div class=\"c-cta-block__action\"><a href=\"https:\/\/pagepro.co\/contact\" class=\"c-cta-block__button ga-cta ga-cta-consultation theme-bg-3\">Prevent Traffic Drop<\/a><\/div><\/div><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"post-launch-monitoring-and-recovery\">Post-launch monitoring and recovery<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Google warns that rankings fluctuate during a move: for a medium-sized site it can take <a href=\"https:\/\/developers.google.com\/search\/docs\/crawling-indexing\/site-move-with-url-changes\">a few weeks or more<\/a> before the new URLs show up, and rankings settle over time. Monitoring tells you whether a dip is that normal fluctuation or a fault you need to fix.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"track-rankings-and-traffic-trends\"><span class=\"underline-accent\">Track rankings and traffic trends<\/span><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Daily Search Console reviews:<\/strong> Check coverage, crawl errors and 404s every day for the first weeks, and compare indexed pages with the benchmark.<\/li>\n\n\n\n<li><strong>Rank tracking by URL:<\/strong> Watch the pages and keywords from your benchmark, and look for consistent patterns rather than single-day swings.<\/li>\n\n\n\n<li><strong>Server logs:<\/strong> Check that Googlebot is crawling the new URLs and that no unexpected error codes appear.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"recover-pages-that-lose-rankings\"><span class=\"underline-accent\">Recover pages that lose rankings<\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">When a page from your benchmark drops and stays down for more than a few days, check it in this order before changing any content.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Compare with the benchmark:<\/strong> Confirm the drop is real for that URL and its keywords, not site-wide fluctuation.<\/li>\n\n\n\n<li><strong>Check the redirect:<\/strong> Request the old URL and confirm one permanent redirect to the right new page, with no chain.<\/li>\n\n\n\n<li><strong>Check the page head:<\/strong> Compare title, description, canonical and hreflang with the Metatag export, and look for a stray noindex.<\/li>\n\n\n\n<li><strong>Check internal links:<\/strong> Make sure the page still receives the internal links it had on Drupal.<\/li>\n\n\n\n<li><strong>Fix and request indexing:<\/strong> Correct what you found, then request indexing through the URL Inspection tool in Search Console.<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"resubmit-sitemaps-and-recrawl\"><span class=\"underline-accent\">Resubmit sitemaps and recrawl<\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Submit the new XML sitemap in Search Console as soon as the site is live. Google&#8217;s site-move guidance also suggests keeping a sitemap of the old URLs for a while: its indexed count should fall to zero as the redirects are processed, which confirms the move is working. Submit your most valuable pages through the URL Inspection tool to have them recrawled sooner.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For the headless side of the same move, from Core Web Vitals to getting cited by AI search, see the <a href=\"https:\/\/pagepro.co\/blog\/headless-cms-seo-migration-guide\/\">headless CMS SEO migration guide<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"faq\">FAQ<\/h2>\n\n\n\n<div class=\"schema-faq wp-block-yoast-faq-block\"><div class=\"schema-faq-section\" id=\"faq-question-1293896587477\"><strong class=\"schema-faq-question\">How do I handle legacy Drupal absolute URLs to prevent broken internal links?<\/strong> <p class=\"schema-faq-answer\">Replace absolute URLs and \/node\/ paths in body content with the final new URLs during the migration, using a search-and-replace step in the migration script. Use the path alias export to look up each target, so internal links never depend on redirects.<\/p> <\/div> <div class=\"schema-faq-section\" id=\"faq-question-1108783987577\"><strong class=\"schema-faq-question\">How long does it take for search rankings to stabilize after a CMS migration?<\/strong> <p class=\"schema-faq-answer\">Google says rankings fluctuate during a site move and settle over time, and for a medium-sized site the new URLs can take a few weeks or more to show up. Larger sites take longer. Track rankings and indexing daily in the first weeks to tell normal fluctuation from real errors.<\/p> <\/div> <div class=\"schema-faq-section\" id=\"faq-question-1084004073974\"><strong class=\"schema-faq-question\">What is the best way to map Drupal taxonomy terms to a new site structure?<\/strong> <p class=\"schema-faq-answer\">Keep each taxonomy term as its own record with its own URL on the new platform, for example a document in Sanity that articles reference. Category pages that rank then keep their address, and every article keeps its links to its terms.<\/p> <\/div> <div class=\"schema-faq-section\" id=\"faq-question-1316878296762\"><strong class=\"schema-faq-question\">How do I verify that 301 redirects from Drupal work correctly?<\/strong> <p class=\"schema-faq-answer\">Request every old URL from your redirect spreadsheet with a crawler such as Screaming Frog and confirm it returns one permanent redirect, 301 or 308, straight to the right page, with no loops or chains. Repeat the check right after launch on the live site.<\/p> <\/div> <div class=\"schema-faq-section\" id=\"faq-question-1160560742083\"><strong class=\"schema-faq-question\">Why do some pages lose visibility after migration despite having correct redirects?<\/strong> <p class=\"schema-faq-answer\">Visibility drops often happen because canonical tags, noindex tags, hreflang, page speed or structured data changed during the migration, or because the page lost internal links. Search engines also need time to recrawl, so compare the page with your benchmark before changing anything.<\/p> <\/div> <\/div>\n","protected":false},"excerpt":{"rendered":"<p>What this means for your team A Drupal migration is a rebuild, and every rebuild carries SEO risk. The risk concentrates in three places: missing redirects, metadata lost in the content scripts, and staging settings left on at launch. Plan the SEO steps into the project from the start: the inventory and redirect map belong [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":24816,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"rop_custom_images_group":[],"rop_custom_messages_group":[],"rop_publish_now":"yes","rop_publish_now_accounts":[],"rop_publish_now_history":[],"rop_publish_now_status":"pending","footnotes":""},"categories":[660,309],"tags":[],"class_list":["post-24811","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-for-cto","category-headless"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>SEO Migration from Drupal - Pagepro<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/pagepro.co\/blog\/seo-migration-from-drupal\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"SEO Migration from Drupal - Pagepro\" \/>\n<meta property=\"og:description\" content=\"What this means for your team A Drupal migration is a rebuild, and every rebuild carries SEO risk. The risk concentrates in three places: missing redirects, metadata lost in the content scripts, and staging settings left on at launch. Plan the SEO steps into the project from the start: the inventory and redirect map belong [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/pagepro.co\/blog\/seo-migration-from-drupal\/\" \/>\n<meta property=\"og:site_name\" content=\"Pagepro\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/thisispagepro\" \/>\n<meta property=\"article:author\" content=\"https:\/\/facebook.com\/krzysztof.lojniewski\" \/>\n<meta property=\"article:published_time\" content=\"2026-10-14T14:37:47+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-11-04T12:12:21+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2026\/10\/SEO-Migration-from-Drupal.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1280\" \/>\n\t<meta property=\"og:image:height\" content=\"720\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Chris Lojniewski\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@https:\/\/x.com\/chrislojniewski\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Chris Lojniewski\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"13 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/pagepro.co\\\/blog\\\/seo-migration-from-drupal\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/pagepro.co\\\/blog\\\/seo-migration-from-drupal\\\/\"},\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/pagepro.co\\\/blog\\\/seo-migration-from-drupal\\\/\"},\"headline\":\"SEO Migration from Drupal\",\"datePublished\":\"2026-10-14T14:37:47+00:00\",\"dateModified\":\"2026-11-04T12:12:21+00:00\",\"inLanguage\":\"en-US\",\"breadcrumb\":{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/pagepro.co\\\/blog\\\/seo-migration-from-drupal\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Blog\",\"item\":\"https:\\\/\\\/pagepro.co\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"For CTO\",\"item\":\"https:\\\/\\\/pagepro.co\\\/blog\\\/category\\\/for-cto\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"SEO Migration from Drupal\"}]},\"publisher\":{\"@id\":\"https:\\\/\\\/pagepro.co\\\/#organization\"},\"articleSection\":\"For CTO\",\"wordCount\":2919,\"image\":{\"@id\":\"https:\\\/\\\/pagepro.co\\\/blog\\\/seo-migration-from-drupal\\\/#primaryimage\"},\"author\":{\"@id\":\"https:\\\/\\\/pagepro.co\\\/blog\\\/author\\\/chris-lojniewski\\\/#person\",\"name\":\"Chris Lojniewski\"}},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/pagepro.co\\\/#organization\",\"name\":\"Pagepro\",\"url\":\"https:\\\/\\\/pagepro.co\\\/\",\"foundingDate\":\"2016-02-27\",\"description\":\"Pagepro is a website replatforming and headless CMS migration agency. We move content-heavy websites to Next.js and Sanity, take over unfinished and AI-built Next.js projects, and provide continuous development and support.\",\"logo\":{\"@type\":\"ImageObject\",\"@id\":\"https:\\\/\\\/pagepro.co\\\/#logo\",\"url\":\"https:\\\/\\\/pagepro.co\\\/assets\\\/svg\\\/pagepro-full-color.svg\",\"width\":300,\"height\":132,\"caption\":\"Pagepro\"},\"sameAs\":[\"https:\\\/\\\/www.linkedin.com\\\/company\\\/pagepro\\\/\",\"https:\\\/\\\/x.com\\\/pagepro_agency\",\"https:\\\/\\\/www.facebook.com\\\/thisispagepro\",\"https:\\\/\\\/www.instagram.com\\\/pagepro_\\\/\",\"https:\\\/\\\/www.youtube.com\\\/@Pagepro_agency\",\"https:\\\/\\\/clutch.co\\\/profile\\\/pagepro\",\"https:\\\/\\\/www.sanity.io\\\/agency-partners\\\/pagepro\",\"https:\\\/\\\/github.com\\\/Pagepro\"],\"knowsAbout\":[\"Website replatforming\",\"Headless CMS migration\",\"Website and CMS migration\",\"Next.js development\",\"Sanity CMS development\",\"Headless CMS architecture\",\"AI-built application takeover\",\"Next.js support and maintenance\",\"Web application development\",\"React development\",\"React Native development\",\"Team augmentation\"],\"areaServed\":[{\"@type\":\"Country\",\"name\":\"United Kingdom\"},{\"@type\":\"Country\",\"name\":\"United States\"},{\"@type\":\"Country\",\"name\":\"Poland\"}],\"subOrganization\":[{\"@id\":\"https:\\\/\\\/pagepro.co\\\/#ltd\"},{\"@id\":\"https:\\\/\\\/pagepro.co\\\/#spzoo\"}]},{\"@type\":\"FAQPage\",\"mainEntity\":[{\"@type\":\"Question\",\"name\":\"How do I handle legacy Drupal absolute URLs to prevent broken internal links?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Replace absolute URLs and \\\/node\\\/ paths in body content with the final new URLs during the migration, using a search-and-replace step in the migration script. Use the path alias export to look up each target, so internal links never depend on redirects.\"}},{\"@type\":\"Question\",\"name\":\"How long does it take for search rankings to stabilize after a CMS migration?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Google says rankings fluctuate during a site move and settle over time, and for a medium-sized site the new URLs can take a few weeks or more to show up. Larger sites take longer. Track rankings and indexing daily in the first weeks to tell normal fluctuation from real errors.\"}},{\"@type\":\"Question\",\"name\":\"What is the best way to map Drupal taxonomy terms to a new site structure?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Keep each taxonomy term as its own record with its own URL on the new platform, for example a document in Sanity that articles reference. Category pages that rank then keep their address, and every article keeps its links to its terms.\"}},{\"@type\":\"Question\",\"name\":\"How do I verify that 301 redirects from Drupal work correctly?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Request every old URL from your redirect spreadsheet with a crawler such as Screaming Frog and confirm it returns one permanent redirect, 301 or 308, straight to the right page, with no loops or chains. Repeat the check right after launch on the live site.\"}},{\"@type\":\"Question\",\"name\":\"Why do some pages lose visibility after migration despite having correct redirects?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Visibility drops often happen because canonical tags, noindex tags, hreflang, page speed or structured data changed during the migration, or because the page lost internal links. Search engines also need time to recrawl, so compare the page with your benchmark before changing anything.\"}}]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"SEO Migration from Drupal - Pagepro","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/pagepro.co\/blog\/seo-migration-from-drupal\/","og_locale":"en_US","og_type":"article","og_title":"SEO Migration from Drupal - Pagepro","og_description":"What this means for your team A Drupal migration is a rebuild, and every rebuild carries SEO risk. The risk concentrates in three places: missing redirects, metadata lost in the content scripts, and staging settings left on at launch. Plan the SEO steps into the project from the start: the inventory and redirect map belong [&hellip;]","og_url":"https:\/\/pagepro.co\/blog\/seo-migration-from-drupal\/","og_site_name":"Pagepro","article_publisher":"https:\/\/www.facebook.com\/thisispagepro","article_author":"https:\/\/facebook.com\/krzysztof.lojniewski","article_published_time":"2026-10-14T14:37:47+00:00","article_modified_time":"2026-11-04T12:12:21+00:00","og_image":[{"width":1280,"height":720,"url":"https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2026\/10\/SEO-Migration-from-Drupal.png","type":"image\/png"}],"author":"Chris Lojniewski","twitter_card":"summary_large_image","twitter_creator":"@https:\/\/x.com\/chrislojniewski","twitter_misc":{"Written by":"Chris Lojniewski","Est. reading time":"13 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/pagepro.co\/blog\/seo-migration-from-drupal\/#article","isPartOf":{"@id":"https:\/\/pagepro.co\/blog\/seo-migration-from-drupal\/"},"mainEntityOfPage":{"@id":"https:\/\/pagepro.co\/blog\/seo-migration-from-drupal\/"},"headline":"SEO Migration from Drupal","datePublished":"2026-10-14T14:37:47+00:00","dateModified":"2026-11-04T12:12:21+00:00","inLanguage":"en-US","breadcrumb":{"@type":"BreadcrumbList","@id":"https:\/\/pagepro.co\/blog\/seo-migration-from-drupal\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Blog","item":"https:\/\/pagepro.co\/blog\/"},{"@type":"ListItem","position":2,"name":"For CTO","item":"https:\/\/pagepro.co\/blog\/category\/for-cto\/"},{"@type":"ListItem","position":3,"name":"SEO Migration from Drupal"}]},"publisher":{"@id":"https:\/\/pagepro.co\/#organization"},"articleSection":"For CTO","wordCount":2919,"image":{"@id":"https:\/\/pagepro.co\/blog\/seo-migration-from-drupal\/#primaryimage"},"author":{"@id":"https:\/\/pagepro.co\/blog\/author\/chris-lojniewski\/#person","name":"Chris Lojniewski"}},{"@type":"Organization","@id":"https:\/\/pagepro.co\/#organization","name":"Pagepro","url":"https:\/\/pagepro.co\/","foundingDate":"2016-02-27","description":"Pagepro is a website replatforming and headless CMS migration agency. We move content-heavy websites to Next.js and Sanity, take over unfinished and AI-built Next.js projects, and provide continuous development and support.","logo":{"@type":"ImageObject","@id":"https:\/\/pagepro.co\/#logo","url":"https:\/\/pagepro.co\/assets\/svg\/pagepro-full-color.svg","width":300,"height":132,"caption":"Pagepro"},"sameAs":["https:\/\/www.linkedin.com\/company\/pagepro\/","https:\/\/x.com\/pagepro_agency","https:\/\/www.facebook.com\/thisispagepro","https:\/\/www.instagram.com\/pagepro_\/","https:\/\/www.youtube.com\/@Pagepro_agency","https:\/\/clutch.co\/profile\/pagepro","https:\/\/www.sanity.io\/agency-partners\/pagepro","https:\/\/github.com\/Pagepro"],"knowsAbout":["Website replatforming","Headless CMS migration","Website and CMS migration","Next.js development","Sanity CMS development","Headless CMS architecture","AI-built application takeover","Next.js support and maintenance","Web application development","React development","React Native development","Team augmentation"],"areaServed":[{"@type":"Country","name":"United Kingdom"},{"@type":"Country","name":"United States"},{"@type":"Country","name":"Poland"}],"subOrganization":[{"@id":"https:\/\/pagepro.co\/#ltd"},{"@id":"https:\/\/pagepro.co\/#spzoo"}]},{"@type":"FAQPage","mainEntity":[{"@type":"Question","name":"How do I handle legacy Drupal absolute URLs to prevent broken internal links?","acceptedAnswer":{"@type":"Answer","text":"Replace absolute URLs and \/node\/ paths in body content with the final new URLs during the migration, using a search-and-replace step in the migration script. Use the path alias export to look up each target, so internal links never depend on redirects."}},{"@type":"Question","name":"How long does it take for search rankings to stabilize after a CMS migration?","acceptedAnswer":{"@type":"Answer","text":"Google says rankings fluctuate during a site move and settle over time, and for a medium-sized site the new URLs can take a few weeks or more to show up. Larger sites take longer. Track rankings and indexing daily in the first weeks to tell normal fluctuation from real errors."}},{"@type":"Question","name":"What is the best way to map Drupal taxonomy terms to a new site structure?","acceptedAnswer":{"@type":"Answer","text":"Keep each taxonomy term as its own record with its own URL on the new platform, for example a document in Sanity that articles reference. Category pages that rank then keep their address, and every article keeps its links to its terms."}},{"@type":"Question","name":"How do I verify that 301 redirects from Drupal work correctly?","acceptedAnswer":{"@type":"Answer","text":"Request every old URL from your redirect spreadsheet with a crawler such as Screaming Frog and confirm it returns one permanent redirect, 301 or 308, straight to the right page, with no loops or chains. Repeat the check right after launch on the live site."}},{"@type":"Question","name":"Why do some pages lose visibility after migration despite having correct redirects?","acceptedAnswer":{"@type":"Answer","text":"Visibility drops often happen because canonical tags, noindex tags, hreflang, page speed or structured data changed during the migration, or because the page lost internal links. Search engines also need time to recrawl, so compare the page with your benchmark before changing anything."}}]}]}},"_links":{"self":[{"href":"https:\/\/pagepro.co\/blog\/wp-json\/wp\/v2\/posts\/24811","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pagepro.co\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/pagepro.co\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/pagepro.co\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/pagepro.co\/blog\/wp-json\/wp\/v2\/comments?post=24811"}],"version-history":[{"count":8,"href":"https:\/\/pagepro.co\/blog\/wp-json\/wp\/v2\/posts\/24811\/revisions"}],"predecessor-version":[{"id":24983,"href":"https:\/\/pagepro.co\/blog\/wp-json\/wp\/v2\/posts\/24811\/revisions\/24983"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/pagepro.co\/blog\/wp-json\/wp\/v2\/media\/24816"}],"wp:attachment":[{"href":"https:\/\/pagepro.co\/blog\/wp-json\/wp\/v2\/media?parent=24811"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/pagepro.co\/blog\/wp-json\/wp\/v2\/categories?post=24811"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/pagepro.co\/blog\/wp-json\/wp\/v2\/tags?post=24811"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}