{"id":114,"date":"2026-11-03T08:00:00","date_gmt":"2026-11-03T07:00:00","guid":{"rendered":"https:\/\/hoja.in\/blog\/moving-a-wordpress-blog-from-a-subdomain-to-blog\/"},"modified":"2026-10-16T14:00:13","modified_gmt":"2026-10-16T12:00:13","slug":"moving-a-wordpress-blog-from-a-subdomain-to-blog","status":"publish","type":"post","link":"https:\/\/hoja.in\/blog\/moving-a-wordpress-blog-from-a-subdomain-to-blog\/","title":{"rendered":"Moving a WordPress blog from a subdomain to \/blog"},"content":{"rendered":"<p>Hi folks,<\/p>\n<p>My blog lived at blog.hoja.in since 2016, on its own WordPress installation, next to the TYPO3 site on hoja.in. This year, together with the TYPO3 upgrade, I moved it to <code>hoja.in\/blog<\/code>. One domain, one place for visitors, and the blog&#8217;s links and authority count for the main site instead of a separate host.<\/p>\n<p>The move itself is not complicated, but WordPress stores its own URL in many places, some of them serialized, some JSON-encoded. Here is how I did it, with the commands from my runbook.<\/p>\n<h2>Step 1: put the files in the right place<\/h2>\n<p>The TYPO3 project has its web root in <code>public\/<\/code>, so WordPress went into <code>public\/blog\/<\/code>. Two things make this work next to TYPO3:<\/p>\n<ul>\n<li>WordPress needs its own <code>.htaccess<\/code> in <code>public\/blog\/<\/code> with <code>RewriteBase \/blog\/<\/code>. For Apache, the rewrite rules of the deepest directory win, so requests below <code>\/blog\/<\/code> go to WordPress&#8217; <code>index.php<\/code>, not to TYPO3&#8217;s.<\/li>\n<li>The table prefix stays as it was (<code>myblog_<\/code> in my case). Changing it during a move is an extra risk for no gain.<\/li>\n<\/ul>\n<pre><code class=\"language-apache\"># public\/blog\/.htaccess\n# BEGIN WordPress\n&lt;IfModule mod_rewrite.c&gt;\nRewriteEngine On\nRewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]\nRewriteBase \/blog\/\nRewriteRule ^index.php$ - [L]\nRewriteCond %{REQUEST_FILENAME} !-f\nRewriteCond %{REQUEST_FILENAME} !-d\nRewriteRule . \/blog\/index.php [L]\n&lt;\/IfModule&gt;\n# END WordPress<\/code><\/pre>\n<h2>Step 2: siteurl and home<\/h2>\n<p>WordPress has two options for its address: <code>siteurl<\/code> (where the WordPress files are) and <code>home<\/code> (the public address). When both are wrong, you cannot even log in to fix them, because wp-admin redirects to the old host. I set them as constants in the config instead, which override the database values:<\/p>\n<pre><code class=\"language-php\">\/\/ wp-config-production.php (on the server, not in git)\ndefine('WP_HOME', 'https:\/\/hoja.in\/blog');\ndefine('WP_SITEURL', 'https:\/\/hoja.in\/blog');\ndefine('DISALLOW_FILE_EDIT', true);<\/code><\/pre>\n<p>My <code>wp-config.php<\/code> only decides which file to load: <code>wp-config-ddev.php<\/code> when <code>IS_DDEV_PROJECT<\/code> is set, otherwise <code>wp-config-production.php<\/code>. The local file sets the same constants to <code>https:\/\/hoja.in\/blog<\/code>. So the same code runs locally and on the server, and no password is in git.<\/p>\n<h2>Step 3: replace the old URLs in the database<\/h2>\n<p>The constants fix where WordPress <em>thinks<\/em> it lives. They do not fix the thousands of old URLs inside post content, image links, widget settings and plugin options. Never do this with a plain SQL <code>REPLACE()<\/code>: many values are PHP-serialized, where the string length is part of the data. <code>s:22:\"http:\/\/blog.hoja.in\/x\"<\/code> with a longer URL inside and the old length in front is broken, and WordPress silently drops the whole option. <code>wp search-replace<\/code> unserializes, replaces and serializes again.<\/p>\n<p>Always run it with <code>--dry-run<\/code> first. On my local copy, before exporting it for production:<\/p>\n<pre><code class=\"language-bash\">wp search-replace 'https:\/\/hoja.in\/blog' 'https:\/\/hoja.in\/blog' \n  --all-tables-with-prefix --precise --dry-run --report-changed-only<\/code><\/pre>\n<pre><code class=\"language-text\">Table                    Column            Replacements  Type\nmyblog_options           option_value      4             PHP\nmyblog_posts             post_content      10            PHP\nmyblog_posts             guid              50            PHP\nmyblog_yoast_indexable   permalink         26            PHP\nmyblog_yoast_indexable   twitter_image     3             PHP\nmyblog_yoast_indexable   open_graph_image  3             PHP\nSuccess: 96 replacements to be made.<\/code><\/pre>\n<p>Read this table. Does the number of posts look right? Is a table missing that you expected? <code>--all-tables-with-prefix<\/code> includes plugin tables like Yoast&#8217;s, which a plain <code>wp search-replace<\/code> would skip because they are not registered core tables. <code>--precise<\/code> makes it use PHP for every row instead of SQL where it can, slower but safe for serialized data. Then run the same command without <code>--dry-run<\/code>. If you start from the production dump instead, replace both schemes:<\/p>\n<pre><code class=\"language-bash\">wp core update-db\nwp search-replace 'https:\/\/blog.hoja.in' 'https:\/\/hoja.in\/blog' --all-tables-with-prefix --precise\nwp search-replace 'http:\/\/blog.hoja.in'  'https:\/\/hoja.in\/blog' --all-tables-with-prefix --precise<\/code><\/pre>\n<h3>The guid column<\/h3>\n<p>You see <code>guid<\/code> in the list above. The WordPress documentation on changing the site URL is very clear that the GUID should not be changed, because feed readers use it to recognise posts they already know. <code>--skip-columns=guid<\/code> does that. My runbook does not skip it; if I did it again, I would add the option.<\/p>\n<h3>The URLs that hide in JSON<\/h3>\n<p>After the replacement I searched once more for the bare old host name, in a dry run:<\/p>\n<pre><code class=\"language-bash\">wp search-replace 'blog.hoja.in' 'x' --all-tables-with-prefix --dry-run --report-changed-only<\/code><\/pre>\n<p>Three rows were left, in <code>myblog_yoast_indexable.open_graph_image_meta<\/code>. That column holds JSON, and JSON escapes slashes: the value contains <code>http:\/\/blog.hoja.in\/wp-content\/...<\/code>, so a search for <code>http:\/\/blog.hoja.in<\/code> never matches it. For Yoast the clean fix is to rebuild its index after the move, which is a step in my runbook anyway:<\/p>\n<pre><code class=\"language-bash\">wp yoast index --reindex --skip-confirmation<\/code><\/pre>\n<p>For other plugins that store JSON, search for the host name alone, look at the rows, and replace the escaped form explicitly if needed.<\/p>\n<h2>Step 4: 301 from the old subdomain<\/h2>\n<p>Every old link on other sites, in search results and in my own old posts points to blog.hoja.in. Those must keep working, permanently. In the document root of the subdomain I put only one <code>.htaccess<\/code>:<\/p>\n<pre><code class=\"language-apache\">RewriteEngine On\nRewriteRule ^(.*)$ https:\/\/hoja.in\/blog\/$1 [R=301,L]<\/code><\/pre>\n<p>It keeps the path, so <code>blog.hoja.in\/some-post\/<\/code> lands on <code>hoja.in\/blog\/some-post\/<\/code> in one hop. The permalink structure (<code>\/%postname%\/<\/code>) stays the same, so no per-post redirects are needed. If you change the permalink structure at the same time, do it in a separate step; two changes at once are hard to debug.<\/p>\n<h2>Step 5: check what search engines will see<\/h2>\n<p>After the switch, I check with curl, not with the browser (the browser cache lies after redirects):<\/p>\n<pre><code class=\"language-bash\"># one hop, permanent, path kept\ncurl -sI https:\/\/blog.hoja.in\/some-post\/ | grep -iE '^(HTTP|location)'\n\n# canonical of a post points to the new address\ncurl -s https:\/\/hoja.in\/blog\/some-post\/ | grep -o '&lt;link rel=\"canonical\"[^&gt;]*&gt;'\n\n# the sitemap lists only new URLs\ncurl -s https:\/\/hoja.in\/blog\/sitemap_index.xml | grep -c 'blog.hoja.in'<\/code><\/pre>\n<p>The last command must print <code>0<\/code>. Yoast generates the canonical and the sitemap from its indexables, which is one more reason to reindex. Finally, <code>robots.txt<\/code> of the main site now lists both sitemaps, the TYPO3 one and the blog one:<\/p>\n<pre><code class=\"language-text\">Sitemap: https:\/\/hoja.in\/sitemap.xml\nSitemap: https:\/\/hoja.in\/blog\/sitemap_index.xml<\/code><\/pre>\n<h2>Rollback<\/h2>\n<p>Keep the old database dump and the old blog folder until you are sure. The rollback in my runbook is three lines: restore the dump, restore the folder, remove the subdomain redirect. Because the old installation was never changed in place, that really works.<\/p>\n<p>Moving a blog is one of those jobs where a dry run costs five minutes and a mistake costs your search traffic. Use the dry run. Cheers!<\/p>\n<h2>Further reading<\/h2>\n<ul>\n<li><a href=\"https:\/\/developer.wordpress.org\/cli\/commands\/search-replace\/\">WP-CLI: wp search-replace<\/a><\/li>\n<li><a href=\"https:\/\/developer.wordpress.org\/advanced-administration\/upgrade\/migrating\/\">WordPress: migrating WordPress<\/a><\/li>\n<li><a href=\"https:\/\/developer.wordpress.org\/advanced-administration\/wordpress\/wp-config\/\">WordPress: editing wp-config.php (WP_HOME, WP_SITEURL)<\/a><\/li>\n<li><a href=\"https:\/\/httpd.apache.org\/docs\/current\/mod\/mod_rewrite.html\">Apache mod_rewrite<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>blog.hoja.in became hoja.in\/blog: WP_HOME and WP_SITEURL, wp search-replace with a dry run, URLs hidden in JSON, a 301 from the old subdomain, and canonical and sitemap checks.<\/p>\n","protected":false},"author":1,"featured_media":115,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[22],"tags":[45,41,42],"class_list":["post-114","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-wordpress","tag-devops","tag-seo","tag-wordpress"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.7 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Moving a WordPress blog from a subdomain to \/blog<\/title>\n<meta name=\"description\" content=\"Move WordPress from a subdomain to \/blog: WP_HOME, wp search-replace with --dry-run, serialized and JSON data, 301 redirects and sitemap checks.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/hoja.in\/blog\/moving-a-wordpress-blog-from-a-subdomain-to-blog\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Moving a WordPress blog from a subdomain to \/blog\" \/>\n<meta property=\"og:description\" content=\"Move WordPress from a subdomain to \/blog: WP_HOME, wp search-replace with --dry-run, serialized and JSON data, 301 redirects and sitemap checks.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/hoja.in\/blog\/moving-a-wordpress-blog-from-a-subdomain-to-blog\/\" \/>\n<meta property=\"og:site_name\" content=\"Hoja Mustaffa Abdul Latheef \u2013 Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-11-03T07:00:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/hoja.in\/blog\/wp-content\/uploads\/2026\/10\/moving-a-wordpress-blog-from-a-subdomain-to-blog.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Hoja Mustaffa Abdul Latheef\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@hojaonline\" \/>\n<meta name=\"twitter:site\" content=\"@hojaonline\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Hoja Mustaffa Abdul Latheef\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/moving-a-wordpress-blog-from-a-subdomain-to-blog\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/moving-a-wordpress-blog-from-a-subdomain-to-blog\\\/\"},\"author\":{\"name\":\"Hoja Mustaffa Abdul Latheef\",\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/#\\\/schema\\\/person\\\/e6fbd54c2061674d8ea3e7861d858c7b\"},\"headline\":\"Moving a WordPress blog from a subdomain to \\\/blog\",\"datePublished\":\"2026-11-03T07:00:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/moving-a-wordpress-blog-from-a-subdomain-to-blog\\\/\"},\"wordCount\":815,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/#\\\/schema\\\/person\\\/e6fbd54c2061674d8ea3e7861d858c7b\"},\"image\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/moving-a-wordpress-blog-from-a-subdomain-to-blog\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/hoja.in\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/moving-a-wordpress-blog-from-a-subdomain-to-blog.jpg\",\"keywords\":[\"DevOps\",\"SEO\",\"WordPress\"],\"articleSection\":[\"WordPress\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/hoja.in\\\/blog\\\/moving-a-wordpress-blog-from-a-subdomain-to-blog\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/moving-a-wordpress-blog-from-a-subdomain-to-blog\\\/\",\"url\":\"https:\\\/\\\/hoja.in\\\/blog\\\/moving-a-wordpress-blog-from-a-subdomain-to-blog\\\/\",\"name\":\"Moving a WordPress blog from a subdomain to \\\/blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/moving-a-wordpress-blog-from-a-subdomain-to-blog\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/moving-a-wordpress-blog-from-a-subdomain-to-blog\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/hoja.in\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/moving-a-wordpress-blog-from-a-subdomain-to-blog.jpg\",\"datePublished\":\"2026-11-03T07:00:00+00:00\",\"description\":\"Move WordPress from a subdomain to \\\/blog: WP_HOME, wp search-replace with --dry-run, serialized and JSON data, 301 redirects and sitemap checks.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/moving-a-wordpress-blog-from-a-subdomain-to-blog\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/hoja.in\\\/blog\\\/moving-a-wordpress-blog-from-a-subdomain-to-blog\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/moving-a-wordpress-blog-from-a-subdomain-to-blog\\\/#primaryimage\",\"url\":\"https:\\\/\\\/hoja.in\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/moving-a-wordpress-blog-from-a-subdomain-to-blog.jpg\",\"contentUrl\":\"https:\\\/\\\/hoja.in\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/moving-a-wordpress-blog-from-a-subdomain-to-blog.jpg\",\"width\":1200,\"height\":630,\"caption\":\"From subdomain to \\\/blog\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/moving-a-wordpress-blog-from-a-subdomain-to-blog\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/hoja.in\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Moving a WordPress blog from a subdomain to \\\/blog\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/hoja.in\\\/blog\\\/\",\"name\":\"Hoja Mustaffa Abdul Latheef \u2013 Blog\",\"description\":\"Notes from daily work with TYPO3, PHP and AI-assisted engineering\",\"publisher\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/#\\\/schema\\\/person\\\/e6fbd54c2061674d8ea3e7861d858c7b\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/hoja.in\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/#\\\/schema\\\/person\\\/e6fbd54c2061674d8ea3e7861d858c7b\",\"name\":\"Hoja Mustaffa Abdul Latheef\",\"logo\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/#\\\/schema\\\/person\\\/image\\\/\"},\"description\":\"Senior TYPO3 Developer at jweiland.net, TYPO3 CMS Certified Developer. I write about TYPO3 upgrades, extension development, PHP and AI-assisted engineering with Claude Code.\",\"sameAs\":[\"https:\\\/\\\/hoja.in\\\/\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Moving a WordPress blog from a subdomain to \/blog","description":"Move WordPress from a subdomain to \/blog: WP_HOME, wp search-replace with --dry-run, serialized and JSON data, 301 redirects and sitemap checks.","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:\/\/hoja.in\/blog\/moving-a-wordpress-blog-from-a-subdomain-to-blog\/","og_locale":"en_US","og_type":"article","og_title":"Moving a WordPress blog from a subdomain to \/blog","og_description":"Move WordPress from a subdomain to \/blog: WP_HOME, wp search-replace with --dry-run, serialized and JSON data, 301 redirects and sitemap checks.","og_url":"https:\/\/hoja.in\/blog\/moving-a-wordpress-blog-from-a-subdomain-to-blog\/","og_site_name":"Hoja Mustaffa Abdul Latheef \u2013 Blog","article_published_time":"2026-11-03T07:00:00+00:00","og_image":[{"width":1200,"height":630,"url":"https:\/\/hoja.in\/blog\/wp-content\/uploads\/2026\/10\/moving-a-wordpress-blog-from-a-subdomain-to-blog.jpg","type":"image\/jpeg"}],"author":"Hoja Mustaffa Abdul Latheef","twitter_card":"summary_large_image","twitter_creator":"@hojaonline","twitter_site":"@hojaonline","twitter_misc":{"Written by":"Hoja Mustaffa Abdul Latheef","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/hoja.in\/blog\/moving-a-wordpress-blog-from-a-subdomain-to-blog\/#article","isPartOf":{"@id":"https:\/\/hoja.in\/blog\/moving-a-wordpress-blog-from-a-subdomain-to-blog\/"},"author":{"name":"Hoja Mustaffa Abdul Latheef","@id":"https:\/\/hoja.in\/blog\/#\/schema\/person\/e6fbd54c2061674d8ea3e7861d858c7b"},"headline":"Moving a WordPress blog from a subdomain to \/blog","datePublished":"2026-11-03T07:00:00+00:00","mainEntityOfPage":{"@id":"https:\/\/hoja.in\/blog\/moving-a-wordpress-blog-from-a-subdomain-to-blog\/"},"wordCount":815,"commentCount":0,"publisher":{"@id":"https:\/\/hoja.in\/blog\/#\/schema\/person\/e6fbd54c2061674d8ea3e7861d858c7b"},"image":{"@id":"https:\/\/hoja.in\/blog\/moving-a-wordpress-blog-from-a-subdomain-to-blog\/#primaryimage"},"thumbnailUrl":"https:\/\/hoja.in\/blog\/wp-content\/uploads\/2026\/10\/moving-a-wordpress-blog-from-a-subdomain-to-blog.jpg","keywords":["DevOps","SEO","WordPress"],"articleSection":["WordPress"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/hoja.in\/blog\/moving-a-wordpress-blog-from-a-subdomain-to-blog\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/hoja.in\/blog\/moving-a-wordpress-blog-from-a-subdomain-to-blog\/","url":"https:\/\/hoja.in\/blog\/moving-a-wordpress-blog-from-a-subdomain-to-blog\/","name":"Moving a WordPress blog from a subdomain to \/blog","isPartOf":{"@id":"https:\/\/hoja.in\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/hoja.in\/blog\/moving-a-wordpress-blog-from-a-subdomain-to-blog\/#primaryimage"},"image":{"@id":"https:\/\/hoja.in\/blog\/moving-a-wordpress-blog-from-a-subdomain-to-blog\/#primaryimage"},"thumbnailUrl":"https:\/\/hoja.in\/blog\/wp-content\/uploads\/2026\/10\/moving-a-wordpress-blog-from-a-subdomain-to-blog.jpg","datePublished":"2026-11-03T07:00:00+00:00","description":"Move WordPress from a subdomain to \/blog: WP_HOME, wp search-replace with --dry-run, serialized and JSON data, 301 redirects and sitemap checks.","breadcrumb":{"@id":"https:\/\/hoja.in\/blog\/moving-a-wordpress-blog-from-a-subdomain-to-blog\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/hoja.in\/blog\/moving-a-wordpress-blog-from-a-subdomain-to-blog\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/hoja.in\/blog\/moving-a-wordpress-blog-from-a-subdomain-to-blog\/#primaryimage","url":"https:\/\/hoja.in\/blog\/wp-content\/uploads\/2026\/10\/moving-a-wordpress-blog-from-a-subdomain-to-blog.jpg","contentUrl":"https:\/\/hoja.in\/blog\/wp-content\/uploads\/2026\/10\/moving-a-wordpress-blog-from-a-subdomain-to-blog.jpg","width":1200,"height":630,"caption":"From subdomain to \/blog"},{"@type":"BreadcrumbList","@id":"https:\/\/hoja.in\/blog\/moving-a-wordpress-blog-from-a-subdomain-to-blog\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/hoja.in\/blog\/"},{"@type":"ListItem","position":2,"name":"Moving a WordPress blog from a subdomain to \/blog"}]},{"@type":"WebSite","@id":"https:\/\/hoja.in\/blog\/#website","url":"https:\/\/hoja.in\/blog\/","name":"Hoja Mustaffa Abdul Latheef \u2013 Blog","description":"Notes from daily work with TYPO3, PHP and AI-assisted engineering","publisher":{"@id":"https:\/\/hoja.in\/blog\/#\/schema\/person\/e6fbd54c2061674d8ea3e7861d858c7b"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/hoja.in\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/hoja.in\/blog\/#\/schema\/person\/e6fbd54c2061674d8ea3e7861d858c7b","name":"Hoja Mustaffa Abdul Latheef","logo":{"@id":"https:\/\/hoja.in\/blog\/#\/schema\/person\/image\/"},"description":"Senior TYPO3 Developer at jweiland.net, TYPO3 CMS Certified Developer. I write about TYPO3 upgrades, extension development, PHP and AI-assisted engineering with Claude Code.","sameAs":["https:\/\/hoja.in\/"]}]}},"_links":{"self":[{"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/posts\/114","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/comments?post=114"}],"version-history":[{"count":1,"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/posts\/114\/revisions"}],"predecessor-version":[{"id":180,"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/posts\/114\/revisions\/180"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/media\/115"}],"wp:attachment":[{"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/media?parent=114"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/categories?post=114"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/tags?post=114"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}