Universally Documentation

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

Install the Astro integration

Installing takes four steps: add the package, put your API key in .env, register the integration in astro.config.mjs, and add one component to your layout. After that, every page you already have is also served under each language's prefix, such as /fr/about.

Before you start

  • Astro 5 or newer, with output: 'server' or output: 'static'. Server rendering also needs an Astro adapter.
  • Node 18 or newer. Reading .env and .env.local needs Node 20.12 or newer. On older Node the files are skipped without an error, so set UNIVERSALLY_API_KEY in the process environment instead.
  • The Owner or Admin role in the workspace, to create the project and see its API key. Editors see "Ask a project admin for this project's API key." instead of the key.

Create the project

  1. Start a new project. Under Select Your Technology, pick Astro (marked Beta).
  2. Fill in Domain, the fully qualified domain where the site is served. It is required for Astro.
  3. Fill in Project Name, check Source Language (English (US) by default), and click Next.
  4. On Setup Instructions, pick SDK under How should translated pages be served? and click Continue.

The screen then lists the four install steps below, with a "{n} of 4 done" counter. Each step has a Mark as complete button. The ticks are stored only in your browser and gate nothing. The same steps stay available later under Setup in the project sidebar.

1. Install the integration

npm install @universally-sdk/astro
# or: pnpm add @universally-sdk/astro
# or: yarn add @universally-sdk/astro
# or: bun add @universally-sdk/astro

2. Add your API key

Put the line from the Setup page in .env, next to your other secrets, in the Astro project root:

UNIVERSALLY_API_KEY=paste-the-64-character-key-here

The key is one 64 character string. Keep it on the server and never commit .env. The same key is on API Settings behind Show API key. See Find your API key.

3. Configure Astro

Register the integration in astro.config.mjs and set site to your domain:

import node from '@astrojs/node';
import universally from '@universally-sdk/astro';
import { defineConfig } from 'astro/config';

export default defineConfig({
  site: 'https://example.com',
  output: 'server',
  adapter: node({ mode: 'standalone' }),
  integrations: [universally()]
});

universally() reads the key from .env, so you pass nothing to it. site is required for hreflang links, because they have to be absolute URLs. A static site drops the adapter and uses output: 'static'. Every option is listed in Astro integration options.

To type Astro.locals, add two lines to src/env.d.ts:

/// <reference types="astro/client" />
/// <reference types="@universally-sdk/astro/env" />

4. Use it in your pages

Add the head tag once in your layout, then translate strings with t(). This is src/layouts/Base.astro:

---
import { UniversallyHead } from '@universally-sdk/astro/components';

const { t } = Astro.locals;
---

<html lang={Astro.currentLocale}>
  <head>
    <meta charset="utf-8" />
    <title>{t('My site')}</title>
    <UniversallyHead />
  </head>
  <body>
    <slot />
  </body>
</html>

<UniversallyHead /> takes no props. It renders the hreflang links and the language switcher script. Then wrap the text of a page, here src/pages/about.astro:

---
import Base from '../layouts/Base.astro';

const { t, href } = Astro.locals;
---

<Base>
  <h1>{t('About us')}</h1>
  <p><a href={href('/pricing')}>{t('See pricing')}</a></p>
</Base>

One page file serves every language. Translate pages in Astro covers t(), href(), inline HTML, and islands.

Add languages

  1. Click Continue to languages.
  2. On Add Languages, add at least one target language. Its URL Format decides the prefix: Language Code (the default) gives /fr/, Region Code uses the region, so Spanish (Mexico) becomes /mx/, and Custom takes 2 to 6 characters. See Add languages.
  3. Click Finish. It stays disabled until the project has a language.

Languages are read when your Astro config runs. Restart the dev server after adding one.

Verify it worked

npx astro dev

Open http://localhost:4321/about for your source text and http://localhost:4321/fr/about for French. The first render of a new string shows the source text. Reload after a second or two and it is translated. View the page source to confirm one <link rel="alternate" hreflang> per language.

If it does not work

  • The build fails with "set UNIVERSALLY_API_KEY in .env…": the key is not in the options, the environment, .env.local, or .env next to astro.config.mjs.
  • /fr/about returns 404: the language was added after the dev server started, or its Live switch is off. Restart.
  • No hreflang links: site is missing from astro.config.mjs.

More cases are in Astro integration troubleshooting.

Was this helpful?