Hamburger Icon
  • Labs icon Lab
  • Core Tech
Labs

Guided: Adding Internationalization and SEO in Next.js 14

In this hands-on lab, you'll enhance a Next.js 14 application with internationalization and SEO best practices. You'll configure Next.js's built-in i18n routing, implement multi-language support, and optimize your app for search engines. By the end, you'll have a globally accessible, SEO-friendly Next.js application showcasing key internationalization techniques.

Labs

Path Info

Level
Clock icon Beginner
Duration
Clock icon 40m
Published
Clock icon Oct 04, 2024

Contact sales

By filling out this form and clicking submit, you acknowledge our privacy policy.

Table of Contents

  1. Challenge

    Configuring Internationalization in Next.js

    Introduction to Setting Up i18n

    In this step, you will enhance your Next.js application by adding internationalization (i18n) support. Internationalization allows your application to serve content in multiple languages, making it accessible to users worldwide. By configuring i18n, you'll lay the foundation for rendering content in different languages in subsequent steps.

    Important Notes:

    • Throughout this process, be careful to preserve any existing code in the files you're modifying unless explicitly instructed to remove it. This ensures you keep important elements like reactStrictMode and global style imports.
    • The root directory is nextjs-seo-internationalization

    Relevant Project Structure Overview:

    • next-i18next.config.js: A configuration file in the root directory that defines the supported languages (locales) and sets the default language for your application.
    • next.config.js: The Next.js configuration file, also in the root directory, where you'll integrate the i18n settings.
    • pages/_app.js: The custom App component in your pages directory, where you'll initialize internationalization for your application.

    Objectives

    • Define supported languages (locales) for your application using the i18n variable.
    • Set a default language.
    • Configure your application to recognize and use these settings.
    • Ensure your application runs without errors after the configuration.

    What You'll Do

    Add internationalization support to your Next.js application by:

    1. Creating next-i18next.config.js inside the nextjs-seo-internationalization folder to define the supported languages and set the default language. Remember to use module.exports to export the configuration.

      • Create an i18n object within your configuration file

      • Set locales: In the i18n object, add a locales array to define the languages your application will support. For this lab, you will support English ('en') and Spanish ('es').

      • Set defaultLocale: Also within the i18n object, add defaultLocale and set it to 'en' to make English the default language of your application.

      • Export the configuration: Use module.exports to export the configuration object containing the i18n settings.

      • Tip: You can create the file either via the UI or by using the terminal. If using the terminal:

      cd nextjs-seo-internationalization
      touch next-i18next.config.js
      
    2. Updating next.config.js to include the internationalization settings alongside the existing reactStrictMode setting.

      • Import the i18n Settings: Import the i18n configuration from the next-i18next.config.js file you just created.
      • Integrate i18n into Next.js Config: Include the imported i18n variable in your Next.js configuration object by adding an i18n property.
      • Preserve Existing Settings: Ensure you keep the existing reactStrictMode setting alongside the new i18n setting.
      • Ensure Proper Export: Make sure the Next.js configuration, including both the existing reactStrictMode setting and the new i18n settings, is correctly exported.
      • Hint #1: Use require or ES6 import statements to import modules.
      • Hint #2: Remember how to export modules in JavaScript using module.exports.
    3. Modifying pages/_app.js to initialize internationalization in your application while preserving the existing import for global styles.

      • Import Necessary Function: Import appWithTranslation higher-order component from the next-i18next library.
      • Preserve Existing Imports: Ensure you keep the existing import for global styles ('../styles/globals.css').
      • Wrap Your App Component: Use appWithTranslation to wrap your main App component, enabling i18n support across all pages.
      • Export the Enhanced Component: Ensure the wrapped App component is exported correctly.
    4. Running the development server with npm run dev to verify that your application starts without errors. Once the server is running, open and refresh the Web Browser tab in the lab environment and navigate to http://localhost:3000 and ensure your application is functioning correctly.

    info> If you get stuck at any point during this exercise, you can refer to the solutions directory for guidance. The solutions are provided to help you learn, but try to solve the tasks on your own first! With the i18n configuration in place, your application is now prepared to handle multiple languages. This foundational step enables you to serve content in different locales, enhancing the accessibility of your site. In the next step, you'll create translation files to provide localized content for your users.

  2. Challenge

    Creating Translation Files

    Introduction to Content Localization

    Now that your application supports internationalization, you need to create translation files that store the translated strings for each language. These files will enable your application to display content in the user's selected language, ensuring a personalized and accessible experience for a global audience.

    Relevant Project Structure Overview

    • public/locales/: The directory where your translation files will be organized.
    • public/locales/en/common.json: Contains English translations.
    • public/locales/es/common.json: Contains Spanish translations.

    Objectives

    • Organize translation files effectively within the project structure.
    • Create separate translation files for each supported language.
    • Ensure that your application can access and use these translation files without issues.

    What You'll Do

    1. Create the Locales Directory

      • Organize Your Translation Files: Create a locales directory within the public folder of your project. This directory will house all your translation files, keeping them organized and easily accessible.
    2. Add Locale Subdirectories

      • Separate Languages: Inside the locales directory, create subdirectories for each supported language. For this lab, you will create en for English and es for Spanish. This separation ensures that translations are neatly organized by language.
    3. Create common.json Files

      • Define Translated Strings: Within each language subdirectory (en and es), create a common.json file. These JSON files will store key-value pairs where keys are identifiers used in your application, and values are the corresponding translated strings.

      • Populate Translations: Add the following pre-populated translations to each common.json file:

        For en/common.json:

        {
          "welcome": "Welcome to our store!",
          "product": {
            "price": "Price",
            "backToHome": "Back to Home"
          },
          "meta": {
            "homeTitle": "Welcome to My E-commerce Site",
            "homeDescription": "Discover the best products in our store."
          }
        }
        

        For es/common.json:

        {
          "welcome": "¡Bienvenido a nuestra tienda!",
          "product": {
            "price": "Precio",
            "backToHome": "Volver al inicio"
          },
          "meta": {
            "homeTitle": "Bienvenido a Mi Sitio de Comercio Electrónico",
            "homeDescription": "Descubre los mejores productos en nuestra tienda."
          }
        }
        ``` By setting up the translation files for each supported locale, your application now has the necessary resources to display content in both English and Spanish. This organization ensures that all textual content is easily maintainable and scalable as you add more languages in the future. In the next step, you'll implement language-specific content rendering to dynamically display translated content in your components.
  3. Challenge

    Implementing Language-Specific Cotent Rendering

    Introduction to Rendering Translated Content

    With your translation files in place, it's time to modify your application to display content based on the selected language. This involves updating your components to use the useTranslation hook from next-i18next, replacing hardcoded text with translation keys, and ensuring that translations are loaded server-side. By implementing these changes, your application will dynamically render content in the user's chosen language, enhancing the overall user experience for a global audience.

    Note: In this lab, the language switching will only be implemented on the home page (pages/index.js). Other pages, such as the product detail page (product/[id].js), will remain in English.

    Relevant Project Structure Overview

    • pages/index.js: The main page of your application, which will be updated to render language-specific content.
    • pages/_app.js: The custom App component, already configured for internationalization, ensuring that translations are available throughout your application.

    Objectives

    • Import and utilize the useTranslation hook in your components.
    • Replace hardcoded text with translation keys to fetch appropriate translations.
    • Load translations server-side using getStaticProps and serverSideTranslations.
    • Ensure that your application correctly renders content in the selected language without errors.

    What You'll Do

    1. Import the useTranslation Hook

      • Access Translations: In your components, import the useTranslation hook from next-i18next to access translation functions.

        • Hint #1: The useTranslation hook allows you to retrieve translated strings based on keys defined in your common.json files.

        • Hint #2: Ensure that you're importing from the correct library (next-i18next).

        import { useTranslation } from 'next-i18next';
        
    2. Replace Hardcoded Text with Translation Keys

      • Use the t Function: Replace any hardcoded strings in your components with translation keys using the t function provided by the useTranslation hook.

        Understanding the t Function:

        • The t function is a translation function that takes a translation key as input and returns the corresponding translated string based on the current locale.
        • It looks up the key in your translation files (e.g., common.json) and retrieves the appropriate text.

        How to Use the t Function:

        • Initialize the t Function in Your Component:

          const { t } = useTranslation('common');
          

          The 'common' parameter refers to the namespace of your translation files, matching the common.json files you created earlier.

        • Replace Hardcoded Strings with t Function Calls

          Before:

          <h1>Welcome to our store!</h1>
          

          After:

          <h1>{t('welcome')}</h1>
          

          Explanation: The key 'welcome' corresponds to an entry in your common.json files.

        • Access Nested Translation Keys: Use dot notation to access nested keys in your translation files.

          <p>{t('meta.homeDescription')}</p>
          

          Explanation: This accesses the homeDescription key within the meta object in your common.json files.

        • Ensure Keys Match Your Translation Files: Double-check that the keys you use in the t function match those defined in your common.json files to avoid missing translations.

        • Using the t Function in index.js

          // pages/index.js
          import { useTranslation } from 'next-i18next';
          
          export default function Home() {
            const { t } = useTranslation('common');
          
            return (
              <div>
                <h1>{t('welcome')}</h1>
                <p>{t('meta.homeDescription')}</p>
                <p>{t('product.price')}: $99.99</p>
              </div>
            );
          }
          
    3. Load Translations Server-Side

      • Implement getStaticProps: Use getStaticProps along with serverSideTranslations to load the necessary translations during build time, ensuring that translated content is available when the page is rendered.

        • Hint #1: The serverSideTranslations function is essential for fetching translations based on the current locale.

        • Hint #2: Ensure that the locale parameter is correctly passed to serverSideTranslations.

        Example:

        // pages/index.js
        import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
        
        export async function getStaticProps({ locale }) {
          return {
            props: {
              ...(await serverSideTranslations(/*you must fill, ['you must fill'*/])),
            },
          };
        }
        

        Explanation: This function fetches the translations for the common namespace based on the current locale.

    4. Verify Changes

      • Run the Development Server:

        • Start your development server with:
          npm run dev
          
        • Navigate to http://localhost:3000 in your browser.
      • Check Content Display:

        • Ensure that the content displays correctly in both supported languages (en and es).
        • Switch the language by changing the URL (e.g., adding /en or /es at the end) or using a language switcher if implemented.
      • Ensure No Errors:

        • Confirm that there are no errors related to missing translations or incorrect configurations in the console. With language-specific content rendering implemented, your application can now dynamically display content based on the user's selected language. This enhancement ensures a personalized and seamless user experience across different locales. In the next step, you'll add a language switcher component, empowering users to toggle between their preferred languages effortlessly.
  4. Challenge

    Implementing a Language Switcher

    Introduction to Implementing a Language Switcher

    Enhancing user experience by allowing users to manually switch between supported languages is a crucial aspect of internationalization. In this step, you will complete a mandatory language switcher component that enables users to toggle between English and Spanish seamlessly on the home page. By focusing on the home page, you'll implement the core functionality of language switching without adding complexity to other parts of the application.

    Note: In this lab, the language switcher will only be implemented on the home page (pages/index.js). Other pages, such as the product detail page (product/[id].js), will remain in English. This approach allows you to concentrate on the main concepts of internationalization without overwhelming complexity.

    This feature empowers users to choose their preferred language on the main page, making your application more accessible and user-friendly for a diverse audience.

    Objectives

    • Complete the LanguageSwitcher Component
    • Integrate the LanguageSwitcher into the Home Page
    • Ensure Smooth Language Switching on the Home Page
    • Maintain Consistency and Accessibility

    What You'll Do

    1. Complete the LanguageSwitcher Component

      • Open the existing file components/LanguageSwitcher.js.
      • Import useRouter from next/router and Link from next/link.
      • Use useRouter to get locale, locales, and asPath.
      • Implement the component logic:
        • Map through locales.
        • Skip rendering for the current locale.
        • For other locales, render a Link component with the correct props.
        • Inside the Link, render a button with appropriate styling and text.
    2. Integrate the LanguageSwitcher into pages/index.js

      • Import the LanguageSwitcher Component at the top of the file:
        import LanguageSwitcher from '../components/LanguageSwitcher';
        
      • Import useRouter from next/router
        import { useRouter } from 'next/router';
        
      • Access the Current Locale in your Home component
        const { locale } = useRouter();
        
      • Update Product Names to Use the Selected Language
        • Replace {product.name.en} with {product.name[locale]} in your product mapping.
      • Add the <LanguageSwitcher /> Component near the top of your returned JSX, before your main content
        return (
          <div className={styles.container}>
            <LanguageSwitcher />
            {/* Rest of your content */}
          </div>
        );
        
    3. Verify Functionality

      • Test Language Switching:
        • Run your development server and switch between English and Spanish.
        • Ensure that the application's content, including product names, updates accordingly.
      • Check URL Localization:
        • Verify that the URL reflects the selected language (e.g., /en or /es).
      • Confirm No Errors:
        • Check for console errors and resolve any issues related to the language switching functionality. By adding a language switcher, you've empowered users to effortlessly toggle between English and Spanish, enhancing the overall user experience and accessibility of your application. This interactive feature ensures that users can engage with your content in their preferred language without any hindrance. In the next step, you'll focus on configuring dynamic metadata for SEO to further optimize your application for search engines.
  5. Challenge

    Configuring Dynamic Metadata for SEO

    Introduction to Configuring Dynamic Metadata for SEO

    Optimizing your application for search engines is essential for improving visibility and attracting a broader audience. In this step, you'll enhance your Next.js application by implementing dynamic metadata tailored to each supported language. This involves creating an SEO component that sets the page's <title> and <meta name="description"> tags based on the current locale and translations. By doing so, you ensure that search engines index your site effectively, providing relevant information to users in their preferred language.

    Key Concepts:

    • Head Component Integration: The Head component from next/head allows you to modify the <head> section of your HTML document, enabling you to set dynamic metadata such as <title> and <meta> tags.
    • useTranslation Hook: Provides the t function to fetch translated strings based on keys defined in your common.json files.
    • Dynamic Metadata: By passing titleKey and descriptionKey to the SEO component, you can dynamically set the page's title and description based on the selected language.

    Project Structure Overview

    In this step, you'll primarily work with the following files:

    • components/SEO.js: A new component responsible for setting dynamic metadata (<title>, <meta name="description">, etc.) based on the current locale.
    • pages/index.js: The main page of your application, which will be updated to include the SEO component.

    Objectives

    • Create an SEO Component: Develop a reusable component that dynamically sets metadata based on translation key props and the current locale.
    • Integrate the SEO Component into Pages: Incorporate the SEO component into your pages to ensure that each page has appropriate metadata.
    • Utilize Translations for Metadata: Leverage your existing translation files (common.json) to provide localized metadata.
    • Enhance SEO Performance: Improve your application's search engine optimization by providing accurate and relevant metadata for each language.

    What You'll Do

    1. Create the SEO Component

      • Define the Component Structure: The SEO component should accept two props: titleKey and descriptionKey.
      • Implement Dynamic Metadata Logic: Use the useTranslation hook to fetch translation strings.
      • Integrate with Next.js Head: Utilize Next.js's Head component to inject metadata into the <head> section.
      • Style and Optimize: Ensure that the SEO component is efficient and extensible.
    2. Integrate the SEO Component into pages/index.js

      • Import the SEO Component: Bring the newly created SEO component into your main page.
      • Pass Translation Key Props: Use appropriate translation keys when implementing the SEO component.
      • Ensure Metadata Reflects Current Locale: Verify that metadata updates based on the selected language.
    3. Verify Functionality

      • Run the Development Server: Start your server and inspect the page's <head> section.
      • Check Metadata in Different Languages: Switch between languages to confirm metadata changes. With dynamic metadata configured, your application now sets appropriate <title> and <meta name="description"> tags based on the current locale. This optimization significantly improves your site's SEO, making it more discoverable and relevant to users in different languages. In the final step, you'll implement hreflang tags to inform search engines about language-specific versions of your webpages, further enhancing your international SEO strategy.
  6. Challenge

    Implementing hreflang Tags for Language Alternatives

    Introduction to Implementing hreflang Tags for SEO

    Search Engine Optimization (SEO) is crucial for making your application discoverable by users across different languages and regions. The hreflang attribute plays a key role in informing search engines about the language and regional targeting of your webpages. By implementing hreflang tags, you ensure that users are directed to the correct language version of your site, enhancing user experience and improving international SEO performance.

    Key Concepts

    • hreflang Attributes: Inform search engines about the language and regional targeting of your webpages, helping them serve the most appropriate version to users based on their language and location.
    • Canonical Tags: Prevent duplicate content issues by specifying the preferred version of a webpage.

    Project Structure Overview In this step, you'll primarily work with the following files:

    • components/SEO.js: The existing SEO component that will be updated to include hreflang tags and canonical links.
    • pages/index.js: Ensuring proper integration of the updated SEO component.

    Objectives

    • Add hreflang Links: Incorporate hreflang link tags using the Head component from next/head.
    • Reference All Locales: Ensure that each page includes hreflang tags for all supported locales (en and es).
    • Set Canonical Tags: Define canonical URLs to prevent duplicate content issues.
    • Ensure Consistency: Maintain consistency between translation files and hreflang implementations.
    • Validate Implementation: Verify that hreflang and canonical tags are correctly rendered.

    What You'll Do

    1. Update the SEO Component (components/SEO.js)

      • Import Necessary Modules
        import { useRouter } from 'next/router';
        
      • Access Router Properties Use useRouter to access locales, locale, and asPath.
      • Define Your Site URL
        const siteUrl = 'http://localhost:3000'; // Replace with your actual domain in production
        
      • Add Canonical Link Tag
        <link rel="canonical" href={`${siteUrl}/${locale}${asPath}`} />
        
      • Incorporate hreflang Link Tags
        {locales.map((loc) => (
          <link
            key={loc}
            rel="alternate"
            hrefLang={loc}
            href={`${siteUrl}/${loc}${asPath}`}
          />
        ))}
        
      • Include a Default hreflang Tag
        <link
          rel="alternate"
          hrefLang="x-default"
          href={`${siteUrl}${asPath}`}
        />
        
    2. Verify Implementation

      • Inspect the Page Source
      • Check hreflang and Canonical Tags
      • Switch Languages and Re-Verify
      • Validate with SEO Tools By implementing hreflang and canonical tags, your application now provides clear signals to search engines about the language and regional targeting of your webpages. This setup ensures that users are directed to the correct language version of your site in search results, thereby improving both visibility and user experience on a global scale. Congratulations! You have successfully enhanced your Next.js application with internationalization and SEO best practices, making it accessible and optimized for a diverse international audience.
  7. Challenge

    Conclusion

    Congratulations on Successfully Completing the Adding Internationalization and SEO in Next.js 14 Lab!

    You've made impressive progress in mastering internationalization and SEO best practices within a Next.js 14 application. Throughout this lab, you've configured multiple locales, localized your content, and optimized your application for search engines, ensuring it effectively reaches a global audience.

    Summary of Your Achievements

    1. Internationalization (i18n) Configuration:

      • Setup: You've configured Next.js's built-in internationalization routing by defining supported locales (en and es) and setting the default locale in next.config.js.
      • Impact: This foundational setup enables your application to serve content in multiple languages, laying the groundwork for a globally accessible site.
    2. Creating Translation Files:

      • Setup: You created organized translation files (common.json) for each supported language within the public/locales directory.
      • Impact: These translation files store all necessary translated strings, allowing your application to display content dynamically based on the user's selected language.
    3. Implementing Language-Specific Content Rendering:

      • Implementation: By utilizing the useTranslation hook from next-i18next, you replaced hardcoded text with translation keys, enabling your components to render content in the selected language seamlessly.
      • Impact: This ensures a personalized and accessible experience for users across different locales, enhancing user engagement.
    4. Implementing a Language Switcher:

      • Implementation: You developed and integrated a Language Switcher component that allows users to toggle between English and Spanish effortlessly.
      • Impact: This interactive feature empowers users to choose their preferred language, making your application more user-friendly and inclusive.
    5. Configuring Dynamic Metadata for SEO:

      • Implementation: You created a reusable SEO component that dynamically sets the <title> and <meta name="description"> tags based on the current locale and translation keys.
      • Impact: Dynamic metadata improves your site's SEO by providing relevant and localized information to search engines, enhancing discoverability.
    6. Implementing hreflang Tags for Language Alternatives:

      • Implementation: You enhanced the SEO component to include hreflang and canonical tags, informing search engines about language-specific versions of your webpages and specifying preferred URLs.
      • Impact: This optimization prevents duplicate content issues and ensures that users are directed to the correct language version of your site in search results, boosting international SEO performance.

    Enhancing Your Application

    Here are some key implementations you've completed and their significance:

    • i18n Routing Configuration:
      • Functionality: Ensures that your application correctly routes users to content in their selected language, maintaining a consistent and user-friendly URL structure.
    • Translation Integration:
      • Functionality: Replaces static text with dynamic translations, enabling your application to display content in multiple languages without the need for duplicate pages.
    • Language Switcher Functionality:
      • Functionality: Provides users with an intuitive interface to switch languages, with the application's content updating instantly to reflect their choice.
    • SEO Optimization:
      • Functionality: By setting dynamic metadata and implementing hreflang tags, you've made your application more discoverable and relevant to users in different languages, enhancing your global reach.

    Further Development

    While you've built a solid foundation for internationalization and SEO, there's always room for enhancement:

    • Add Translations to Specific Product Pages:

      • Action: Extend your internationalization efforts to individual product pages, ensuring that product details are available in all supported languages.
    • Expand Locale Support:

      • Action: Consider adding more languages to broaden your application's accessibility.
    • Refine Translation Files:

      • Action: Continuously update and maintain your translation files to include all new content and ensure accuracy.
    • Explore Advanced SEO Strategies:

      • Action: Implement structured data, optimize performance, and explore other SEO best practices to further boost your site's search engine ranking.
    • Integrate Automated Testing:

      • Action: Enhance your testing strategy by adding automated tests for internationalized routes and SEO tags to ensure reliability and effectiveness.

    Further Learning Resources

    To continue enhancing your skills in Next.js, internationalization, and SEO, Pluralsight offers extensive courses that cover these topics and more. Dive deeper into modern web development, React frameworks, and advanced SEO techniques to build more complex, globally accessible, and search engine optimized applications.

Victor is an Assessment Author.

What's a lab?

Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.

Provided environment for hands-on practice

We will provide the credentials and environment necessary for you to practice right within your browser.

Guided walkthrough

Follow along with the author’s guided walkthrough and build something new in your provided environment!

Did you know?

On average, you retain 75% more of your learning if you get time for practice.