Building a Multilingual Site in Sitecore JSS with Next.js – A Developer’s Journey

"How do I build a multilingual Sitecore JSS application with Next.js?" That’s the question that haunted Alex, our Fictitious Sitecore Developer!

· Sitecore , Sitecore JSS , Tutorials

"How do I build a multilingual Sitecore JSS application with Next.js?"

That’s the question that haunted Alex, our Fictitious Sitecore Developer!

Article content

As he sipped his coffee, staring at the project backlog. The client, a global brand, needed their website in multiple languages, with seamless switching, SEO-friendly URLs, and localized content served efficiently.

"Challenge accepted!" Alex thought, opening his Sitecore instance and setting up his JSS Next.js app.


🚀 Step 1: Setting Up the Sitecore JSS Project

Before diving into multilingual setup, Alex had to ensure his JSS project was up and running.

Install JSS with Next.js

npx create-sitecore-jss@latest my-multilingual-app --template nextjs
cd my-multilingual-app        

He configured the JSS App to work with Sitecore, setting up the connection:

jss setup        

At this point, Alex had a working Sitecore JSS Next.js app.


🌍 Step 2: Configuring Multilingual Support in Sitecore

Now, Alex needed to configure multiple languages in Sitecore. He navigated to /sitecore/system/Languages/ and added the required languages:

  • en (English)
  • fr-FR (French)
  • es-ES (Spanish)

Then, he set up the content tree with localized versions under /sitecore/content/MyApp/Home with language versions for each item.

Important Configurations in sitecore/config/*.config

He added allowed languages in the Sitecore configuration:

<configuration>
  <sitecore>
    <settings>
      <setting name="AllowedLanguages" value="en,fr-FR,es-ES" />
    </settings>
  </sitecore>
</configuration>        

🛠 Step 3: Configuring Next.js for Multilingual Routing

Alex turned to i18n settings in Next.js to handle multiple languages. In next.config.js, he added:

module.exports = {
  i18n: {
    locales: ['en', 'fr-FR', 'es-ES'],
    defaultLocale: 'en',
  },
};        

This ensured that the Next.js app understood which languages were supported and how to handle language switching in URLs (e.g., /fr-FR/about for French).


🔗 Step 4: Fetching Language-Specific Content from Sitecore

To make sure JSS pulled the right language version, Alex modified sitecore/api.ts to fetch content dynamically based on the active language:

import { GraphQLRequestClient } from '@sitecore-jss/sitecore-jss-nextjs';
const API_URL = process.env.SITECORE_GRAPHQL_ENDPOINT;
const API_KEY = process.env.SITECORE_API_KEY;
export async function getPageData(route, locale) {
  const client = new GraphQLRequestClient(API_URL, {
    headers: { 'sc_apikey': API_KEY },
  });
  const query = `{
    item(path: "${route}", language: "${locale}") {
      id
      name
      fields {
        field {
          name
          value
        }
      }
    }
  }`;
  return client.request(query);
}        

Now, when a user switched languages, the app would dynamically pull the correct localized content.


🌀 Step 5: Implementing Language Switcher Component

To allow users to switch languages easily, Alex created a LanguageSwitcher component:

📁 components/LanguageSwitcher.js

import { useRouter } from 'next/router';
import Link from 'next/link';
const LanguageSwitcher = () => {
  const { locale, locales, asPath } = useRouter();
  return (
    <div>
      {locales.map((lng) => (
        <Link key={lng} href={asPath} locale={lng}>
          <button disabled={lng === locale}>
            {lng.toUpperCase()}
          </button>
        </Link>
      ))}
    </div>
  );
};
export default LanguageSwitcher;        

✅ This allowed the user to switch languages without losing the current page context.


📡 Step 6: Handling Server-Side Rendering for Multilingual Pages

Since Next.js supports both static and server-side rendering, Alex wanted to make sure the localized pages were built correctly.

📁 pages/[...slug].js

import { getPageData } from '../sitecore/api';
import { useRouter } from 'next/router';
export async function getServerSideProps({ params, locale }) {
  const route = '/' + (params.slug ? params.slug.join('/') : '');
  const pageData = await getPageData(route, locale);
  return {
    props: { pageData },
  };
}
const Page = ({ pageData }) => {
  const { locale } = useRouter();
  return (
    <div>
      <h1>{pageData.item?.name} ({locale.toUpperCase()})</h1>
      <p>{pageData.item?.fields[0]?.value}</p>
    </div>
  );
};
export default Page;        

✅ This setup ensured each page dynamically fetched content based on language.


🖥 Step 7: Testing the Multilingual Setup

After deploying everything, Alex tested the implementation:

🚀 Success! The content changed dynamically based on language, and the URLs were SEO-friendly.


📌 Step 8: Deploying to Production

Finally, Alex pushed everything to Vercel for deployment:

git add .
git commit -m "Added multilingual support"
git push origin main        

And with one simple command, he deployed:

vercel        

🎉 The Final Takeaway

Alex sat back and admired his work. His Sitecore JSS app with Next.js now had:

Multilingual support

SEO-friendly localized URLs

Dynamic content fetching

A seamless language switcher

"On to the next challenge!" he thought, as he grabbed another coffee.

🚀 And that’s how you build a multilingual Sitecore JSS app with Next.js!

💬 What challenges have you faced while implementing multilingual support in Sitecore JSS? Drop them in the comments!

#Sitecore #JSS #NextJS #Multilingual #DXP #HeadlessCMS


Photograph of Ashish Kapoor

About the author

Ashish Kapoor

Global Director of Marketing Technology | Chief Technology Advisor | Architecting the Future with SaaS MACH & Agentic AI | 2x Sitecore Ambassador MVP

  • 21+ years in enterprise product architecture
  • Sitecore MVP Ambassador (2023, 2024)
  • Global digital delivery across 40+ countries
  • 100+ AI agents shipped in production
  • $2M+ MarTech rationalisation savings
Read the full bio