<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="../assets/xml/rss.xsl" media="all"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Focus on your mission, not your tech - Another Cup of Coffee (Posts about SEO)</title><link>https://anothercoffee.net/</link><description></description><atom:link href="https://anothercoffee.net/categories/seo.xml" rel="self" type="application/rss+xml"></atom:link><language>en</language><copyright>Copyright © 2006 - 2026 &lt;a href="https://anothercoffee.net/" title="Another Cup of Coffee Limited"&gt;Another Cup of Coffee Limited&lt;/a&gt; </copyright><lastBuildDate>Wed, 18 Feb 2026 16:39:44 GMT</lastBuildDate><generator>Nikola (getnikola.com)</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>Fixing Access Forbidden (403) issues after migrating WordPress to a static site</title><link>https://anothercoffee.net/fixing-access-forbidden-403-issues-after-migrating-wordpress-to-a-static-site/</link><dc:creator>Anthony Lopez-Vito</dc:creator><description>&lt;p&gt;After migrating a WordPress site to static files, Google Search Console may start sending you notifications about page indexing problems. Often the issue will be marked as ‘&lt;em&gt;Blocked due to access forbidden (403)&lt;/em&gt;‘, a fairly common error that can have different causes, depending on how your website and server is set up.&lt;/p&gt;


&lt;figure class="figure d-flex flex-column align-items-center"&gt;
    &lt;img src="https://anothercoffee.net/images/no-entry-Lucian-Alexe-Unsplash-l0w1ftNPZ9s.jpg" alt="No entry road stock photo - Access Forbidden 403 error" class="figure-img img-fluid rounded" width="800" height="417"&gt;
&lt;/figure&gt;

&lt;p&gt;This article specifically deals with the case when:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You previously had a working WordPress installation;&lt;/li&gt;
&lt;li&gt;You migrate the site to static HTML files on an Apache web server;&lt;/li&gt;
&lt;li&gt;Google Search Console starts complaining about page indexing problems.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If this does not apply to your situation, the proposed solution may not work but you will still find the explanation useful in diagnosing the problem.&lt;/p&gt;
&lt;h2&gt;Table of contents&lt;/h2&gt;
&lt;div class="toc"&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="https://anothercoffee.net/fixing-access-forbidden-403-issues-after-migrating-wordpress-to-a-static-site/#forbidden-403"&gt;The Forbidden 403 error&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://anothercoffee.net/fixing-access-forbidden-403-issues-after-migrating-wordpress-to-a-static-site/#wordpress-requests"&gt;How WordPress serves your browser requests&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://anothercoffee.net/fixing-access-forbidden-403-issues-after-migrating-wordpress-to-a-static-site/#static-files"&gt;Serving static files&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://anothercoffee.net/fixing-access-forbidden-403-issues-after-migrating-wordpress-to-a-static-site/#directory-index"&gt;Web server directory index&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://anothercoffee.net/fixing-access-forbidden-403-issues-after-migrating-wordpress-to-a-static-site/#generating-static-site"&gt;Generating static HTML files from a WordPress site&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://anothercoffee.net/fixing-access-forbidden-403-issues-after-migrating-wordpress-to-a-static-site/#why-forbidden"&gt;Why access is forbidden&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://anothercoffee.net/fixing-access-forbidden-403-issues-after-migrating-wordpress-to-a-static-site/#how-to-fix"&gt;How to fix the Access Forbidden (403) error&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;

&lt;h2 id="forbidden-403"&gt;The Forbidden 403 error&lt;/h2&gt;
&lt;p&gt;Being in the 4XX category of HTTP response codes, &lt;em&gt;Access Forbidden (403)&lt;/em&gt; is a client-side error that may show in a message similar to the following combinations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Access Forbidden (403)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;403 Forbidden&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;HTTP 403&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;HTTP Error 403 – Forbidden&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Forbidden: You don’t have permission to access [directory path] on this server&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The Google Search Console notification email will be about page indexing problems with  ‘&lt;em&gt;Blocked due to access forbidden (403)&lt;/em&gt;‘ as one of the Top Issues.&lt;/p&gt;

&lt;figure class="figure d-flex flex-column align-items-center"&gt;
    &lt;img src="https://anothercoffee.net/images/anothercoffee-google-search-console-page-indexing-issues.png" alt="Google Search Console Page indexing issues" class="figure-img img-fluid rounded" width="498" height="348"&gt;
    &lt;figcaption&gt;A typical Access Forbidden (403) notification from the Google Search Console&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Nevertheless, it being a client-side error doesn’t necessary isolate the problem to your browser. Many solutions online will advise you to clear your cache or refresh the page. This is easy to do and usually a sensible first step but if you found the issue via a Google Search Console notification after a WordPress migration, these recommendations won’t help.&lt;/p&gt;
&lt;p&gt;The 403 response code essentially means that a web client, such as your browser, does not have permission to access the requested resource. The web server understands the request but can’t allow access due to file permissions settings or a server misconfiguration. When it comes to WordPress, the error will almost certainly be due to a misbehaving plugin, a &lt;a href="https://kinsta.com/blog/403-forbidden-error/" target="_blank" rel="noreferrer noopener nofollow"&gt;corrupt .htaccess file or incorrect file permissions&lt;/a&gt;. However, if you’ve recently converted your WordPress installation to a static site, the error will most likely have a different cause.&lt;/p&gt;
&lt;p&gt;To understand why the &lt;em&gt;Access Forbidden&lt;/em&gt; error happens, it’s worth reviewing the differences between how the WordPress content management system (CMS) serves content and how a static site responds to web client requests.&lt;/p&gt;

&lt;h2 id="wordpress-requests"&gt;How WordPress serves your browser requests&lt;/h2&gt;
&lt;p&gt;WordPress is a database-driven Content management system (CMS). Most of the content is stored in a database and URLs generally do not correspond to any files in the web server’s filesystem. Instead, URLs are external references to the database content. WordPress calls these references &lt;em&gt;permalinks&lt;/em&gt; and its rewriting engine uses internal &lt;a href="https://codex.wordpress.org/Using_Permalinks"&gt;rules&lt;/a&gt;, specified in the &lt;a href="https://codex.wordpress.org/Using_Permalinks#Choosing_your_permalink_structure"&gt;permalink settings&lt;/a&gt;, to build permalinks dynamically. When a client requests a page from the site, WordPress takes care of serving the correct content. Included with the pages will be any XML-based RSS (Really Simple Syndication) feeds. WordPress will send the HTML page or an XML feed, depending on what the client requests.&lt;/p&gt;
&lt;p&gt;For example, if you set the permalink settings to the &lt;em&gt;Post name&lt;/em&gt; structure, WordPress will generate a HTML post when you browse to the following URL:&lt;br&gt;&lt;code&gt;https://example.com/your-post/&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The RSS feed for that post will be at:&lt;br&gt;&lt;code&gt;https://example.com/your-post/feed/&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;RSS feeds are normally parsed by an RSS client rather than for displaying directly in the browser window so requesting the RSS feed resource will not send HTML. Instead WordPress will generate XML for the feed.&lt;/p&gt;

&lt;h2 id="static-files"&gt;Serving static files&lt;/h2&gt;
&lt;p&gt;By definition, static sites have no way of dynamically generating content based on the browser request. You make a request to the web server at a given URL and if the resource is present with the correct access permissions, the web server will go ahead and serve the file. The URL for a static site will normally look something like:&lt;br&gt;&lt;code&gt;https://example.com/your-post.html&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If you have an RSS feed, it might look something like:&lt;br&gt;&lt;code&gt;https://example.com/feed.xml&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Notice that the request includes the path to the file, such as &lt;code&gt;your-post.html&lt;/code&gt; or &lt;code&gt;feed.xml&lt;/code&gt;. The file is not present in a WordPress permalink because, as mentioned previously, it is only a reference to the actual content stored in the database.&lt;/p&gt;

&lt;h2 id="directory-index"&gt;Web server directory index&lt;/h2&gt;
&lt;p&gt;Web servers such as Apache also have a &lt;a href="https://httpd.apache.org/docs/2.4/mod/mod_dir.html#directoryindex" target="_blank" rel="noreferrer noopener nofollow"&gt;Directory Index directive&lt;/a&gt;. This is a configuration that can set the server to automatically send a file when a client makes a request without a filename in the URL. The file known as the directory index and is normally named &lt;code&gt;index.html&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Web servers such as Apache also have a &lt;a href="https://httpd.apache.org/docs/2.4/mod/mod_dir.html#directoryindex" target="_blank" rel="noreferrer noopener nofollow"&gt;Directory Index directive&lt;/a&gt;. In the early days of the web, you could browse to a folder in the web server filesystem and get a listing of all the files present. For security, most web hosts now disable this feature for most of their hosting services. The Directory Index directive is a configuration that can set the server to automatically send a file when a client request only includes the folder name in the URL. For most hosting services, the standard directory index files are normally &lt;code&gt;index.html&lt;/code&gt; and &lt;code&gt;index.php&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Say a client makes a request for the following:&lt;br&gt;&lt;code&gt;https://example.com/docs/&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;If the directory index is set to &lt;code&gt;index.html&lt;/code&gt;, the server would return:&lt;br&gt;&lt;code&gt;http://example.com/docs/index.html&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;index.html&lt;/code&gt; renders as a web page in the browser. Directory index resources can also be set to other file types like &lt;code&gt;index.txt&lt;/code&gt; or &lt;code&gt;index.xml&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id="generating-static-site"&gt;Generating static HTML files from a WordPress site&lt;/h2&gt;
&lt;p&gt;WordPress plugins such as &lt;a href="https://wordpress.org/plugins/simply-static/" target="_blank" rel="noreferrer noopener nofollow"&gt;Simply Static&lt;/a&gt; will crawl your site to generate static HTML file copies for the pages. Since WordPress includes RSS feeds, static XML copies will also be generated for these feeds. The tables below show typical WordPress permalinks and their equivalents after static HTML copies are generated.&lt;/p&gt;
&lt;figure class="wp-block-table"&gt;
&lt;table class="has-fixed-layout"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="width:30%"&gt;Page type&lt;/th&gt;
&lt;th&gt;WordPress permalink&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Page content&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;code&gt;https://example.com/your-post/&lt;/code&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RSS feed&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;code&gt;https://example.com/your-post/feed/&lt;/code&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/figure&gt;
&lt;figure class="wp-block-table"&gt;
&lt;table class="has-fixed-layout"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="width:30%"&gt;Page type&lt;/th&gt;
&lt;th&gt;Static file URL&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Page content&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;code&gt;https://example.com/your-post/index.html&lt;/code&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RSS feed&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;code&gt;https://example.com/your-post/feed/index.xml&lt;/code&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/figure&gt;
&lt;p&gt;Once again notice that the static site specifies the filename in the path whereas the WordPress permalink, when set to the &lt;em&gt;Post name&lt;/em&gt; structure, does not.&lt;/p&gt;
&lt;h2 id="why-forbidden"&gt;Why access is forbidden&lt;/h2&gt;
&lt;p&gt;We have all the puzzle pieces to understand why you would get the &lt;em&gt;Access Forbidden (403)&lt;/em&gt; error and how you can fix the problem. After you migrate your WordPress site to static files, the old permalink paths to pages will still serve a web page because most hosting providers have &lt;code&gt;index.html&lt;/code&gt; as a directory index resource.&lt;/p&gt;
&lt;p&gt;You can request the URL in the WordPress post name permalink format:&lt;br&gt;&lt;code&gt;https://example.com/your-post/&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The static file generator would have created an index.html in this location:&lt;br&gt;&lt;code&gt;https://example.com/your-post/&lt;/code&gt;index.html&lt;/p&gt;
&lt;p&gt;The webserver sees the &lt;code&gt;index.html&lt;/code&gt; in the filesystem and delivers it to the browser which can render the web page content. Human site visitors will be perfectly happy because they receive the web page resources they expect. However, Googlebot, Google’s web page crawler, will spider through your site &lt;em&gt;including the RSS feed locations&lt;/em&gt;. Remember, the RSS feed folders will contain an &lt;code&gt;index.xml&lt;/code&gt;. XML files are not normally a default directory index resource for most web hosts. Since there is no &lt;code&gt;index.html&lt;/code&gt; file in the feed folder, the web server thinks it’s being asked to deliver a file listing. Again remember that file listings are disabled by most web hosts for security. Thus you get the error:&lt;/p&gt;
&lt;p class="has-text-align-center"&gt;&lt;code&gt;Access Forbidden (403)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;You are forbidden by the web server to access that folder listing.&lt;/p&gt;

&lt;h2 id="how-to-fix"&gt;How to fix the Access Forbidden (403) error&lt;/h2&gt;
&lt;p&gt;Now that we know exactly why we get this error we attempt a fix. If your host runs Apache, the solution will likely be simple. Edit or create the &lt;code&gt;.htaccess&lt;/code&gt; file in the root of your site and add &lt;code&gt;index.xml&lt;/code&gt; to the list of directory index resources. For example, if it not already there, add the following line somewhere near the top of the file:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;DirectoryIndex index.html index.php index.xml&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;index.xml&lt;/code&gt; in the list will tell Apache to serve the XML file when Googlebot requests the RSS feed directory. While you’re doing this, inspect a few o the feed directories to make sure the &lt;code&gt;index.xml&lt;/code&gt; files have the correct permissions (usually &lt;code&gt;775&lt;/code&gt; for most server setups) and the correct ownership. The ownership settings should be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;user&lt;/code&gt;&lt;/strong&gt; is the user account with root privileges on your web server.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;group&lt;/code&gt;&lt;/strong&gt; is usually &lt;strong&gt;&lt;code&gt;www-data&lt;/code&gt;&lt;/strong&gt; or &lt;strong&gt;&lt;code&gt;apache&lt;/code&gt;&lt;/strong&gt; but you may need to check this with your hosting provider.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can test your changes by pointing your browser to a few feed directories to see if the server returns XML. Remember to leave out the &lt;code&gt;index.xml&lt;/code&gt; file and specify the directory only. For example:&lt;br&gt;&lt;code&gt;https://example.com/your-post/feed/&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If your browser displays the RSS feed XML, you know the problem has been solved and can be reasonably confident that Googlebot won’t encounter the 403 error.&lt;/p&gt;
&lt;p&gt;This may not work if you’re running a VPS server for your site where some more in-depth configuration may be needed, such as editing your Apache configuration files. Also, &lt;code&gt;.htaccess&lt;/code&gt; is not used by other web servers such as NGINX. In these cases, your next port of call should be to contact your hosting provider. Tell them that you would like to add &lt;code&gt;index.xml&lt;/code&gt; to the directory index resources so that the XML file is served when a visitor lands in a directory. Most good hosting companies will be able to guide you on your options or make the change on your behalf. After you’ve applied the fix, be sure to go to your Google Search Console to revalidate the affected page.&lt;/p&gt;

&lt;div class="footnotes"&gt;
    &lt;p&gt;Photo by &lt;a href="https://unsplash.com/@lucian_alexe?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" target="_blank" rel="nofollow"&gt;Lucian Alexe&lt;/a&gt; on &lt;a href="https://unsplash.com/photos/l0w1ftNPZ9s?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" target="_blank" rel="nofollow"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;hr&gt;

&lt;section class="mt-4 pt-4"&gt;
    &lt;h2&gt;You may also like&lt;/h2&gt;

    &lt;div class="row"&gt;

        &lt;div class="col-md-6 col-lg-4 mb-4"&gt;
            &lt;div class="card h-100"&gt;
                &lt;a href="https://anothercoffee.net/drupal-to-wordpress-migration-guide/"&gt;
                        &lt;img src="https://anothercoffee.net/images/drupal-to-wordpress-migration-utilities-featured.jpg" class="card-img-top" alt="Drupal to WordPress Migration Guide"&gt;&lt;/a&gt;
                &lt;div class="card-body d-flex flex-column"&gt;
                    &lt;h5 class="card-title"&gt;&lt;a href="https://anothercoffee.net/drupal-to-wordpress-migration-guide/" class="listtitle"&gt;Drupal to WordPress Migration Guide&lt;/a&gt;&lt;/h5&gt;
                    &lt;div class="mb-2"&gt;
                        &lt;span&gt;&lt;time class="listdate" datetime="2025-01-03T15:30:30Z" title="Updated for 2025"&gt;Updated for 2025&lt;/time&gt;&lt;/span&gt;
                    &lt;/div&gt;
                    &lt;p class="card-text flex-grow-1"&gt;In this guide, you'll find insights drawn from almost 15 years of specialising in complex Drupal to WordPress migration projects. I'll walk you through the entire migration process, from the initial evaluation to post-launch considerations.&lt;/p&gt;
                &lt;/div&gt;
            &lt;/div&gt;
        &lt;/div&gt;

        &lt;div class="col-md-6 col-lg-4 mb-4"&gt;
            &lt;div class="card h-100"&gt;
                &lt;a href="https://anothercoffee.net/secure-your-ai-workflow-using-local-tokenisation/"&gt;
                        &lt;img src="https://anothercoffee.net/images/Secure-your-AI-workflow-using-local-tokenisation-in-PaigeSafe-featured.jpg" class="card-img-top" alt="Secure Your AI Workflow Using Local Tokenisation"&gt;&lt;/a&gt;
                &lt;div class="card-body d-flex flex-column"&gt;
                    &lt;h5 class="card-title"&gt;&lt;a href="https://anothercoffee.net/secure-your-ai-workflow-using-local-tokenisation/" class="listtitle"&gt;Secure Your AI Workflow Using Local Tokenisation&lt;/a&gt;&lt;/h5&gt;
                    &lt;div class="mb-2"&gt;
                        &lt;span&gt;&lt;time class="listdate" datetime="2024-11-12T13:59:03Z" title="12 November 2024"&gt;12 November 2024&lt;/time&gt;&lt;/span&gt;
                    &lt;/div&gt;

                        &lt;p class="card-text flex-grow-1"&gt;Don't leak confidential client data when using cloud-based LLMs. Secure your AI workflow with local tokenisation using PaigeSafe.&lt;/p&gt;
                &lt;/div&gt;
            &lt;/div&gt;
        &lt;/div&gt;

        &lt;div class="col-md-6 col-lg-4 mb-4"&gt;
            &lt;div class="card h-100"&gt;
                &lt;a href="https://anothercoffee.net/drupal-7-docker-containers-migration-projects/"&gt;
                        &lt;img src="https://anothercoffee.net/images/posts/Drupal-Docker-Containers-card-300-150.jpg" class="card-img-top" alt="How To Set Up Drupal 7 Docker Containers for Migration Projects"&gt;&lt;/a&gt;
                &lt;div class="card-body d-flex flex-column"&gt;
                    &lt;h5 class="card-title"&gt;&lt;a href="https://anothercoffee.net/drupal-7-docker-containers-migration-projects/" class="listtitle"&gt;How To Set Up Drupal 7 Docker Containers for Migration Projects&lt;/a&gt;&lt;/h5&gt;
                    &lt;div class="mb-2"&gt;
                        &lt;span&gt;&lt;time class="listdate" datetime="2024-09-09T13:25:15Z" title="09 September 2024"&gt;09 September 2024&lt;/time&gt;&lt;/span&gt;
                    &lt;/div&gt;

                        &lt;p class="card-text flex-grow-1"&gt;Learn how Docker is a valuable tool for Drupal 7 end of life migrations. In this post, I'll give a step-by-step guide to setting up a Drupal 7 container for your migration project.&lt;/p&gt;
                &lt;/div&gt;
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;

&lt;/section&gt;</description><category>Apache</category><category>Blog</category><category>Help</category><category>Migration</category><category>SEO</category><category>Sys Admin</category><category>Troubleshooting</category><category>WordPress</category><guid>https://anothercoffee.net/fixing-access-forbidden-403-issues-after-migrating-wordpress-to-a-static-site/</guid><pubDate>Thu, 09 Feb 2023 01:15:57 GMT</pubDate></item><item><title>Preserving SEO during a Drupal to WordPress migration</title><link>https://anothercoffee.net/drupal-wordpress-migration-seo/</link><dc:creator>Anthony Lopez-Vito</dc:creator><description>&lt;p&gt;This article is about preserving SEO during a &lt;a href="https://anothercoffee.net/drupal-to-wordpress-migration-tool/" title="Drupal to WordPress migration tool"&gt;Drupal to WordPress migration&lt;/a&gt;. It’s not about which platform is better. A web search will bring up many articles about the relative SEO merits of Drupal versus WordPress. I’ve found the best summary on that topic in a &lt;a href="https://www.drupal.org/node/1468704#comment-5690028"&gt;forum post&lt;/a&gt; by &lt;a href="https://www.drupal.org/u/john_b"&gt;Drupal.org user&lt;/a&gt; and developer, &lt;a href="http://www.digitprofessionals.com/"&gt;John Birchall&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;“The consensus that WordPress has better SEO is a guess…WordPress fans will guess one way, Drupal fans the other. In my opinion, WordPress SEO plugins work better for sites which are short on skill or time or money. If you want to give your clients hand-made quality, Drupal does rather a good job. This also goes for SEO. Nevertheless, lack of developer skill and client budget does sometimes mean we are better off simply ‘reheating’ and rolling out the wonderful prepackaged solutions available for WordPress.” (Slightly paraphrased for clarity.)
&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;If you’re reading this post, I will assume that you’ve already decided to migrate your site to WordPress. Rather than re-hashing the Drupal versus WordPress SEO debate, I’ll focus on some technical details that affect your SEO efforts when migrating from Drupal to WordPress. First, let’s start with some basics.&lt;/p&gt;

&lt;figure class="figure d-flex flex-column align-items-center"&gt;
    &lt;img class="figure-img img-fluid rounded" src="https://anothercoffee.net/images/one-way-url-drupal-wordpress-seo.jpg" alt="One-way traffic sign to symbolise preserving SEO during a Drupal to WordPress migration" width="800" height="284"&gt;
&lt;/figure&gt;

&lt;h2&gt;Can I preserve my SEO during the migration?&lt;/h2&gt;
&lt;p&gt;The quick answer is, &lt;em&gt;‘Yes’&lt;/em&gt;. It is possible to &lt;em&gt;preserve&lt;/em&gt; search engine optimisation during a migration. However, it can be easy to overlook the idea that you might end up with better SEO by revisiting your approach entirely. I’ve had site migrations where replicating optimisations from the Drupal version wouldn’t have made a significant impact in the business—or at the very least, where SEO was something that could be improved after the migration. If your site falls into this category, I would not recommend putting too much into preserving your Drupal optimisations. The money spent hiring me or anyone else may be better spent on improving the WordPress SEO &lt;em&gt;after&lt;/em&gt; exporting your Drupal content.&lt;/p&gt;
&lt;p&gt;There are some easy and low-cost approaches you can take such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Using or building an SEO-friendly and responsive WordPress theme.&lt;/li&gt;
&lt;li&gt;Installing SEO WordPress plugins.&lt;/li&gt;
&lt;li&gt;Creating higher quality content.&lt;/li&gt;
&lt;li&gt;Improving page load times. WordPress is a lighter CMS so you should get this ‘out of the box’ but you can lose any gains if, for example, you replicate calls to third-party libraries.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Of course, you should consult an expert if you rely heavily on search traffic. Preserving SEO may be vital for your site but it’s worth making a conscious assessment about the investment needed.&lt;/p&gt;
&lt;h2&gt;What kind of work is involved in preserving SEO?&lt;/h2&gt;
&lt;p&gt;The underlying differences between Drupal and WordPress mean preserving SEO often takes the bulk of a migration budget. The amount of work needed depends on what you’re trying to preserve. To give an example from a past migration project where SEO was vital, tasks included:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pre-migration auditing, mapping and analysing links on the Drupal site;&lt;/li&gt;
&lt;li&gt;Developing an SEO-friendly custom theme;&lt;/li&gt;
&lt;li&gt;Creating redirects for every URL that would change on WordPress;&lt;/li&gt;
&lt;li&gt;Ensuring we preserve &lt;a href="http://www.webopedia.com/TERM/O/on_page_optimization.html"&gt;on-page optimization&lt;/a&gt; for all high-value pages;&lt;/li&gt;
&lt;li&gt;Making further adjustments as directed by an SEO consultant after she analysed her webmaster tools.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Remember that SEO isn’t a one-time effort. The project needed multiple months of on-going work. Further, I was taking direction from the client’s SEO consultant who incurred her own separate fees. Thus the client allocated a sizeable budget for SEO alone. In his case it was worth the money because the Drupal site earned him many times that amount on revenue from search traffic. Minimising any negative impact on SEO after migrating to WordPress was a priority.&lt;/p&gt;
&lt;p&gt;How much time and money &lt;em&gt;you’ll&lt;/em&gt; need to allocate for your migration depends on a range of factors that are very specific to your site. You’ll only know after doing some in-depth analysis and documentation. Here’s an article on Search Engine Journal that I send to clients when they ask about the SEO impact of a CMS migration: &lt;a title="How To Avoid SEO Disaster During a Website Redesign – Top Marketer Concerns" href="http://www.searchenginejournal.com/how-to-avoid-seo-disaster-during-a-website-redesign/"&gt;How To Avoid SEO Disaster During a Website Redesign&lt;/a&gt;. It’s worth a read and afterwards you can think about how much SEO should play a part of your site migration project.&lt;/p&gt;
&lt;h2&gt;SEO considerations&lt;/h2&gt;
&lt;p&gt;What exactly will affect SEO during a typical Drupal to WordPress migration? Here are a few SEO considerations to keep in mind for your migration project. It’s certainly not an exhaustive list but paying attention to these points should cover the basics.&lt;/p&gt;
&lt;h3&gt;On-page SEO&lt;/h3&gt;
&lt;p&gt;A lot of the on-page SEO comes over as a natural side-effect of most content migration processes. For example, page titles, content keyword optimisation, sub-heading tags, image file names and internal linking are all embedded into the Drupal node content. These remain intact when the nodes are imported into WordPress, unless content cleaning or other manipulation is part of the project. &lt;/p&gt;
&lt;p&gt;Other areas, such as URL structure, meta data and load speed will need work due to the differences of the two systems.&lt;/p&gt;
&lt;h3&gt;Off-site SEO&lt;/h3&gt;
&lt;p&gt;Off-site SEO will be unaffected by a CMS migration as long as you have the necessary redirects set up to catch URL changes for any backlinks. This is an effort that’s external to the site so not within the scope of this article.&lt;/p&gt;
&lt;h3&gt;Drupal aliases vs WordPress permalinks&lt;/h3&gt;
&lt;p&gt;URL structure is one of the SEO areas that will change after a CMS migration. A big part is because of some important differences between how Drupal and WordPress handle URLs. Drupal creates URLs using either the node ID or a URL alias stored in its database’s &lt;code&gt;url_alias&lt;/code&gt; table. Take a look at some sample entries.&lt;/p&gt;

    &lt;figure class="figure d-flex flex-column align-items-center"&gt;
        &lt;img class="figure-img img-fluid rounded" src="https://anothercoffee.net/images/drupal-url_alias-table.png" alt="Drupal url_alias table" width="430" height="167"&gt;
        &lt;figcaption&gt;Drupal url_alias table&lt;/figcaption&gt;
    &lt;/figure&gt;

&lt;p&gt;You’ll see an entry for &lt;code&gt;node/28&lt;/code&gt; associated with a URL alias &lt;code&gt;projects/april&lt;/code&gt;. This means that under Drupal, the page with node ID &lt;code&gt;28&lt;/code&gt; can be accessed using either &lt;em&gt;http://example.com/node/28&lt;/em&gt; or &lt;em&gt;http://example.com/projects/april&lt;/em&gt;. Not shown is that content can have multiple aliases. The site could therefore also have another entry &lt;code&gt;node/28&lt;/code&gt; associated with URL alias &lt;code&gt;projects-april&lt;/code&gt; and yet another with &lt;code&gt;my-projects/april&lt;/code&gt;. You will always be able to find a page by appending the URL alias entry in the &lt;code&gt;url_alias&lt;/code&gt; table to the site’s domain name.  &lt;/p&gt;
&lt;p&gt;WordPress has a different mechanism for creating URLs. Rather than relying on database entries, it generates &lt;a href="https://codex.wordpress.org/Using_Permalinks" title="WordPress codex: Using Permalinks"&gt;rewrite rules&lt;/a&gt; and builds the permalink dynamically depending on your &lt;a href="https://codex.wordpress.org/Using_Permalinks#Choosing_your_permalink_structure" title="WordPress codex: Choosing your permalink structure"&gt;permalink settings&lt;/a&gt;. WordPress’ closest equivalent to the Drupal &lt;code&gt;url_alias&lt;/code&gt; is its &lt;a title="Understanding Permalinks and Slugs in WordPress" href="https://bloggertowp.org/tutorials/user-guide/permalinks-and-slugs/"&gt;permalink slug&lt;/a&gt; stored as the &lt;code&gt;post_name&lt;/code&gt; in the &lt;code&gt;wp_posts&lt;/code&gt; table. Under my standard Drupal to WordPress migration, I migrate over the Drupal aliases by converting them into WordPress post name slugs. (See the table mapping in a separate article, &lt;a title="Drupal to WordPress migration: posts table mapping" href="http://192.168.1.30:8100/drupal-to-wordpress-migration-posts-table-mapping/"&gt;Drupal to WordPress migration: posts table mapping&lt;/a&gt;.) If you have the &lt;em&gt;Post name&lt;/em&gt; structure set in the WordPress Permalinks Settings, you’d then find the Project April page at either &lt;em&gt;http://example.com/?p=28&lt;/em&gt; or &lt;em&gt;http://example.com/april/&lt;/em&gt;. Note that this would cause an SEO problem because the new WordPress link does not match the old Drupal link.&lt;/p&gt;

&lt;figure class="figure d-flex flex-column align-items-center"&gt;
    &lt;img class="figure-img img-fluid rounded" src="https://anothercoffee.net/images/wordpress-wp_posts-table.png" alt="WordPress wp_posts table" width="270" height="171"&gt;
    &lt;figcaption&gt;WordPress wp_posts table&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;We would have to do some extra work to solve this problem. For example, if the &lt;em&gt;april&lt;/em&gt; node was a page, we could create and link to a parent &lt;em&gt;Projects&lt;/em&gt; page to create the Drupal &lt;em&gt;http://example.com/projects/april&lt;/em&gt; structure. Alternatively, if it was a post, we could create a &lt;em&gt;projects&lt;/em&gt; category or tag and set the Category base or Tag base setting. We could also create .htaccess redirects or use one of the many WordPress &lt;a href="https://wordpress.org/plugins/redirection/" title="Redirection plugin for WordPress"&gt;redirection plugins&lt;/a&gt;. The exact solution would depend on your project’s requirements.&lt;/p&gt;
&lt;h3 id="wordpress_permalink_constraints"&gt;WordPress permalinks have more constraints&lt;/h3&gt;
&lt;p&gt;Aside from the differences in how URLs are stored and generated, you should also be aware of WordPress permalink constrains. These will have a big impact on the amount of work needed to preserve your Drupal SEO when migrating to WordPress. I’ll briefly summarise them below.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The Drupal URL alias has a 255 character limit but the WordPress the &lt;code&gt;post_name&lt;/code&gt; field stores only 200 characters. Make sure to keep track of any truncated posts names and create a corresponding redirect.&lt;/li&gt;
&lt;li&gt;Since there’s no WordPress equivalent of the Drupal &lt;code&gt;url_alias&lt;/code&gt; table, you’ll need to decide which alias will be converted into the post name. You should create separate redirects for the other aliases.&lt;/li&gt;
&lt;li&gt;WordPress slugs which create the permalink are essentially a URL-friendly version of the post title. WordPress automatically cleans up the post title to create slugs for new content but you may encounter problems when migrating Druapl aliases into slugs. Characters that would be valid within a Drupal alias are invalid as a WordPress slug. For example, you cannot have forward slashes, accented characters and quotes in your WordPress slug. You’ll need to clean up and keep track of any problem aliases, otherwise WordPress will not be able to serve the page.&lt;/li&gt;
&lt;li&gt;As previously mentioned, under Drupal you will always be able to find a page by appending the URL alias entry to the site’s domain name. WordPress does not store any records of its URL structure. You will end up with broken links and a potential SEO nightmare if you change the Permalink structure settings without consideration.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Remember your Drupal taxonomies&lt;/h3&gt;
&lt;p&gt;It’s easy to forget Drupal’s powerful taxonomy system is capable of generating listings that attract valuable traffic. Use webmaster tools to audit your site traffic to pick up on any such listing pages. Unlike Drupal which allows for multiple vocabularies, WordPress only offers one set of &lt;em&gt;categories&lt;/em&gt; and &lt;em&gt;tags&lt;/em&gt; out of the box. Replicating your Drupal taxonomy listings in WordPress may take considerable development but a quick fix may be to manually replicate the important listings pages. Obviously the size of your site will dictate if this will be feasible.&lt;/p&gt;
&lt;h3&gt;Menu and breadcrumb navigation&lt;/h3&gt;
&lt;p&gt;Menu structure and breadcrumb navigation is often an important part of your SEO. Ensure that your selected WordPress theme both supports breadcrumbs (some don’t) and the same type of breadcrumbs e.g. hierarchy, attribute and history-based breadcrumbs.&lt;/p&gt;
&lt;h3&gt;Migrate metatags generated by Drupal metatag modules&lt;/h3&gt;
&lt;p&gt;Also remember that you may have installed modules that generate metatag information contributing to your SEO. Export these from the relevant Drupal table and import them into the WordPress database using the format for your preferred WordPress metatag plugin. For example, if you used the Drupal &lt;a href="https://www.drupal.org/project/metatag" title="Drupal metatag module"&gt;metatag module&lt;/a&gt; and would like to use the WordPress &lt;a href="https://wordpress.org/plugins/add-meta-tags/" title="Add-Meta-Tags plugin for WordPress"&gt;Add-Meta-Tags plugin&lt;/a&gt;, you’ll need to extract data from the &lt;code&gt;metatags&lt;/code&gt; table and insert them into &lt;code&gt;wp_postmeta&lt;/code&gt; table as a &lt;code&gt;meta_key&lt;/code&gt; and &lt;code&gt;meta_value&lt;/code&gt; pair. Keep in mind that some investigative work will be necessary to find out how your preferred modules and plugins store their data.&lt;/p&gt;
&lt;h3&gt;Search engine visibility&lt;/h3&gt;
&lt;p&gt;WordPress has a setting to discourage search engines from indexing site. It can be found in &lt;em&gt;Settings &amp;gt; Reading &amp;gt; Search Engine Visibility&lt;/em&gt;. It’s normal to have this checked during development but make sure you disable it when launching.&lt;/p&gt;
&lt;h3&gt;Load speed&lt;/h3&gt;
&lt;p&gt;WordPress, in general, requires fewer hosting resources than Drupal. You could very well find that a slow site on an under-performing server running Drupal becomes more responsive under WordPress. Don’t take this for granted, however. Use the migration as an opportunity to make improvements. Thoroughly vet plugin candidates to make sure they’re not pulling in third-party scripts that will increase page load times. Also avoid bloated page-builder themes. In my experience, these can be terrible for load speed as they try to cram in every conceivable bit functionality, thereby drastically slowing down what could have been a nimble site.&lt;/p&gt;
&lt;h2&gt;Preserving SEO during a Drupal to WordPress migration can be lots of work&lt;/h2&gt;
&lt;p&gt;As may have gathered by now, the amount of work and budget needed will reply on many factors. It’s not possible to prescribe what will be necessary for your site without in-depth detail about your configuration and requirements. Nevertheless, I hopefully will have given you enough information to get started with planning an approach.&lt;/p&gt;
&lt;div style="border-top: 3px solid #BABECB;margin: 50px 0 0 0;padding: 20px 0 0 0; font-style:italic;"&gt;
A little plug to keep the lights running. If you think all of this work is too much trouble, please consider &lt;a href="http://192.168.1.30:8100/#contact"&gt;hiring me&lt;/a&gt; for your Drupal to WordPress migration project.
&lt;/div&gt;

&lt;div class="alert alert-info text-center"&gt;
&lt;h3 style="font-size:1.5em"&gt;&lt;a href="https://anothercoffee.net/drupal-to-wordpress-migration-service/" title="Drupal to WordPress migration"&gt;Drupal to WordPress migration service&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Any Drupal version · All content · Custom content types · SEO · Plugins&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;If you’re not sure how to make the appropriate changes or would simply like someone else to do the work, please &lt;a href="https://anothercoffee.net/drupal-to-wordpress-migration-service/#contact" title="Get an estimate for Drupal to WordPress migration"&gt;request a quotation&lt;/a&gt; for my &lt;strong&gt;&lt;a href="https://anothercoffee.net/drupal-to-wordpress-migration-service/" title="Ask about Drupal to WordPress migration service"&gt;Drupal to WordPress migration service&lt;/a&gt;.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;button class="cta-button"&gt;
    &lt;a href="https://forms.gle/ywPt7faLawXoqcpF7" target="_blank" rel="nofollow" title="Contact me to inquire about my Drupal to WordPress migration service"&gt;Get a quote&lt;/a&gt;
&lt;/button&gt;

&lt;/div&gt;</description><category>Blog</category><category>Drupal</category><category>Help</category><category>Migration</category><category>SEO</category><category>WordPress</category><guid>https://anothercoffee.net/drupal-wordpress-migration-seo/</guid><pubDate>Wed, 16 Mar 2016 00:28:53 GMT</pubDate></item></channel></rss>