The short version
If your languages share the same content, translate per field inside one Storyblok story. If the content differs per language or country, give each language its own folder. You only need a separate space per market when different teams run their own site. Then fix the URL for each language, link the language versions with hreflang and agree on how your editors translate and review.
Storyblok localization starts with one decision: do you translate per field inside the same page, give each language its own folder, or give each market its own space? If your languages share the same content, field-level translation is enough. If the content differs per country, work with folders. You only need a separate space when different teams run their own site.
I have been building websites for more than 20 years, and these days often with Storyblok and Astro, like the New Impact portfolio site in Dutch, English and French. This guide covers the choices you make before the build. How do you translate content? Which URL does each language get? How does Google link the language versions? And how do your editors translate without doing the same work twice?
What does a multilingual website need?
A multilingual website is more than translated copy. You need four things that fit together. First, a content structure that can carry every language. Second, a fixed URL per language. Third, a link between the language versions for search engines. And finally, a way of working in which someone writes, reviews and publishes the translations.
In a headless CMS like Storyblok, those jobs live in two places. Storyblok stores the content and the translations. The frontend, usually Astro in our projects, decides which URLs exist and which hreflang links end up in the HTML. A good setup makes those decisions once and then runs on its own, even when your editors add a fourth language next year.
Field-level, folder-level or space-level translation?
Storyblok describes three approaches in its internationalization documentation. They are not mutually exclusive, but the first choice shapes how your editors work every day.
| Approach | How it works | Fits | Watch out for |
|---|---|---|---|
| Field level | One story per page with a version per language; you mark fields as translatable | Languages with the same content and the same page structure | The Blocks field type itself cannot be translated, so the structure is the same in every language |
| Folder level | Each language or market gets its own folder with its own stories | Content that differs per country or language | More stories to manage; link the versions as alternate versions |
| Space level | Each market gets its own space, with shared components through the CLI and API | Large projects with separate teams per market or channel | More administration and syncing between spaces |
Field-level translation
For field-level translation, you add the languages under Settings, Internationalization. Then you mark in the Block library which fields are translatable. An editor picks the language in the Visual Editor and fills in the translated fields. Fields you do not translate, such as an image or a date, stay the same for every language.
By default, publishing a story publishes all of its languages at once. If you want a translation to go live only when it is ready, turn on publishing individual translations. Through the API, you fetch a language with the language parameter. With fallback_lang, a missing translation falls back to another language, for example Spanish for a Colombian variant that is not fully translated yet.
A folder per language
For folder-level translation, you create a folder per language or market at the top level in Storyblok, such as nl/, en/ and fr/. Each folder holds its own stories, so you can drop a block in French or show a different case study. The Dimensions app links the versions of the same page across folders. Without that app, you turn on Alternative Versions and duplicate the folder.
This approach takes more upkeep, because every change that applies to all languages has to be made in each folder. In return, each language can have truly different content. For companies with a different offer per country, that is often the most honest choice.
A separate space per market
A separate space per market is meant for large projects where teams work independently, with their own editors and their own schedule. You share components and content through Storyblok’s CLI and Management API. For most small and midsize companies, that is more administration than they need.
You can also combine the field and folder approaches: a folder per market, with field-level translation inside each folder. Storyblok’s example is a US folder with English and Spanish next to an EU folder with English, Spanish, French and German.
Which URL does each language get?
Every language needs a fixed place in the URL. In Astro, you set that up with i18n routing: you list the languages and choose a default.
// astro.config.mjs
import { defineConfig } from 'astro/config'
export default defineConfig({
i18n: {
locales: ['en', 'nl', 'fr'],
defaultLocale: 'en',
routing: { prefixDefaultLocale: false },
},
})With prefixDefaultLocale: false, the default setting, the default language gets no prefix: /about in English, /nl/... and /fr/... for the other languages. Set it to true and every language gets a prefix, including the default one. Make this call before launch. Changing it later moves every URL and needs a redirect per page.
Translated slugs
A second choice is whether the slug itself is translated: /fr/a-propos instead of /fr/about. Translated slugs read more naturally to visitors. With field-level translation, you handle that with the Translatable Slugs app; with folder-level translation, each story in a language folder simply has its own slug.
This site does the same without a CMS: website-performance is called laadtijd-website in Dutch, and a fixed pairs list decides which pages are translations of each other. That list feeds the hreflang links and the sitemap, so the site never points to a translation that does not exist.
How do you tell Google which pages belong together?
Hreflang tells Google which pages are translations of each other. The rules are in Google Search Central’s guidelines:
- Every language version points to itself and to all other versions.
- You use fully qualified URLs, including
https://. - The link has to work in both directions; otherwise Google ignores it.
- An
x-defaultpoints to the page for visitors whose language is not on the list.
Google lists three equivalent places for those links: the HTML, the HTTP headers or the sitemap. Pick one and keep it consistent. Google does not use hreflang to detect a page’s language; it does that itself. Fully translated pages also do not count as duplicate content.
In a Storyblok project, you read the linked versions from the story (its alternates or translated slugs) and let the frontend write the links. To build one sitemap per language from that data, with code, read the guide to localized sitemaps with Astro and Storyblok.
How do your editors translate?
The technology decides where a translation lives. Who writes and reviews it is a separate agreement. According to Storyblok’s translations manual, there are three ways to work, and you can mix them.
By hand or with AI
To translate by hand, the editor picks the language in the Visual Editor and fills in each translatable field, optionally with the default language shown next to it. You turn on AI translations under Settings, Labs. Then you translate a whole story or one field at a time. Storyblok lists 48 supported languages, including Dutch, French and English.
If you work with a folder per language, Dimensions creates a translated copy in the target folder with Create Clone & AI Translate and links it as an alternate version right away. The same rule applies to every AI translation: have someone who knows the language and your customers review it. Product names, technical terms and legal copy are where it goes wrong.
A translation agency or TMS
If you work with a translation agency or a translation management system (TMS), Storyblok has apps for Crowdin, LingoHub, Localazy, Lokalise and Smartling. With the Export Translatable Fields and Import Translatable Fields apps, you exchange translations as XML or JSON. For a site with two or three languages and an in-house editor, that is often unnecessary; for ten languages, it is not.
How did we set this up for New Impact?
For the Antwerp video production company New Impact, we built a portfolio site in Dutch, English and French, with Astro as the frontend and Storyblok as the CMS. Each language has its own folder in Storyblok, such as fr/ for French, and its own route on the website. The team publishes new portfolio items in every language without a developer.
New portfolio items appear in every language from a single content structure. The site stayed fast as well: in September 2026, the homepage scored 100 in mobile PageSpeed, with an LCP of 1.2 seconds. Those are the values from the monthly measurement on the case page.
Which Storyblok localization setup fits your website?
In practice, four questions decide the setup:
- Is the content the same in every language, apart from the translation? Choose field-level translation.
- Do the offer, the case studies or the page structure differ per country or language? Choose a folder per language.
- Do separate teams per market work on their own schedule? Consider a space per market.
- Who translates and who reviews? That decides whether you work by hand, with AI or with a TMS.
Before the build, also fix the URL structure, and after launch, check in Google Search Console that every language version shows up. If you are weighing Storyblok against another CMS, the guide to switching to Storyblok covers the migration side.

