{"id":1079,"date":"2026-10-31T16:34:05","date_gmt":"2026-10-31T16:34:05","guid":{"rendered":"https:\/\/www.vps.tc\/blog\/?p=1079"},"modified":"2026-10-31T15:40:49","modified_gmt":"2026-10-31T15:40:49","slug":"multilingual-wordpress-site","status":"publish","type":"post","link":"https:\/\/www.vps.tc\/blog\/en\/multilingual-wordpress-site\/","title":{"rendered":"How to Build a Multilingual WordPress Site"},"content":{"rendered":"<div class=\"aiw-summary\" id=\"aiw-ozet\">\n<p class=\"aiw-summary-title\">Quick Summary &#8211; Multilingual WordPress Site<\/p>\n<p>You can publish English pages under \/en\/ without changing existing Turkish URLs. This hypothetical staging scenario uses one WordPress installation and Polylang; translated content is prepared separately.<\/p>\n<ul>\n<li><strong>Recovery Comes First<\/strong> \u2014 Back up the database and files together, verify restoration in a separate environment, and restrict staging access.<\/li>\n<li><strong>Workflow Fit<\/strong> \u2014 Compare Polylang, WPML, and TranslatePress against editorial needs, compatibility, licensing, and data portability.<\/li>\n<li><strong>Stable Language URLs<\/strong> \u2014 Keep Turkish at the root, hide the default language code, and publish English content under \/en\/.<\/li>\n<li><strong>Linked Translation Pairs<\/strong> \u2014 Link pages as translations of each other, then check menus, forms, and theme strings separately.<\/li>\n<li><strong>Separate SEO Roles<\/strong> \u2014 Use hreflang to identify language alternatives and give each language page a canonical pointing to its own URL.<\/li>\n<li><strong>Publishing Approval Checks<\/strong> \u2014 Do not publish content until URL, redirect, language switcher, and indexing checks pass in both languages.<\/li>\n<\/ul>\n<\/div>\n<p class=\"aiw-lead\">You can publish English content without changing your existing Turkish page URLs. To build a multilingual WordPress site, prepare a backed-up staging copy, choose a language plugin, and link translation pairs. Keep Turkish at the root and English under \/en\/; before launch, verify menus, the language switcher, reciprocal hreflang references, and each page&#039;s self-referencing canonical.<\/p>\n<div class=\"aiw-toc\" style=\"border:1px solid #dbe3ea;border-radius:8px;padding:16px 20px;margin:0 0 28px\">\n<p class=\"aiw-toc-head\"><strong>Table of Contents<\/strong><span class=\"aiw-toc-meta\"> \u00b7 16 min read<\/span><\/p>\n<ol style=\"margin:10px 0 0;padding-left:22px\">\n<li><a href=\"#protect-the-existing-site-before-adding-a-second-language\">Protect the Existing Site Before Adding a Second Language<\/a><\/li>\n<li><a href=\"#polylang-wpml-or-translatepress-what-determines-the-choice\">Polylang, WPML or TranslatePress: What Determines the Choice?<\/a><\/li>\n<li><a href=\"#turkish-at-the-root-english-under-en\">Turkish at the Root, English Under \/en\/<\/a><\/li>\n<li><a href=\"#translation-goes-beyond-the-post-body\">Translation Goes Beyond the Post Body<\/a><\/li>\n<li><a href=\"#hreflang-and-canonical-serve-different-purposes\">hreflang and Canonical Serve Different Purposes<\/a><\/li>\n<li><a href=\"#test-both-languages-before-publishing\">Test Both Languages Before Publishing<\/a><\/li>\n<li><a href=\"#how-do-translation-pairs-stay-consistent-as-content-grows\">How Do Translation Pairs Stay Consistent as Content Grows?<\/a><\/li>\n<li><a href=\"#test-both-languages-before-publishing-2\">Test Both Languages Before Publishing<\/a><\/li>\n<li><a href=\"#frequently-asked-questions\">Frequently Asked Questions<\/a><\/li>\n<li><a href=\"#sources\">Sources<\/a><\/li>\n<\/ol>\n<\/div>\n<h2 id=\"protect-the-existing-site-before-adding-a-second-language\">Protect the Existing Site Before Adding a Second Language<\/h2>\n<p>A multilingual WordPress site need not break existing Turkish URLs. Keep <code>https:\/\/example.com\/hakkimizda\/<\/code>; publish English at <code>https:\/\/example.com\/en\/about\/<\/code>. Turkish stays default, its URL language code hidden. I would start with an inventory.<\/p>\n<p>This hypothetical staging environment uses Ubuntu Server 24.04 LTS, Nginx 1.24, PHP 8.3-FPM, MariaDB 10.11, WordPress 6.8.3, WP-CLI 2.12 and Polylang 3.7 series. These are reference versions, not necessarily current releases. Verify security updates and compatibility against official sources; keep verified patch versions consistent. The allocated 2 vCPU, 4 GB RAM and 40 GB disk guarantee no performance level.<\/p>\n<p>For this single-site, classic-theme installation, inventory page and post URLs, menu locations, form fields, validation messages, email notifications and theme strings. Record owners and translation status. Body translations alone are insufficient: English forms can still return Turkish errors.<\/p>\n<p>Protect staging with Nginx HTTP Basic Authentication or a VPN over valid HTTPS. Enable WordPress&#8217;s search-engine discouragement setting, too. That is not access control. Verify unauthenticated access fails; block email to real recipients.<\/p>\n<p>WordPress&#8217;s backup documentation recommends saving database and files together for complete restoration. Here, sudo-capable <code>deploy<\/code> has suitable file ownership; WP-CLI runs without root. Check free space; pause edits, uploads and scheduled writes. <code>--single-transaction<\/code> alone cannot synchronize database and files.<\/p>\n<pre><code>(\nset -eu\numask 077\nsudo install -d -m 700 -o deploy -g \"$(id -gn)\" \/srv\/backups\/example.com\nbackup=$(mktemp -d \/srv\/backups\/example.com\/pre-language.XXXXXXXX)\ncd \/var\/www\/example.com\/public\nwp db export \"$backup\/database.sql\" --single-transaction\ntar -czf \"$backup\/files.tar.gz\" -C \/var\/www\/example.com public\ncd \"$backup\"\nsha256sum database.sql files.tar.gz &gt; SHA256SUMS\nsha256sum -c SHA256SUMS\ntar -tzf files.tar.gz &gt; \/dev\/null\nprintf 'Yedek dizini: %s\\n' \"$backup\"\n)<\/code><\/pre>\n<p>This writes a SQL dump and file archive into a unique, restricted directory outside the web root. Expect two checksum <code>OK<\/code> results, silent archive listing and the backup path printed with a Turkish label. These checks do not prove restoration. Save <code>\/etc\/nginx\/sites-available\/example.com<\/code> and necessary service settings separately.<\/p>\n<p>A <a href=\"https:\/\/www.vps.tc\/blog\/en\/what-is-a-vps-snapshot-point-in-time-backups\/\">VPS snapshot<\/a> offers quick rollback, but a same-infrastructure copy is not an independent backup. Transfer the backup to separate storage. Restore files into an isolated environment and SQL into a separate database; verify administrator login, media and existing Turkish URLs before enabling English.<\/p>\n<div class=\"aiw-callout aiw-callout-warn\">\n<p class=\"aiw-callout-label\">Caution<\/p>\n<p>WordPress&#039;s setting that asks search engines not to index a site does not prevent access to staging. Protect the copy with authentication or network access restrictions; separately verify the status of those protections and noindex settings on the live site.<\/p>\n<\/div>\n<h2 id=\"polylang-wpml-or-translatepress-what-determines-the-choice\">Polylang, WPML or TranslatePress: What Determines the Choice?<\/h2>\n<p>A plugin cannot decide who updates your English pages. Start there. An editor-led multilingual WordPress site needs a different workflow from an automatically translated catalog: decide who translates, approves and maintains content before choosing.<\/p>\n<p><strong>Polylang<\/strong> suits editors managing languages as separate, linked WordPress content. Its official WordPress.org listing includes multilingual posts, pages, categories, tags and menus for free; content duplication and URL-base translation are listed as Pro features. Giving an English page the slug <code>about<\/code> is not translating a shared category base. Different page slugs alone do not require Pro.<\/p>\n<p><strong>WPML<\/strong> merits consideration for centralized translation assignments and translator roles. <strong>TranslatePress<\/strong> focuses on visual translation through the visitor-facing page. Separate content records versus translated displayed strings affect updates and migration, not just editing. Check compatibility with your theme and plugins, including theme changes and dynamically generated text.<\/p>\n<p>The supplied sources exclude official WPML and TranslatePress documentation, so their current package limits remain unverified here. Check vendor documentation for free and paid features, licensed site counts, renewal terms and automatic-translation quotas. Provider accounts, API keys or credits depend on the integration; check which third party receives your text. Separate licensing costs from translation usage charges.<\/p>\n<p>For our hypothetical staging environment-WordPress 6.8.3, a classic theme and the Polylang 3.7 series-I would choose Polylang: separately editing Turkish originals and English counterparts is sufficient. WooCommerce and Multisite remain outside scope. Manual translation requires no external translation API; my choice makes no speed claim. These are reference versions, not a claim that they are current. Verify security patches and compatibility against official sources before installation; keep verified patch versions consistent throughout the examples.<\/p>\n<p>For portability, I would check language relationships, menus and plugin-specific records alongside the text. Do not assume standard WordPress export carries everything: rehearse migration into the destination system. Compare plugins on separate staging copies, never by activating multiple multilingual plugins together on the same site.<\/p>\n<h2 id=\"turkish-at-the-root-english-under-en\">Turkish at the Root, English Under \/en\/<\/h2>\n<p>Adding English does not mean moving Turkish URLs. I&#8217;d keep them. In this hypothetical staging environment, <code>https:\/\/example.com\/hakkimizda\/<\/code> stays; its translation is <code>https:\/\/example.com\/en\/about\/<\/code>. Subdirectories keep your multilingual WordPress site under one domain, certificate and installation. <code>\/en\/<\/code> is a URL prefix, not a physical folder.<\/p>\n<p>Polylang&#8217;s WordPress.org listing supports subdirectories, subdomains and separate domains. Subdomains need DNS records, certificate coverage and Nginx server-name mapping. Separate domains add registration and renewal tracking, without requiring separate WordPress installations. Subdirectories reduce that operational work.<\/p>\n<h3>Assign languages first<\/h3>\n<p>For the WordPress 6.8.3 and Polylang 3.7 series reference baseline, add Turkish and English under Languages, keeping codes <code>tr<\/code> and <code>en<\/code>. Make Turkish the default; assign it to existing content. Check posts, pages and categories for missing languages. Link the English page as the Turkish page&#8217;s translation, with slug <code>about<\/code>.<\/p>\n<p>In Polylang&#8217;s URL settings, select directory-based languages, hide the default language code and remove the <code>\/language\/<\/code> prefix. Save Settings \u2192 Permalinks without changing the Turkish structure. This example uses pretty permalinks; don&#8217;t change existing URLs to match it.<\/p>\n<h3>Let WordPress handle \/en\/<\/h3>\n<p>Edit-not duplicate-the existing HTTPS server block&#8217;s <code>location \/<\/code> rule in <code>\/etc\/nginx\/sites-available\/example.com<\/code>. Keep root <code>\/var\/www\/example.com\/public<\/code> and PHP socket <code>\/run\/php\/php8.3-fpm.sock<\/code>. This is not a replacement for the full configuration:<\/p>\n<pre><code>location \/ {\n    try_files $uri $uri\/ \/index.php?$args;\n}<\/code><\/pre>\n<p>Without a matching file or directory, this forwards the request and query parameters to WordPress. Polylang determines the language, not Nginx. As <code>deploy<\/code>, run:<\/p>\n<pre><code>sudo nginx -t &amp;&amp; sudo systemctl reload nginx<\/code><\/pre>\n<p>A successful test should report <code>syntax is ok<\/code> and <code>test is successful<\/code>. The <code>&amp;&amp;<\/code> allows reloading only after success; otherwise, fix the reported error first. These messages do not verify page mappings.<\/p>\n<p>Google Search Central documents separate URLs for language versions. I&#8217;d leave browser-language detection disabled here: let visitors opening a Turkish URL choose English themselves, rather than forcing a redirect.<\/p>\n<div class=\"aiw-callout aiw-callout-example\">\n<p class=\"aiw-callout-label\">Example<\/p>\n<p>In this hypothetical example, https:\/\/example.com\/hakkimizda\/ and https:\/\/example.com\/en\/about\/ are two language versions of the same content. \/en\/ is not a physical directory: Nginx routing sends the request to WordPress, while the plugin manages the language pairing. example.com is a documentation domain, not the address of a working installation.<\/p>\n<\/div>\n<h2 id=\"translation-goes-beyond-the-post-body\">Translation Goes Beyond the Post Body<\/h2>\n<p>English paragraphs beneath &#8220;Hakk\u0131m\u0131zda&#8221; and above Turkish buttons? Not finished. WordPress.org&#8217;s Polylang listing describes multilingual pages, categories, menus and media information-not automatic translation of every string.<\/p>\n<p>In this hypothetical staging environment, with WordPress 6.8.3 and Polylang 3.7 series, open Hakk\u0131m\u0131zda under <strong>Pages<\/strong>. Confirm its language is Turkish, then click the English add-translation icon. Enter &#8220;About&#8221;, the slug <code>about<\/code>, and English content. If About exists, confirm its language is English and select it in the translations field instead of duplicating it. Similar titles do not pair pages.<\/p>\n<p>After publication, expect <code>https:\/\/example.com\/hakkimizda\/<\/code> and <code>https:\/\/example.com\/en\/about\/<\/code>, with the default Turkish language code hidden. These documentation addresses are not expected to be reachable; no tested result is claimed. Verify reciprocal translation links in both editors.<\/p>\n<h3>Check beyond the body<\/h3>\n<ul>\n<li><strong>Titles and slugs:<\/strong> Check separately for leftover Turkish titles and duplicate-generated numeric suffixes.<\/li>\n<li><strong>Categories:<\/strong> Create and pair English equivalents, translating names and slugs. Confirm English posts use English categories.<\/li>\n<li><strong>Menus:<\/strong> In the classic theme, assign each language&#8217;s menu to its corresponding theme location. Edit custom-link labels and destinations separately.<\/li>\n<li><strong>Homepage:<\/strong> Create and link the static homepage&#8217;s English counterpart. Check Turkish at the root and English at <code>\/en\/<\/code>.<\/li>\n<li><strong>Image alternative text:<\/strong> With media translation enabled, edit language-specific alt text. Inspect existing image blocks too; media-record changes may not update them.<\/li>\n<li><strong>Supported theme strings:<\/strong> Translate strings registered with Polylang&#8217;s string-translation screen. Hard-coded text needs separate attention, potentially theme translation files or developer changes.<\/li>\n<\/ul>\n<p>Disable the menu language switcher&#8217;s homepage-redirect option: English on Hakk\u0131m\u0131zda should open About. Here, enable hiding languages without translations. This controls the switcher, not content creation.<\/p>\n<p>I would require human review before publishing machine translations, especially service terms, pricing and buttons. Check destinations alongside labels: an &#8220;Apply&#8221; button opening a Turkish form from the English page remains a translation gap.<\/p>\n<h2 id=\"hreflang-and-canonical-serve-different-purposes\">hreflang and Canonical Serve Different Purposes<\/h2>\n<p>Pointing an English page&#8217;s canonical at Turkish does not establish a translation relationship. Different job. <code>hreflang<\/code> identifies language alternatives; <code>canonical<\/code> identifies the preferred URL among identical or very similar pages. Google Search Central&#8217;s canonical documentation calls that preference a signal, not a directive. Swapping their roles misrepresents the relationship.<\/p>\n<p>In this hypothetical staging environment, <code>https:\/\/example.com\/hakkimizda\/<\/code> and <code>https:\/\/example.com\/en\/about\/<\/code> should each reference themselves as canonical. English should not canonicalize to Turkish: translated main content is not merely another-address duplication. On this multilingual WordPress site, they are language alternatives.<\/p>\n<p>Google&#8217;s localized-pages documentation requires self-references and reciprocal alternatives. Turkish&#8217;s <code>tr<\/code> points to itself; <code>en<\/code> points to English. English lists both too. Nonreciprocal annotations may be ignored. Use full URLs, including protocol and domain.<\/p>\n<p>This hypothetical HTML illustrates expected <code>head<\/code> output, not tested results or code to add manually. Only the canonical changes:<\/p>\n<pre><code>&lt;!-- https:\/\/example.com\/hakkimizda\/ sayfas\u0131n\u0131n head alan\u0131 --&gt;\n&lt;link rel=\"canonical\" href=\"https:\/\/example.com\/hakkimizda\/\"&gt;\n&lt;link rel=\"alternate\" hreflang=\"tr\" href=\"https:\/\/example.com\/hakkimizda\/\"&gt;\n&lt;link rel=\"alternate\" hreflang=\"en\" href=\"https:\/\/example.com\/en\/about\/\"&gt;\n\n&lt;!-- https:\/\/example.com\/en\/about\/ sayfas\u0131n\u0131n head alan\u0131 --&gt;\n&lt;link rel=\"canonical\" href=\"https:\/\/example.com\/en\/about\/\"&gt;\n&lt;link rel=\"alternate\" hreflang=\"tr\" href=\"https:\/\/example.com\/hakkimizda\/\"&gt;\n&lt;link rel=\"alternate\" hreflang=\"en\" href=\"https:\/\/example.com\/en\/about\/\"&gt;<\/code><\/pre>\n<p>Keep WordPress locales such as <code>tr_TR<\/code> and <code>en_US<\/code> out of these hreflang values. Google uses ISO 639-1 language codes, optionally followed by a hyphen and an ISO 3166-1 Alpha-2 region code. Here, without country targeting, <code>tr<\/code> and <code>en<\/code> suffice. Hiding Turkish&#8217;s URL code changes nothing.<\/p>\n<p>Polylang&#8217;s WordPress.org listing confirms hreflang support. If you use an SEO plugin, I would inspect both page sources for duplicate hreflang tags and multiple canonicals-especially the English canonical&#8217;s destination. Automatic generation does not guarantee correct configuration. Fix conflicts through the responsible components&#8217; settings, not extra theme tags.<\/p>\n<p><code>x-default<\/code> is optional: Google uses it for a fallback URL when no listed language matches. This example needs none. Google accepts HTML and XML sitemaps as alternative hreflang methods. Verify whether your integration includes sitemap language alternatives; do not assume it does. If you use both methods, check that their page pairings agree.<\/p>\n<div class=\"aiw-callout aiw-callout-warn\">\n<p class=\"aiw-callout-label\">Caution<\/p>\n<p>Pointing the English page&#039;s canonical to the Turkish page is not the same as identifying a language alternative. In this scenario, both pages should use self-referencing canonicals and include themselves and their translated counterparts in the hreflang set. x-default is optional.<\/p>\n<\/div>\n<h2 id=\"test-both-languages-before-publishing\">Test Both Languages Before Publishing<\/h2>\n<p>A Turkish page can look right while its English counterpart redirects elsewhere. Looks aren&#8217;t enough. I check HTTP responses, HTML source and browser behavior on a multilingual WordPress site, including logged-out requests. Watch the address bar: a correct title does not prove correct translation pairing.<\/p>\n<p>This hypothetical staging example uses <code>deploy<\/code>; it has not been tested. No real response is expected from documentation address <code>192.0.2.10<\/code>. Allow test connections through staging protection. <code>--resolve<\/code> targets the IP without changing DNS, preserving the HTTPS hostname and certificate verification.<\/p>\n<pre><code>(\n  kontrol_dizini=$(mktemp -d) || exit 1\n  trap 'rm -rf -- \"$kontrol_dizini\"' EXIT\n\n  for yol in \/hakkimizda\/ \/en\/about\/; do\n    printf '\\nAdres: https:\/\/example.com%s\\n' \"$yol\"\n    curl --silent --show-error --location --max-redirs 5 \\\n      --connect-timeout 10 --max-time 30 \\\n      --resolve example.com:443:192.0.2.10 \\\n      --dump-header \"$kontrol_dizini\/headers\" \\\n      --output \"$kontrol_dizini\/page.html\" \\\n      --write-out 'HTTP=%{http_code} yonlendirme=%{num_redirects} hedef=%{url_effective}\\n' \\\n      \"https:\/\/example.com$yol\" || continue\n\n    grep -Ei '^(HTTP\/|Location:|X-Robots-Tag:)' \"$kontrol_dizini\/headers\"\n    tr '\\n' ' ' &lt; \"$kontrol_dizini\/page.html\" \\\n      | grep -oEi '&lt;(link|meta)[^&gt;]*&gt;' \\\n      | grep -Ei 'canonical|alternate|robots'\n  done\n)\n\nwp --path=\/var\/www\/example.com\/public option get blog_public<\/code><\/pre>\n<p><strong>Hypothetical expectation:<\/strong> both URLs show <code>HTTP=200<\/code>, <code>yonlendirme=0<\/code> and <code>hedef<\/code> matching the requested URL. <code>--location<\/code> follows redirects; dumped headers reveal intermediate statuses and <code>Location<\/code> values. Investigate unexpected <a href=\"https:\/\/www.vps.tc\/blog\/en\/301-redirect-seo-implementation-guide\/\">301 redirect<\/a> chains. A <code>401<\/code> or <code>403<\/code> warrants checking access protection, not automatically blaming translations.<\/p>\n<p>Google Search Central&#8217;s canonical documentation says translated main content is not duplicate merely because it is translated. Each canonical here should reference itself. Google&#8217;s localized-pages documentation calls for reciprocal hreflang references, including self-references: both pages should list <code>tr<\/code> as <code>https:\/\/example.com\/hakkimizda\/<\/code> and <code>en<\/code> as <code>https:\/\/example.com\/en\/about\/<\/code>. Filtering is preliminary; check apparent omissions against page source.<\/p>\n<p>In the browser, verify that the switcher reaches the paired translation, not the homepage. Test both mobile menus and search for known content in each language. Read empty\/invalid form warnings and successful-submission confirmations. Nonexistent root and <code>\/en\/<\/code> URLs should return genuine <code>404<\/code> responses with localized messages.<\/p>\n<p>Keep separate staging protected. Remove access restrictions and <code>noindex<\/code> from the published site; repeat logged-out requests. Expect <code>blog_public<\/code> to return <code>1<\/code>, and verify that neither HTML robots tags nor <code>X-Robots-Tag<\/code> contains <code>noindex<\/code>. The setting alone does not prove public accessibility.<\/p>\n<p>No full-page cache exists initially. If you add one, alternate repeated requests between both URLs. Once warm, check that content languages, canonicals and switcher destinations have not crossed over.<\/p>\n<div class=\"aiw-callout aiw-callout-tip\">\n<p class=\"aiw-callout-label\">Tip<\/p>\n<p>An HTTP 200 response alone does not prove that the correct language is being served. Test the language switcher, mobile menu, and form validation messages in a browser. If you add full-page caching later, check again that Turkish and English URLs do not serve each other&#039;s content.<\/p>\n<\/div>\n<h2 id=\"how-do-translation-pairs-stay-consistent-as-content-grows\">How Do Translation Pairs Stay Consistent as Content Grows?<\/h2>\n<p>A changed Turkish price, date or service condition can leave published English content outdated. Links are not enough. In this hypothetical staging environment, I would record each pair&#8217;s source modification date, translation owner and latest language approval. Flag English for review whenever Turkish changes; do not assume Polylang handles editorial approval automatically.<\/p>\n<p>Polylang&#8217;s WordPress.org description documents language assignment and translation linking. Track missing translations, reviews pending after source changes, and publication-ready content separately. Each week, check new posts, pages and taxonomy terms needing translation against that list. Keep both content IDs and target URLs: similar titles can hide incorrect pairings. A shared spreadsheet suffices; no workflow plugin is required.<\/p>\n<p>Approve each language separately. Turkish approval does not clear English titles, body text, menu links or other visible wording. Keep meaning-changing edits open until the translation owner reviews them. Never fill missing English with Turkish and mark it translated. Record the reviewed source revision rather than carrying previous approval onto changed text.<\/p>\n<p>Evaluate WordPress, classic-theme and Polylang updates separately in the same staging environment. WordPress 6.8.3 and the Polylang 3.7 series remain the reference baseline, not claims of latest releases. Verify security updates and compatibility through official sources beforehand; keep selected patch versions consistent across examples. Recheck editing, translation linking and language switching after each update.<\/p>\n<p>WordPress&#8217;s backup documentation explains that full restoration needs both database and files. Before changes, store a consistent backup set under <code>\/srv\/backups\/example.com<\/code>. I would withhold update approval until restoring both to the same backup point confirms that content and language pairings remain intact.<\/p>\n<p>The publication gate is concrete: <code>https:\/\/example.com\/hakkimizda\/<\/code> must pair with <code>https:\/\/example.com\/en\/about\/<\/code>, the language switcher must reach the correct counterpart, and both URLs must serve expected content. Google Search Central&#8217;s localized-page guidance calls for <code>hreflang<\/code> links covering the page itself and its other language versions, with reciprocal references. Do not publish new content until its language approval, pairing checks and URL checks are complete.<\/p>\n<h2 id=\"test-both-languages-before-publishing-2\">Test Both Languages Before Publishing<\/h2>\n<ul class=\"aiw-checklist\">\n<li>Back up the database and files from the same recovery point, then restore them together in a separate environment.<\/li>\n<li>Verify security updates and version compatibility for WordPress, PHP, the theme, and the language plugin using official sources.<\/li>\n<li>Assign Turkish to existing content; check that Turkish URLs remain unchanged and English pages load under \/en\/.<\/li>\n<li>Link translation pairs and check menus, the homepage, image alternative text, and form messages in both languages.<\/li>\n<li>Verify that each language page has a self-referencing canonical, reciprocal hreflang links, and no conflicting tags.<\/li>\n<li>Test HTTP statuses, redirect chains, the language switcher, mobile menu, search, and not-found pages.<\/li>\n<li>Check access restrictions and noindex settings on the live site; require language pairing and URL checks before approving subsequent content for publication.<\/li>\n<\/ul>\n<div class=\"aiw-cta\">\n<p>Start with a single Turkish-English page pair on staging. Do not extend the setup to other content until the language switcher, URL, hreflang, and canonical checks pass.<\/p>\n<p class=\"aiw-cta-action\"><a href=\"https:\/\/www.vps.tc\/en\/vps\">Explore VPS plans<\/a><\/p>\n<\/div>\n<h2 id=\"frequently-asked-questions\">Frequently Asked Questions<\/h2>\n<div class=\"aiw-faq\">\n<details class=\"aiw-faq-item\" open>\n<summary>Which plugin should I choose for a multilingual WordPress site?<\/summary>\n<p>The choice depends on who prepares translations and how your editors work. Consider Polylang for teams that create separate content in two languages and link it as translation pairs. Compare WPML and TranslatePress on translation workflow, theme compatibility, licensing, and external service dependencies too. Verify free and paid feature boundaries before installation, and do not activate multiple multilingual plugins at once.<\/p>\n<\/details>\n<details class=\"aiw-faq-item\">\n<summary>Should English pages use \/en\/ or a subdomain?<\/summary>\n<p>For Turkish and English content managed in one WordPress installation, an \/en\/ subdirectory avoids separate DNS and certificate management. A subdomain or separate domain may suit different operational needs, but neither provides better rankings by itself. In this hypothetical scenario, Turkish stays at the root, preserving existing Turkish URLs.<\/p>\n<\/details>\n<details class=\"aiw-faq-item\">\n<summary>Does Polylang automatically translate the entire site?<\/summary>\n<p>Activating a language plugin does not mean all content and interface text will translate automatically. In this scenario, Turkish and English content is prepared separately and linked as translation pairs. Menus, form messages, image alternative text, and theme strings need separate review. If you use automatic translation, verify support in the relevant version, license, and service integration, then have a person review the text.<\/p>\n<\/details>\n<details class=\"aiw-faq-item\">\n<summary>How should hreflang and canonical tags work on a multilingual WordPress site?<\/summary>\n<p>Each page in a Turkish-English translation pair should identify its own URL as canonical. The hreflang set should include both versions using tr and en, with reciprocal and self-referencing links. Do not copy WordPress locale names directly into hreflang values. Inspect the HTML generated by the language and SEO plugins together; x-default is optional.<\/p>\n<\/details>\n<details class=\"aiw-faq-item\">\n<summary>Where should the language switcher lead when a page has no translation?<\/summary>\n<p>Define the switcher&#039;s behavior explicitly and test it with your chosen plugin. Do not link an untranslated page as though a translation exists. You can hide the unavailable language option or provide a navigation path that explains the situation. If you send readers to the other language&#039;s homepage, make clear that it is not a translation of the current page. For published translation pairs, the switcher should lead directly to the matching page.<\/p>\n<\/details>\n<details class=\"aiw-faq-item\">\n<summary>Will adding a second language change existing Turkish URLs?<\/summary>\n<p>Existing Turkish URLs can remain unchanged with the right language and permalink settings. First assign Turkish to existing content, make Turkish the default language, and hide its language code from URLs. Test these changes on staging and verify that old addresses still open the same content. If you intentionally change any URLs, plan permanent redirects to the relevant replacement pages rather than sending every old address to the homepage.<\/p>\n<\/details>\n<\/div>\n<h2 id=\"sources\">Sources<\/h2>\n<ul class=\"aiw-sources\">\n<li><a href=\"https:\/\/wordpress.org\/plugins\/polylang\/\" target=\"_blank\" rel=\"noopener\">WordPress.org &#8211; Polylang Features and Installation Instructions<\/a> \u2014 wordpress.org<\/li>\n<li><a href=\"https:\/\/wordpress.org\/documentation\/article\/wordpress-backups\/\" target=\"_blank\" rel=\"noopener\">WordPress Documentation &#8211; Database and File Backups<\/a> \u2014 wordpress.org<\/li>\n<li><a href=\"https:\/\/developers.google.com\/search\/docs\/specialty\/international\/localized-versions\" target=\"_blank\" rel=\"noopener\">Google Search Central &#8211; Localized Pages and hreflang<\/a> \u2014 developers.google.com<\/li>\n<li><a href=\"https:\/\/developers.google.com\/search\/docs\/crawling-indexing\/consolidate-duplicate-urls\" target=\"_blank\" rel=\"noopener\">Google Search Central &#8211; Specifying Canonical URLs<\/a> \u2014 developers.google.com<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Keep your Turkish URLs intact while publishing English content under \/en\/. Make plugin selection, translation pairing, and search engine language signals part of the same publishing checks.<\/p>\n","protected":false},"author":2,"featured_media":1077,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10],"tags":[],"class_list":["post-1079","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cmss"],"lang":"en","translations":{"en":1079,"tr":1078},"pll_sync_post":[],"_links":{"self":[{"href":"https:\/\/www.vps.tc\/blog\/wp-json\/wp\/v2\/posts\/1079","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.vps.tc\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.vps.tc\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.vps.tc\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.vps.tc\/blog\/wp-json\/wp\/v2\/comments?post=1079"}],"version-history":[{"count":1,"href":"https:\/\/www.vps.tc\/blog\/wp-json\/wp\/v2\/posts\/1079\/revisions"}],"predecessor-version":[{"id":1081,"href":"https:\/\/www.vps.tc\/blog\/wp-json\/wp\/v2\/posts\/1079\/revisions\/1081"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.vps.tc\/blog\/wp-json\/wp\/v2\/media\/1077"}],"wp:attachment":[{"href":"https:\/\/www.vps.tc\/blog\/wp-json\/wp\/v2\/media?parent=1079"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.vps.tc\/blog\/wp-json\/wp\/v2\/categories?post=1079"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.vps.tc\/blog\/wp-json\/wp\/v2\/tags?post=1079"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}