Customizing next.js _error page with i18n localization

Looking to create a customized error page for my Next.js project. I've been using the getServerSideProps method to localize my other pages, but I'm running into issues with translating strings on the _error page. I attempted to use the getStaticProps method as well, but haven't had any luck.

const CustomError = ({ statusCode, hasGetInitialPropsRun, err, pageRootRef }) => {
  const { t } = useTranslation(["error", "common"]);
  return (
      <Layout pageRootRef={pageRootRef}>
        <Head>
          <title>{t("title")}</title>
        </Head>
        <div id="_error" className="_error">
          <div className="pt-5 pb-6">
            <div className="max-w max-640">
              <h1 className="mb-2 t-alignC">{t("heading")}</h1>
              <Hairline color="green" />
              <div className="max-w max-128 mb-5">
                <Image
                    src={`{cdnAssetPrefix}/images/pete/pete-confused.png`}
                    className="fit"
                    alt=""
                    width={128}
                    height={137}
                />
              </div>
              <p>
                {t("go-back-paragraph.go-back")}{""}
                {t("go-back-paragraph.sign-in-again")}
              </p>
              <div className="t-alignC">
                <Link href={LOGIN_URL}>
                  <a className="btn-link btn-xl">
                    {t("go-back-paragraph.go-to-login")}
                  </a>
                </Link>
              </div>
            </div>
          </div>
        </div>
      </Layout>
  );
};

export async function getStaticProps({locale}) {
  return {
    props: { ...(await serverSideTranslations(locale, ["error", "common"])) }
    }
}

Answer №1

When faced with an error, I implemented a clever workaround by directing the user to a personalized error page.

To achieve this, I organized all my custom error pages under pages/error/. Then, I extracted the value of the accept-language header from the initial request and compared it with the locales specified in my i18n configuration (utilizing next-translate). Subsequently, I could dynamically generate a redirect path based on this analysis.

import i18n from '@/../i18n';
import { Routes } from '@/utils/enums';
import { NextPageContext } from 'next';
import router from 'next/router';

interface ErrorProps {
  statusCode: number;
}

export const ErrorPage = ({ statusCode }: ErrorProps) => {
  return (
    // The getInitialProps method will handle this part
    <p>
      {statusCode
        ? `An error ${statusCode} occurred on server`
        : 'An error occurred on client'}
    </p>
  );
};

ErrorPage.getInitialProps = ({ req, res, err }: NextPageContext) => {
  let redirectPath: string;

  const addErrorCodeToPath = (initialPath: string, statusCode: number) => {
    switch (statusCode) {
      case 404:
        initialPath += Routes.ERROR_404; // "/error/404"
        break;
      case 500:
        initialPath += Routes.ERROR_500; // "/error/500"
        break;
      default:
        initialPath += Routes.ERROR_500;
        break;
    }
    return initialPath;
  };

  if (res) {
    // server
    let locale = '';
    const acceptedLangsHeaderValue = req?.headers['accept-language'];

    if (typeof acceptedLangsHeaderValue === 'string') {
      const acceptedLocales: string[] = [];
      acceptedLocales.push(
        ...acceptedLangsHeaderValue.split(';')[0].split(',')
      );
      locale =
        acceptedLocales.find((acceptedLocale) => {
          return i18n.locales.includes(acceptedLocale.split('-')[0]);
        }) ?? '';
    }

    redirectPath = locale && locale !== i18n.defaultLocale ? `/${locale}` : '/';

    redirectPath = addErrorCodeToPath(redirectPath, res.statusCode);

    res.writeHead(302, {
      Location: redirectPath,
    });
    res.end();
    return;
  }
  // client
  redirectPath = router.locale ? `/${router.locale}` : '';
  redirectPath = addErrorCodeToPath(redirectPath, err?.statusCode ?? 500);
  router.push(redirectPath);
};

export default ErrorPage;

Here is a snippet of i18n.js:

const i18n = {
  locales: ['de', 'en'],
  defaultLocale: 'de',
  pages: {
    '*': ['common'],
    '/error/404': ['error'],
    '/error/500': ['error'],
  },
};

module.exports = i18n;

Answer №2

Dealing with a similar issue led me to find a solution that works. Here's how I resolved it:

// custom-i18n.config.js
module.exports = {
    //...
    availableLanguages: ['en','zh','de'], // <- include your options here
}

Include the necessary languages as the fourth parameter

export async function fetchLocalizedData({language}) {
    return {
        data: { ...(await serverSideTranslations(language, ["error", "common"], null, ['en','zh','de'])) }
    }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

I am having trouble with my jQuery login function not properly connecting to the PHP file

Hey there, I've been working on creating a login system from scratch by following an online tutorial. The initial Javascript is functioning properly as it detects errors when the inputs are empty. However, once I enter text into the input fields and c ...

Unbinding or undoing an 'onclick' event when another 'onclick' event is triggered

I am facing an issue where clicking on elements with 'onclick' functions works as expected, but when I click on a different element with another 'onclick' function, the first one remains active. What I actually want is for the previous ...

Using brush strokes to create a unique design on the canvas page

Currently, I am working on implementing a brush-like effect on a web page. The task involves providing multiple patterns/textures in the background and allowing users to drag their mouse to create the pattern effect on the page. If you want to see the st ...

The Ajax function fails to trigger during the first load of the page

Note: Kindly refer to the update at the end of this question before proceeding. The problem described is specific to IE 11 and emerged after a recent Windows update. Following the installation of 5 updates, including one for IE, I removed the latter hopin ...

Encountering the error message "Cannot GET /" when trying to access the front page using Express.js

I am a beginner in Node.js. I have been learning through videos and documentation, and I started developing a site following an MVC structure. The node server appears to be working fine, but I am facing an issue where the front end displays 'Cannot GE ...

NUXT: Module node:fs not found

Encountering an error when running yarn generate in a Kubernetes container during production. The same command works fine locally and was also functioning properly in production up until last week. Error: Cannot find module 'node:fs' Require stac ...

Tips for implementing vue.js composition api with vue-3-socket.io

Is there a way to access the socket instance within the setup function of a Vue.js component? I am utilizing vue-3-socket.io in my main.js import VueSocketIO from 'vue-3-socket.io' import SocketIO from 'socket.io-client' Vue.use(new ...

Implementing CSS styles with jQuery

Looking for a way to dynamically add CSS attributes to different form elements like text fields, text areas, checkboxes, and dropdowns? There's also a separate block that lists possible CSS properties such as font, font-style, width, and padding. What ...

When attempting to print a Rectangle on my webpage using JavaScript and taking user input, I encountered an error stating that 'str' is not defined

I'm trying to implement a feature where clicking on the "try it" button will prompt the user for the number of lines and then print that many lines in the form of a rectangle. However, when I run my code, nothing appears on the DOM and there is an err ...

Problem with jQuery datetimepicker plugin not being identified as a date by Date() object wrapper

I have a component that allows users to select a date and time using the datetimepicker plugin found at this link. Here is my current configuration: $('#startDate').datetimepicker({ format: 'Y-m-d\\TH:i:s', }); When I c ...

React component making repeated calls to my backend server

As a React newbie, I am currently in the process of learning and exploring the framework. I recently attempted to fetch a new Post using axios. However, upon hitting the '/getPost' URL, I noticed that the GetPost component continuously calls the ...

What are the steps to validate an Ajax form using Dojo JavaScript?

Currently, I am in the process of validating a form that has been written in Javascript/Dojo before sending it via Ajax. Here is the code snippet: <script src="http://ajax.googleapis.com/ajax/libs/dojo/1.6/dojo/dojo.xd.js" type="text/javascript" djConf ...

Images from the section will not be shown when retrieving data from the sanity io database

Currently, I am in the process of creating my portfolio website using Next.js and Sanity as my CMS. One issue I encountered was pulling images to display on different sections of the project details page. Although I uploaded the images to my database thr ...

Remove all links with a specific class within a <div> element, excluding the one that was clicked

Is there a way in jQuery to manipulate all links inside a <div> by removing/disabling or changing their classes, except for the one that was clicked? I need to change the class of the clicked link while potentially hiding or altering the others. < ...

Is it possible to utilize jQuery's .wrap or .wrapInner to encase a variety of elements within them?

I am working with a HTML structure that looks like this: <section> <item> <ele class="blue" /> <ele class="green" /> <ele class="red" /> </item> <item> <ele class="blue" /> <ele ...

Encountering ECONNREFUSED error when making requests to an external API in a NextJS application integrated with Auth

Currently, I have integrated Auth0 authentication into my NextJS application by following their documentation. Now, I am in the process of calling an external ExpressJS application using the guidelines provided here: https://github.com/auth0/nextjs-auth0/b ...

Tips on moving information from one form to another after referencing the original page using Javascript and HTML

Imagine this scenario: A page with three text fields, each with default values. There is also a hyperlink that performs a database lookup and returns parameters to the same page where the hyperlink was clicked. The goal is for the text boxes to be automa ...

Troubleshooting problems with mapping over data in NextJS using react-query

I recently transitioned to using NextJS (version 13.4.12) and decided to give react-query a try for data fetching. Before adopting react-query, I had been using a custom useFetch hook that was functioning properly. To implement react-query as per recommen ...

Angular 10: A guide to dynamically highlighting navbar elements based on scrolling position

I am currently working on a single-page application using Angular 10. I have a simple page layout and I want to implement a feature that will highlight the navbar based on the scroll position. How can I achieve this functionality in a single-page applicati ...

Having trouble implementing the center edge effect in this CSS design

Looking for help with CSS to center the edges of a family tree design. Has anyone experience in working on styling family trees? *, *:before, *:after { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } .tree { ...