Universally Documentation

Step-by-step guides, multilingual SEO tips, and best practices to help you translate and scale your WordPress website.

Language subdomains

Language subdomains serve each language on its own hostname, such as fr.example.com. Universally serves that hostname through its reverse proxy: it fetches the page from your main domain and returns it translated, and your main domain is never touched. Each language needs three DNS records, which you add at whoever manages your domain.

Before you start

  • An Any Website or Astro project in the Subdomain serving mode. Pick Subdomain under How should translated pages be served? when you create the project, or move a JavaScript mode project as below. Language subdomains are not available for WordPress, and not yet for Webflow, Framer, Squarespace, Duda, Tilda, Weebly, or Lovable sites. For Astro, see Astro with language subdomains.
  • The snippet on your pages. It renders the language switcher that links the hostnames. See Install on any website.
  • Access to your domain's DNS.
  • The right role. Owner, Admin, or Editor can add a language and manage its hostname, including Re-check now. Removing a language needs Owner or Admin. Everyone can view. See Roles and permissions.

Move from JavaScript mode

  1. Open the project's Setup page and click Move to language subdomains.
  2. Read the Move to language subdomains? dialog and click Move to subdomains.

Your site keeps working on the JavaScript snippet until the first language subdomain goes live, so nothing breaks while you set the DNS up. Moving back to the JavaScript snippet is not available yet: your language subdomains would keep resolving with nothing behind them, and any page already indexed on them would be lost.

Add a language subdomain

  1. Open All Languages. In the Languages card, click Add subdomain for language.
  2. In Add Target Language, pick Language and Region.
  3. Choose the Subdomain format: Language Code (the default), Region Code, or Custom (2 to 6 characters). The preview shows the result after Subdomain:.

The hostname is {segment}.{your domain}, with a leading www dropped, so French with Language Code on www.example.com becomes fr.example.com. Universally creates it when you add the language. If creation failed, the row reads "No subdomain provisioned" with a Retry button.

Add the DNS records

Copy each record into your DNS provider. The row shows each one with its Name, its Value, and a copy button. They can be added in any order.

Type Name Value Purpose
CNAME fr.example.com proxy.universally.app Routes the subdomain
TXT shown once Cloudflare issues it shown once Cloudflare issues it Proves you own the domain
CNAME _acme-challenge.fr.example.com fr.example.com.afc20bbc0f5b23e9.dcv.cloudflare.com Lets the certificate be issued

Leave the records unproxied. On Cloudflare that is Proxy status › DNS only. A proxied record resolves as an A record, which cannot be validated.

Follow the status

Each row carries a status pill:

Status Meaning
Add DNS records The records are not in place yet.
Verifying Universally is verifying ownership. This takes a few minutes.
Live The hostname and its certificate are active, and the subdomain serves your site translated.
DNS moved The subdomain's DNS now points somewhere else. Restore the record to bring it back.
Failed Validation failed. Double-check the records match exactly, then re-check.

A timeline under the pill steps through DNS added, Domain verified, SSL issued, and Live. Checks run every 5 minutes, and the row shows "Checking automatically · last checked Xs ago". Click Re-check now to check straight away.

The card's summary chips count your languages as live, verifying, action needed, and failed. A live row has a Live/Off switch, a word count, and a link to the subdomain.

Verify it worked

  1. Wait for the row to read Live.
  2. Open https://fr.example.com/. It serves your site translated.
  3. On your main domain, use the switcher to move to the language. It takes you to the subdomain.

Translation Rules apply in this mode, Exclude Pages included, because the pages are translated on Universally's side. See Translation rules.

If it does not work

  • The records cannot be validated: a record is proxied. On Cloudflare, set Proxy status to DNS only.
  • The row reads Failed: a record does not match. Compare each Name and Value with your DNS provider character for character, then click Re-check now.
  • The row reads DNS moved: the subdomain's DNS now points somewhere else. Restore the record the row shows.
  • The row reads "No subdomain provisioned": click Retry.

For search engine setup, see hreflang tags and Multilingual SEO overview. If a row stays stuck after the records match, contact support.

Was this helpful?