In this chapter you will learn what it takes to support multi-language for your site.


Next.js has native multi-language support, allowing your projects to switch language on the fly.

To back this, Content Studio has a feature called content layering.

Task: Create a layered project

To demonstrate multi-language, you first need to activate support for translating your content in Content Studio. In our case, let’s try Norwegian.

  1. Create a new project in Content Studio by clicking on the Settings cog icon, on the left-hand side of the grid. You will be presented with the currently available projects:

    content studio settings

    Click New…​ button, and select type Layer. Then choose the Movie DB project as the parent

    content studio create layer

    Fill in the rest of the form, using the following values:

    • Name: Film DB

    • Identifier: intro-no

    • Language: norsk (no)

    • Access mode: Public

    • Other fields may be skipped

      After saving and closing the wizard, the new project should appear in the list.

  2. Verify the new layer by going back to the content list (via the pencil icon), and then switching context using the context selector in the top bar.

    After switching context, you should see the following:

    content studio filmdb

  3. Finally publish the project by clicking the Publish button in the top bar.

Task: Set up i18n in Next.js

Next, let’s turn on multi-language support in Next.js.

  1. This template comes with middleware configured to do language detection and redirection. Feel free to study the code in src/middleware.ts to get a better understanding of how it works.

  2. But you need to configure the Enonic adapter, by specifying which content project to use for each locale:

    // ...
    // ...

    Let’s break down the syntax.

    For each comma separated entry, you will find the following pattern: <locale>:<repository>/<sitekey>. In the example above en:intro/hmdb and no:intro-no/hmdb.

    The first entry will map to the defaultLocale that is used in the locale related methods in the NextJS adapter.

    The reason for repeating paths, is that the path may be different in each project/translation.
  3. Next, add the static texts file for every locale to the src/phrases folder. The file name should be <locale>.json, e.g. no.json for Norwegian.

  4. Finally restart your Next.js server to pick up the changes to environment variables.

Task: Translate and publish

As long as your preview configuration was working before you started, Content Studio should automatically be able to detect the right locale for each project.

You may need to restart/rebuild your Next.js server for the changes to be picked up.
  1. In Content Studio, Switch editing context to the Film DB project by toggling in the top left corner of Content Studio.

    Content Studio should automatically be able to detect the correct Next.js locale for the project. Select an item, and you should get a preview.

  2. Translate the site content by selecting the site content, then click localize (rather than edit..). This effectively takes you to the edit form. You may now show off your skills while translating the page to Norwegian.

  3. Once finished, click Mark as Ready and proceed to publish the entire site structure.

    Publish the entire tree by selecting the tree icon in the publishing wizard. content studio mark as ready

  4. Verify that your front-end is working

    Finally, by adding /no (i.e. localhost:4242/no) to the URL of your Next.js server you should now see the published content from the Norwegian project.

Multi front-end setup

In some cases, you may prefer a setup where each language/market is served by a separate Next.js front-end, or you may simply have different sites accessing the same Enonic instance.

Setting up Next.js to do this is just like handling a single language. To enable Content Studio preview to know which Next.js server to use, some additional configuration will be required.

  1. Update the Next.xp configuration file for your Enonic installation by adding multiple entries:

    The sandbox configuration files are located in the sandbox' home directory inside your user’s root directory at .enonic/sandboxes/<your-sandbox-name>/home/config.
    # uncomment to override default values
    # nextjs.default.secret=yourSecret
    # nextjs.default.url=
    # config 'someName'
    # config 'anotherName'
    # ...
  2. Assign the configuration to your site by clicking the pencil icon next to the Next.XP app name in the site form, and selecting it from the list of named configurations:

    content studio configure nextxp

Accessing locale in views

Here are some insight on how to make further use of locales in your Next.js project.

  1. Locale is available as path parameter on the page

    export type PageProps = {
        locale: string,
        contentPath: string[],
    export default async function Page({params}: { params: PageProps }) {
        const {locale, contentPath} = params;
        // ...
  2. Result of fetchContent() call from @enonic/nextjs-adapter/server contains MetaData object (available in every view) that includes locale and defaultLocale along with other calculated runtime data:

    import {PageComponent, RENDER_MODE, XP_REQUEST_TYPE} from '@enonic/nextjs-adapter';
    export interface MetaData {
        type: string;
        path: string;
        requestType: XP_REQUEST_TYPE;
        renderMode: RENDER_MODE;
        requestedComponent?: PageComponent;
        canRender: boolean;
        catchAll: boolean;
        apiUrl: string;
        baseUrl: string;
        locale: string;
        defaultLocale: string;

You can also use I18n.getLocale() and useLocaleContext() to access locale in server-side and client-side components respectively.

Localizing the views

So far we have only localized the content. Here is how you can localize texts in your views:

  1. Remember, we added file for every locale to the src/phrases folder earlier ?

  2. Use useLocaleContext from @enonic/nextjs-adapter to access current locale in client-side components:

    'use client';
    import {useLocaleContext} from '@enonic/nextjs-adapter/client';
    export default function ClientSideComponent() {
        const {locale, localize} = useLocaleContext();
        const localizedText = localize('text.key');
        // ...
The useLocaleContext hook is only available in client-side components.
  1. In server-side components, you can use I18n.getLocale() from @enonic/nextjs-adapter todo the same:

    import {I18n} from '@enonic/nextjs-adapter';
    export default function ServerSideComponent() {
        const locale = I18n.getLocale();
        const localizedText = I18n.localize('text.key');
        // ...

Now that we have everything working, it’s about time you deploy to live servers.