New guide: AI is in production. Is your governance?

Announcing Visual Copilot - Figma to production in half the time

Builder.io
Builder.io
Contact sales

New guide: AI is in production. Is your governance?

Announcing Visual Copilot - Figma to production in half the time

pro plans

publish

To localize content with Builder, integrate localization into the codebase to keep the app and Builder content in sync. You can choose one of two approaches:

  • Inline localization
  • Content entry localization

Use inline localization to manage locale-specific content within a single entry by localizing individual fields. This approach maintains consistency across entries while customizing specific elements for each locale, such as text or images.

When using the Content API, set the locale parameter when calling builder.get() to return the entry with localized values resolved in the response. The API processes the localization and returns content ready for rendering. Pass the locale as a prop to the <BuilderComponent> component to provide component-level context for rendering the correct localized content.

The locale value is a string, such as "en-FR", that specifies which localized version of the content to render.

The following example shows fetching and rendering inline-localized content:

import { GetServerSideProps, InferGetServerSidePropsType } from 'next';
import { builder } from '@builder.io/sdk';
import { BuilderComponent, BuilderContent } from '@builder.io/react';

const BUILDER_MODEL = /* ADD YOUR MODEL NAME */;
const BUILDER_PUBLIC_API = /* YOUR PUBLIC API KEY HERE */;

// Initialize Builder
builder.init(BUILDER_PUBLIC_API);

export const getServerSideProps = (async ({ resolvedUrl }) => {
  const content = await builder.get(BUILDER_MODEL, {
    userAttributes: { 
      urlPath: resolvedUrl,
    },
    // see https://www.builder.io/c/docs/add-remove-locales.
    locale: 'en-FR', // Inline localization: resolved JSON
  }).toPromise();

  return { props: { content } };
}) satisfies GetServerSideProps<{ content: BuilderContent | null }>

export default function Page({ content }: InferGetServerSidePropsType<typeof getServerSideProps>) {
  
  if (!content) return <div>Loading or 404</div>

  return (
    <BuilderComponent
      model={BUILDER_MODEL}
      content={content}
      locale="en-FR"
    />
  );
}

Use Whole-content entry localization to manage separate entries for each locale. This approach returns a fully localized entry by targeting the locale as a user attribute, rather than resolving individual fields at runtime.

When using the Content API, set the locale as a targeting attribute in the userAttributes parameter when calling builder.get() to fetch the localized entry that matches the targeting rules.

The locale value is a string, such as "en-FR", that specifies which localized entry to render.

The following example fetching and rendering a fully localized content entry using Content entry localization:

import { GetServerSideProps, InferGetServerSidePropsType } from 'next';
import { builder } from '@builder.io/sdk';
import { BuilderComponent, BuilderContent } from '@builder.io/react';

const BUILDER_MODEL = /* ADD YOUR MODEL NAME */;
const BUILDER_PUBLIC_API = /* YOUR PUBLIC API KEY HERE */;

// Initialize Builder
builder.init(BUILDER_PUBLIC_API);

export const getServerSideProps = (async ({ resolvedUrl }) => {
  const content = await builder.get(BUILDER_MODEL, {
    userAttributes: { 
      urlPath: resolvedUrl,
    },
  }).toPromise();

  return { props: { content } };
}) satisfies GetServerSideProps<{ content: BuilderContent | null }>

export default function Page({ content }: InferGetServerSidePropsType<typeof getServerSideProps>) {
  
  if (!content) return <div>Loading or 404</div>

  return (
    <BuilderComponent
      model={BUILDER_MODEL}
      content={content}
    />
  );
}

Integrating localization with Builder Data models is the same as with Page or Section models except that you don't render anything in your code for a Data model. This means that for integrating a Data model, you don't need BuilderComponent for Gen 1 or Content for Gen 2 SDKs.

For more detail on setting up localization in the Builder Data model UI, visit Localizing Data Models.

For example, given a greeting object with localized values for en-US and fr-Fr, Builder transforms it to Hello or Bonjour depending on the locale:

// orginal object with values for each locale
"greeting": {
  "en-US": "Hello",
  "fr-Fr": "Bonjour"
}

Builder transforms the object to use the value that corresponds to the locale, as follows:

// locale=en-US
"greeting": "Hello"
// locale=fr-Fr
"greeting": "Bonjour"

Ideally, you want your app to dynamically adjust to the user's locale.

You can automatically determine the user’s locale based on their system settings by using the Intl.DateTimeFormat() locale and passing it into the locale option:

const res = await fetchOneEntry({
  model: 'page',
  apiKey: /* YOUR PUBLIC API KEY */,
  locale: new Intl.DateTimeFormat().resolvedOptions().locale
  userAttributes: {
    urlPath: window.location.pathname,
  },
});

You may encounter "[object Object]" displaying instead of your localized text content. This typically occurs when localized fields are not properly resolved.

To solve this issue:

  • When using inline localization, ensure you are passing the locale into both the API call and the component.
  • If using the Web Components API, pass locale information into the options attribute rather than a locale attribute, as shown below.
<builder-component
  model="page"
  api-key="your-api-key"
  options='{"locale": "fr-CA"}'>
</builder-component>
  • If dynamically setting the locale with setUserAttributes(), ensure the code calling the function is defined before Builder scripts are loaded.
  • Update your Builder SDK version.

When your codebase and Builder localization are successfully integrated, you can use any Builder localization techniques.

Was this article helpful?