<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Daniel Max</title>
    <description>The latest articles on DEV Community by Daniel Max (@rafinox).</description>
    <link>https://dev.to/rafinox</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4120841%2Fb1ceabe3-0f09-49ec-bc7f-5d185d0f2867.png</url>
      <title>DEV Community: Daniel Max</title>
      <link>https://dev.to/rafinox</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rafinox"/>
    <language>en</language>
    <item>
      <title>How I’m Planning a WordPress to Astro Migration Without Losing SEO</title>
      <dc:creator>Daniel Max</dc:creator>
      <pubDate>Fri, 11 Sep 2026 11:36:53 +0000</pubDate>
      <link>https://dev.to/rafinox/how-im-planning-a-wordpress-to-astro-migration-without-losing-seo-3pd</link>
      <guid>https://dev.to/rafinox/how-im-planning-a-wordpress-to-astro-migration-without-losing-seo-3pd</guid>
      <description>&lt;p&gt;I’m currently rebuilding one of my existing WordPress sites with Astro and planning to move the final build to Cloudflare Pages.&lt;/p&gt;

&lt;p&gt;The main challenge is not rebuilding the design. It is migrating an already indexed site without unnecessarily changing URLs, losing search visibility, or creating technical SEO problems during the switch.&lt;/p&gt;

&lt;p&gt;One project where I’m applying this process is &lt;a href="https://null-brawl.org/" rel="noopener noreferrer"&gt;Nulls Brawl&lt;/a&gt;. The current site remains live on WordPress while the Astro version is prepared separately.&lt;/p&gt;

&lt;p&gt;Here is the migration process I’m following.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Keep the Existing Site Live During Development
&lt;/h2&gt;

&lt;p&gt;I do not want the unfinished Astro version indexed while the WordPress site is still serving users.&lt;/p&gt;

&lt;p&gt;The staging build therefore stays blocked from search engines until the domain migration is ready.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User-agent: *
Disallow: /
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I also keep staging pages out of the production sitemap.&lt;/p&gt;

&lt;p&gt;The important part is removing these restrictions before the final production launch.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Map Every Existing URL Before Changing Anything
&lt;/h2&gt;

&lt;p&gt;Before rebuilding routes, I create a list of all important existing URLs and decide what should happen to each one.&lt;/p&gt;

&lt;p&gt;Each old URL normally falls into one of these groups:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep the same URL&lt;/li&gt;
&lt;li&gt;Redirect to a replacement page&lt;/li&gt;
&lt;li&gt;Return 410 because the content has intentionally been removed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Keeping the same URLs wherever possible reduces unnecessary migration risk.&lt;/p&gt;

&lt;p&gt;For URLs that genuinely move, I use permanent redirects.&lt;/p&gt;

&lt;p&gt;A Cloudflare Pages &lt;code&gt;_redirects&lt;/code&gt; file can be as simple as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/old-page/ /new-page/ 301
/old-guide/ /updated-guide/ 301
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I avoid redirecting unrelated deleted pages to the homepage just to prevent a 404. If content has no real replacement, a proper 404 or 410 is cleaner.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Rebuild SEO Elements Instead of Copying Only the Visible Page
&lt;/h2&gt;

&lt;p&gt;A migration is more than copying HTML and CSS.&lt;/p&gt;

&lt;p&gt;For every important page I check:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;title tag&lt;/li&gt;
&lt;li&gt;meta description&lt;/li&gt;
&lt;li&gt;canonical URL&lt;/li&gt;
&lt;li&gt;H1 and heading structure&lt;/li&gt;
&lt;li&gt;internal links&lt;/li&gt;
&lt;li&gt;image alt text&lt;/li&gt;
&lt;li&gt;Open Graph data&lt;/li&gt;
&lt;li&gt;structured data&lt;/li&gt;
&lt;li&gt;indexability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Astro makes it fairly easy to create reusable SEO components, but the values still need to match the intent of each page.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Generate the Sitemap From Real Routes
&lt;/h2&gt;

&lt;p&gt;I do not want old, redirected, noindex, or removed URLs appearing in the new sitemap.&lt;/p&gt;

&lt;p&gt;The production sitemap should contain only canonical pages that are intended to be indexed.&lt;/p&gt;

&lt;p&gt;The same applies to alternate-language URLs. Each language version needs to point to the correct canonical page and, where appropriate, have consistent hreflang relationships.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Handle Structured Data Carefully
&lt;/h2&gt;

&lt;p&gt;Schema from the WordPress site should not simply be copied without checking whether it still describes the new page correctly.&lt;/p&gt;

&lt;p&gt;For a typical site I may use combinations of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;WebSite&lt;/li&gt;
&lt;li&gt;Organization&lt;/li&gt;
&lt;li&gt;BreadcrumbList&lt;/li&gt;
&lt;li&gt;Article&lt;/li&gt;
&lt;li&gt;FAQPage when the visible page genuinely contains FAQs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I prefer generating schema from the same page data used by the Astro templates instead of maintaining unrelated hardcoded values in several places.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Test Redirects Before Connecting the Domain
&lt;/h2&gt;

&lt;p&gt;This is one of the most important steps.&lt;/p&gt;

&lt;p&gt;Before launch I check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Old URL -&amp;gt; expected new URL
Old removed URL -&amp;gt; expected 404 or 410
Current URL -&amp;gt; 200
Canonical URL -&amp;gt; correct final domain
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I also check for redirect chains such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;A -&amp;gt; B -&amp;gt; C
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and replace them with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;A -&amp;gt; C
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;where possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Performance Is Part of the Migration
&lt;/h2&gt;

&lt;p&gt;One reason I like Astro for content-heavy sites is that pages can ship very little client-side JavaScript.&lt;/p&gt;

&lt;p&gt;But simply using Astro does not automatically make a site fast.&lt;/p&gt;

&lt;p&gt;I still optimize:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;image dimensions and formats&lt;/li&gt;
&lt;li&gt;font loading&lt;/li&gt;
&lt;li&gt;third-party scripts&lt;/li&gt;
&lt;li&gt;layout shifts&lt;/li&gt;
&lt;li&gt;unused JavaScript&lt;/li&gt;
&lt;li&gt;caching&lt;/li&gt;
&lt;li&gt;above-the-fold assets&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I test real pages rather than relying only on the framework choice.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Launch Only After the Technical Checks Pass
&lt;/h2&gt;

&lt;p&gt;My final launch checklist looks roughly like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Remove staging noindex restrictions.&lt;/li&gt;
&lt;li&gt;Confirm robots.txt.&lt;/li&gt;
&lt;li&gt;Confirm sitemap URLs.&lt;/li&gt;
&lt;li&gt;Test important 301 redirects.&lt;/li&gt;
&lt;li&gt;Test intended 404 and 410 responses.&lt;/li&gt;
&lt;li&gt;Verify canonical tags.&lt;/li&gt;
&lt;li&gt;Verify structured data.&lt;/li&gt;
&lt;li&gt;Connect the production domain.&lt;/li&gt;
&lt;li&gt;Crawl the live site again.&lt;/li&gt;
&lt;li&gt;Monitor Google Search Console after migration.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I also keep the old URL map after launch because Search Console or crawl data can reveal a missed redirect later.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I’m Trying to Avoid
&lt;/h2&gt;

&lt;p&gt;The mistakes I am specifically trying to prevent are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;changing URLs without a reason&lt;/li&gt;
&lt;li&gt;publishing staging URLs&lt;/li&gt;
&lt;li&gt;redirecting every removed page to the homepage&lt;/li&gt;
&lt;li&gt;leaving old WordPress URLs in the sitemap&lt;/li&gt;
&lt;li&gt;accidentally shipping &lt;code&gt;noindex&lt;/code&gt; to production&lt;/li&gt;
&lt;li&gt;creating redirect chains&lt;/li&gt;
&lt;li&gt;copying outdated schema&lt;/li&gt;
&lt;li&gt;rebuilding the design while forgetting internal links&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A framework migration should ideally be boring from a search engine’s perspective. The implementation can change completely while the meaning, URLs, and relationships between important pages remain stable.&lt;/p&gt;

&lt;p&gt;That is the approach I’m following while moving this project from WordPress to Astro and Cloudflare Pages.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>astro</category>
      <category>seo</category>
      <category>cloudflare</category>
    </item>
  </channel>
</rss>
