Blog>
Snippets

Utilizing the Provider Pattern with Next.js Internationalization

Set up a context provider for managing internationalization state in a Next.js 14 application, allowing deeply nested components to access and update language settings.
import { createContext, useContext, useState, useEffect } from 'react';

// Define the context
const I18nContext = createContext(null);

export const I18nProvider = ({ children }) => {
  // Initialize state to store the current locale
  const [locale, setLocale] = useState('en');

  // Update the locale state
  function changeLocale(newLocale) {
    setLocale(newLocale);
  }

  // Provide the current locale and the changer function to the tree
  return (
    <I18nContext.Provider value={{ locale, changeLocale }}>
      {children}
    </I18nContext.Provider>
  );
};

// Custom hook for consuming the context
export const useI18n = () => useContext(I18nContext);
The code segment sets up a new React context for internationalization called 'I18nContext'. An 'I18nProvider' component is created to manage the state of the current locale and provide a function to change it. Additionally, a custom hook 'useI18n' is exported to simplify the use of this context in the components.
import { useEffect } from 'react';
import { useRouter } from 'next/router';
import { I18nProvider } from 'path-to-your-i18n-provider'; // Adjust the import path

const MyApp = ({ Component, pageProps }) => {
  const router = useRouter();

  // Sync Next.js router locale with the custom context's locale
  useEffect(() => {
    // You call your context method to set the locale here
    // For example: setLocale(router.locale);
  }, [router.locale]);

  return (
    <I18nProvider>
      <Component {...pageProps} />
    </I18nProvider>
  );
};

export default MyApp;
This code wraps the entire application with the 'I18nProvider' component to make the internationalization context available to all components. The Next.js 'useRouter' hook is used to sync the context's locale state with the Next.js router's locale.
import { useI18n } from 'path-to-your-i18n-provider'; // Adjust the import path

const SomeDeepNestedComponent = () => {
  const { locale, changeLocale } = useI18n();

  return (
    <div>
      Current Locale: {locale}
      <button onClick={() => changeLocale('es')}>Change to Spanish</button>
      <button onClick={() => changeLocale('en')}>Change to English</button>
    </div>
  );
};

export default SomeDeepNestedComponent;
This code demonstrates how a deeply nested component can use the 'useI18n' hook to access and update the language settings. It can read the current locale and provide a way for users to change the locale using buttons.