correct usage of getServerSideProps with Typescript in a next.js project using i18n

I'm encountering challenges with integrating next-i18next into a Typescript NextJS project. There are very few recent examples available for reference. I have successfully set up internationalized routing, but I am facing difficulties in configuring i18next due to issues with the getServerSideProps syntax.

My knowledge of Typescript is limited, and I am not yet familiar with type declarations.

The code snippet provided below resembles the example from next-i18next documentation :

### index.tsx

// rest of index.tsx...

export const getServerSideProps: GetServerSideProps = async ({locale}) => ({
  props: {
    ...await serverSideTranslations(locale, ['common', 'header']),
  },
})

export default Home

An error regarding "locale" is being flagged in my IDE. Despite using getServerSideProps, I am uncertain if this is the most suitable solution for a predominantly static project. However, it appears unavoidable if I intend to implement SSR later on. An effective method for delivering accurately translated content while maintaining consistent URL locale would be greatly appreciated.

Answer №1

The issue with the typing error related to locale is valid because it may be empty if i18n setup is not done properly. You can find a detailed discussion on this topic here: https://example.com/discussion

There are various approaches to address this issue.

  1. Convert the locale to a string data type
export const fetchServerData: FetchServerData = async ({ selectedLocale }) => ({
  props: {
    ...await serverSideTranslations(selectedLocale as string, ['common', 'header']),
  },
})
  1. Create your own custom FetchServerData type where selectedLocale is mandatory and utilize that instead.
type CustomFetchServerData<
  M extends { [key: string]: any } = { [key: string]: any },
  N extends ParsedUrlQuery = ParsedUrlQuery
> = (context: FetchServerDataContext<N>) => Promise<FetchServerDataResult<M>>

type FetchServerDataContext<N extends ParsedUrlQuery = ParsedUrlQuery> = {
  req: IncomingMessage & {
    cookies: NextApiRequestCookies
  }
  res: ServerResponse
  params?: N
  query: ParsedUrlQuery
  preview?: boolean
  previewData?: PreviewData
  resolvedUrl: string
  selectedLocale: string // This is the crucial part.
  locales?: string[]
  defaultLocale?: string
}

export const fetchServerData: CustomFetchServerData = async ({ selectedLocale }) => ({
  props: {
    ...await serverSideTranslations(selectedLocale, ['common', 'header']),
  },
})

I personally prefer the second option as it eliminates the need for repeatedly casting the same variable, which is already in string format.

Answer №2

import { useTranslation } from 'next-i18next'
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
.....
//consider using cxt or context (or locale) variables
export const getServerSideProps: GetServerSideProps = async (ctx) => ({
      props: {
        ...await serverSideTranslations(ctx.locale, ['common', 'header']),
      },
    })
    
export default Home

If this code snippet doesn't produce the desired outcome, feel free to inform me so we can explore other options together.

Answer №3

When passing data as a prop in Next.js, you can define its shape using an interface or a type. This can be done by creating a generic and passing it to GetServerSideProps, as demonstrated below.

export interface User {
  id: string
  firstName: string
  lastname: string
  token: string
}

interface PageProps {
  hydrationData: {
    authStore: {
      user: User
    }
  }
}

export const getServerSideProps: GetServerSideProps<PageProps> =
  async function getServerSideProps(ctx) {

    return {
      props: {
        hydrationData: {
          authStore: {
            user: {
              id: '001',
              firstName: 'John',
              lastname: 'Doe',
              token: 'uuid',
            },
          },
        },
      },
    }
  }

This approach will ensure that your typescript compiler is satisfied with the data passed as props!

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

Using the combination of Stripe and CommerceJS for Bancontact payments

Currently, I am in the process of developing an e-commerce website using nextJS, commerceJS, and Stripe. I have successfully implemented card payments on the site, but now I want to add the bancontact payment method. Unfortunately, I haven't been able ...

Detecting Typescript linting issues in VSCode using Yarn version 3.2.3

Every time I try to set up a new react or next app using the latest yarn v3.2.3, my VS Code keeps showing linting errors as seen in the screenshot below. The main error it displays is ts(2307), which says Cannot find module 'next' or its correspo ...

Currently, I am developing a project in Next.js and looking to integrate the Cropper feature from the 'react-easy-crop' library. However, I am encountering some difficulties along the way

When creating a form input to select a file, the user can press import and a model will open with a cropper tool. After selecting the desired position and cropping the image, sometimes it displays as white or black depending on the selected picture. Result ...

What could be the reason for the appearance of Next.js compile indicator in my final production build?

Upon completing the development and deployment of a Next.js website, I observed that the black compile indicator continued to appear in the bottom-right corner of my browser, similar to its presence during local development. The indicator can be viewed he ...

ngx-slick-carousel: a carousel that loops infinitely and adjusts responsively

I have implemented ngx-slick-carousel to showcase YouTube videos in my project. However, I am facing two main issues. Firstly, the carousel is not infinite, and when the last video is reached, there appears to be white spaces before it loops back to the fi ...

Check out the selected values in Ionic 3

I am trying to retrieve all the checked values from a checkbox list in an Ionic3 app when clicked. Below is the code snippet: <ion-content padding> <ion-list> <ion-item *ngFor="let item of items; let i= index"> <ion-label>{{i ...

Gaining entry to the REDUX state from a Higher Order Component

As a newcomer to the world of coding and React, I've hit a roadblock that I could use some help with. My goal is to create components that can be favorited and then displayed on a separate page. To achieve this, I am utilizing Redux to manage the st ...

The validator function in FormArray is missing and causing a TypeError

I seem to be encountering an error specifically when the control is placed within a formArray. The issue arises with a mat-select element used for selecting days of the week, leading to the following error message: What might I be doing incorrectly to tri ...

What is the best way to retrieve the data from a specific section when a checkbox is selected in Angular 2?

When I select a checkbox for any section and then click the submit button, I want to display the details of that section in the console. Can someone assist me with this? **Stackblitz link:** : https://stackblitz.com/edit/angular-q7y8k1?file=src%2Fapp%2Fa ...

retrieving a single object from $resource by passing a non-ID parameter

I am utilizing $resource to retrieve an array of objects. The method I am invoking is as follows: fetchTeamResource(): ng.resource.IResourceClass<ITeamResource> { return this.$resource("/api/Teams:teamId"); } Below is how I am i ...

Exploring the world of tabbed dynamic routing in Angular 2 version 4

Today I encountered a routing issue that requires assistance from all of you. Currently, I have a sidebar with dynamic tree view navigations on the left and 4 tabs on the right. By default, tab1 is selected to display data related to the active link. Lin ...

Tapping on the hyperlink results in a 404 error when utilizing the next version 14.1

Inside the page app/page.tsx import Link from "next/link"; export default function Home() { return ( <main> <Link href="/hello">Hello</Link> </main> ); } The contents of file ...

Chart.js Axis Labels Orientation Guidelines

I am currently utilizing chart.js within an Angular 8 environment using Primeng. I am looking to customize the options for my chart as follows: For the y-axis ticks, set textDirection to 'ltr' For the x-axis ticks, set textDirection to 'rtl ...

The 'payload' property is not found within the 'Actions' type

I recently started using TypeScript and Visual Studio Code. I encountered the following issue: *[ts] Property 'payload' does not exist on type 'Actions'. This is my code: action.ts file: import { Action } from '@ngrx/store&apos ...

Showing data related to a certain value - what's the best way?

I am currently working on a page where I need to display and edit specific user information at /users/524.json. However, I also want to include the working days from another table on the same page. I have provided most of the code below for reference. Unfo ...

Creating a countdown clock in Angular 5

I am currently working with Angular 5. Is there a way to initiate a timer as soon as the 'play' button is clicked, in order to track the elapsed time since the click? Additionally, I am interested in learning if it's feasible to pause the ...

Adding a background video to my NextJS project resulted in an error being thrown

Struggling to include a background video in mp4 format with NextJS and encountering an error: ./public/video/ocean.mp4 1:0 Module parse failed: Unexpected character '' (1:0) You may need an appropriate loader to handle this file type, currently ...

What is the syntax for assigning a public variable within a TypeScript function?

I am finding it challenging to assign a value to a public variable within another function. I seem to be stuck. export class MyClass{ myVar = false; myFunction(){ Module.anotherFunction(){ this.myVar = true; } } } ...

I'm puzzled as to why I am unable to invoke a class method within this callback function. The error message indicates a TypeError: 'this' is undefined

Currently, I am troubleshooting a challenge in my Angular application that involve TypeScript. The issue lies within a method in a TypeScript class: findArtistBidsAppliedByCurrentWall(bid):Observable<Bid[]> { console.log("findArtistBidsApplied ...

Leveraging the power of useSWR for seamless backend integration with pagination

Whenever the page changes, a new query is generated and its data is set to initialData. Consequently, the user will be able to see the initialData before the new query data is fetched: import React from "react"; import fetch from "../lib/fe ...