By default, sites are published on a subdomain (e.g. global.example.co.jp/en/) and work with just a single DNS record. Google treats subdomains and subdirectories equally, but if branding or URL structure requires serving directly under your own domain, such as example.co.jp/en/ , you can do so by forwarding (reverse proxying) the language paths to Sotomuke from your own CDN or server.
Prerequisites
- Publishing on a subdomain (e.g.
global.example.co.jp) must already be complete. This hostname is the forwarding destination. - You must have an environment where you can write forwarding rules in front of your domain (Cloudflare, a CDN, nginx/Apache, Next.js/Vercel, Netlify, etc.). This cannot be configured on shared hosting or SaaS platforms such as STUDIO or Wix. In that case, please use a subdomain.
- Your Japanese pages continue to be served by your own server as before. Only the language paths are forwarded.
Overview of the steps
- In the dashboard, go to "Publishing settings" → "Serve from a subdirectory" and save your public URL (e.g.
https://example.co.jp). From then on, canonical, hreflang, sitemap and language-switcher URLs will use this domain. - Using one of the methods below, forward the paths for your selected languages, such as
/en/・/zh-Hans/・/ko/(including everything beneath them), toglobal.example.co.jp.The key point is to also rewrite the Host header toglobal.example.co.jpに書き換える(Sotomuke identifies sites by hostname). - Use the "Check forwarding" button to confirm that each language URL is being served by Sotomuke (responses include the
x-sotomuke-siteheader). https://example.co.jp/robots.txttoSitemap: https://global.example.co.jp/sitemap.xmlAdd the following line. Google accepts sitemaps on a different host as long as they are referenced from robots.txt. Submit this sitemap to the example.co.jp property in Search Console.
Method A: Cloudflare (Origin Rules, no code required)
This is the simplest option if your domain is behind the Cloudflare proxy (orange cloud). Go to Rules → Origin Rules and create the following rule.
- Condition: URI Path starts with
/en/(add one per language with OR; if writing it as an expression,(starts_with(http.request.uri.path, "/en/")) or (starts_with(http.request.uri.path, "/ko/"))) - Host header: Rewrite to
global.example.co.jp - DNS record: Override to
global.example.co.jp
If creating it via the API, add origin_rules to the ruleset for the action: "route"、action_parameters: { host_header: "global.example.co.jp", origin: { host: "global.example.co.jp" } } phase.
Method B: Cloudflare Worker (for finer control)
export default {
async fetch(request) {
const url = new URL(request.url);
const langs = ["en", "zh-Hans", "ko"]; // ダッシュボードで選んだ言語
const lang = url.pathname.split("/")[1];
if (langs.includes(lang) || url.pathname === "/sitemap-sotomuke.xml") {
const target = new URL(url);
target.hostname = "global.example.co.jp"; // 公開ホスト名
if (url.pathname === "/sitemap-sotomuke.xml") target.pathname = "/sitemap.xml";
const res = await fetch(target.toString(), { headers: request.headers, cf: { cacheTtl: 300 } });
return new Response(res.body, res);
}
return fetch(request); // それ以外は元サイトへ
},
};
Set the Worker route to example.co.jp/* ./sitemap-sotomuke.xml can also be forwarded so you can list it in robots.txt as a sitemap on the same host.
Method C: nginx
location ~ ^/(en|zh-Hans|ko)/ {
proxy_pass https://global.example.co.jp;
proxy_set_header Host global.example.co.jp;
proxy_ssl_server_name on;
proxy_ssl_name global.example.co.jp;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location = /sitemap-sotomuke.xml {
proxy_pass https://global.example.co.jp/sitemap.xml;
proxy_set_header Host global.example.co.jp;
proxy_ssl_server_name on;
}
Method D: Apache (mod_proxy)
SSLProxyEngine On
ProxyPreserveHost Off
ProxyPassMatch "^/(en|zh-Hans|ko)/(.*)$" "https://global.example.co.jp/$1/$2"
ProxyPass "/sitemap-sotomuke.xml" "https://global.example.co.jp/sitemap.xml"
RequestHeader set Host "global.example.co.jp"
mod_proxy・mod_proxy_http・mod_ssl is required. This is usually not available via .htaccess on shared hosting.
Method E: Next.js / Vercel
// next.config.js
module.exports = {
async rewrites() {
return [
{ source: "/:lang(en|zh-Hans|ko)/:path*", destination: "https://global.example.co.jp/:lang/:path*" },
{ source: "/sitemap-sotomuke.xml", destination: "https://global.example.co.jp/sitemap.xml" },
];
},
};
If your static site is hosted on Vercel, vercel.json in rewrites add the same configuration.
Method F: Netlify
# _redirects
/en/* https://global.example.co.jp/en/:splat 200
/zh-Hans/* https://global.example.co.jp/zh-Hans/:splat 200
/ko/* https://global.example.co.jp/ko/:splat 200
/sitemap-sotomuke.xml https://global.example.co.jp/sitemap.xml 200
Method G: AWS CloudFront
Add global.example.co.jp(HTTPS only, Origin protocol policy: HTTPS only) as an Origin, and set the Behavior Path pattern /en/* and so on to that Origin. Configure the Cache policy to forward query strings, and configure the Origin request policy so that Host is not forwarded (CloudFront sends the Origin's hostname).
Checkpoints
curl -sI https://example.co.jp/en/ | grep -i x-sotomuke-siteatx-sotomuke-site: <スラッグ>is returned, forwarding is working correctly.- Forward query strings (
?utm_source=etc.) as-is. - Forwarding rules must be evaluated before any routing by WordPress or similar systems. If your original site returns a 404, check the order of your rules.
- Once you set a public URL, the subdomain URL (
global.example.co.jp/en/) will continue to work, but because the canonical points to your own domain, search results will show URLs on your own domain. - Access analytics for translated pages will continue to appear in your Sotomuke dashboard as before.
For Web Agencies
With the Agency plan, you can apply the same configuration to each site. If you run many sites on the same CDN, templating the language path forwarding lets you add a new site in just a few minutes. For setup assistance or verification, please contact us.
