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

What causes the difference in inference for unspecified generics between a simple function call and a null-coalescing operator in TypeScript?

What causes the different types of a and b in the given code snippet? function empty<T>() { return [] as T[] } const defEmpty = empty() function test1(abc: number[]|null) { const a = abc ?? defEmpty const b = abc ?? empty() } Upon testing on t ...

What is the best way to compare two TypeScript object arrays for equality, especially when some objects may have multiple ways to be considered equivalent

Currently, I am in the process of developing a cost function for a game where players are given a set of resources in their hand. The resources can be categorized into different types such as Fire, Air, Water, Earth, Good, Evil, Law, Chaos, and Void. Thes ...

Where specifically in the code should I be looking for instances of undefined values?

One method in the codebase product$!: Observable<Product>; getProduct(): void { this.product$ = this.route.params .pipe( switchMap( params => { return this.productServ.getById(params['id']) })) } returns an ...

Implement a system that allows users to subscribe to different projects with customized stripe subscriptions

I am currently working on a common use case and I could use some suggestions on how to visualize it. In this scenario, each user can have multiple projects to which they can subscribe. For instance, let's say a User has two projects under their name: ...

elimination of nonexistent object

How can I prevent releasing data if two attributes are empty? const fork = [ { from: 'client', msg: null, for: null }, { from: 'client', msg: '2222222222222', for: null }, { from: 'server', msg: 'wqqqqqqqq ...

"Encountering a 500 error on Chrome and Internet Explorer while trying to sign

I am currently working on an ASP.NET Core application that handles identity management through Azure AD B2C using the ASP.Net Core OpenID Connect. The front end is developed using AngularJS 2 with TypeScript. In my Logout function, the user is redirected t ...

Using NextJs <Script> is only effective after a page has been reloaded

Currently delving into the world of NextJS and encountering an issue with integrating a third-party ebay script onto one of my route pages. The script only seems to appear sporadically upon reloading the page. However, when navigating to the store page via ...

Integrating Javascript and JQuery in Reactjs: A Comprehensive Guide

Currently, I am working with ReactJS and utilizing the Next.js framework. My goal is to implement the provided code snippet in index.js to display data (day, month, etc.). How should I go about achieving this? Here is the code snippet: <script> fun ...

Upgrade from Next.js version 12

Greetings to all! I have recently been assigned the task of migrating a project from next.js version 12 to the latest version. The changes in page routing and app routing are posing some challenges for me as I attempt to migrate the entire website. Is ther ...

Turn off the auto locale detection feature in next-intl for the initial visit

I've integrated next-intl into my Next.js app by following the steps outlined in their documentation here: import createMiddleware from 'next-intl/middleware'; export default createMiddleware({ // ... other config localeDetection: f ...

React throwing an error when trying to use inline fontWeight styling with Typescript

I am currently working on applying a CSS rule to a td element. const boldText = { fontWeight: 'bold' } <td style={boldText}>Content</td> Unfortunately, I am encountering the following error: [ts] Type '{ style: { fontWeig ...

Error encountered during Jasmine unit testing for the ng-redux @select directive

Here is a snippet from my component.ts file: import { Component, OnInit } from '@angular/core'; import { select } from 'ng2-redux'; import { Observable } from 'rxjs/Observable'; import { PersonalDetailsComponent } from ' ...

Passing information from the main component to a service through API connections

Currently, I am in the process of developing a website dedicated to showcasing the top 20 highest-rated Sci-fi movies. The main component on the homepage leverages a GET request via a service to fetch an array of objects containing the movie data. This mov ...

The delay function in RxJS allows for waiting to return a value until a specific condition is met within a stream and

Currently, I am facing an issue with a method in my application that triggers a server request. This method has access to a stream from the redux-store and needs to execute a callback only when the result of the request is found in the mentioned stream. Th ...

Formulate a multi-line string using a collection in React's JavaScript framework

I'm working on a React function that involves a set and I need to update an HTML element using the data from this set. Below is an example of my code: const updateElement = (mySet) => { document.getElementById('myId').innerHTML = Arra ...

Can you explain how the "reduce" function can be implemented using an interface in TypeScript?

Can you explain the "reduce" function using an interface in TypeScript? https://i.stack.imgur.com/X1VxL.png ...

Tips for injecting scripts into the head tag after an Angular component has been loaded

Currently, I am facing an issue with a script tag containing a Skype web control CDN. The script has been placed in the head section of my index.html file, but it is being called before the component that needs it has finished loading. Does anyone have a ...

Incorrect Angular Routing Component OpeningI am experiencing an issue where

I am facing an issue with lazy loading a module, where it is not correctly displaying the desired component. Even though the route seems correct, it shows a different component instead. Despite specifying the path for "Push-Campaign", it displays the "Cli ...

"When a class extends another class and utilizes properties within a static property, it essentially becomes

I have been encountering challenges with generics in TypeScript for quite some time now. My current setup is as follows: First, there is a generic class defined as: class Entity { public static schema = {}; } Then, there is a class that extends the ...

What is the best way to simulate an overloaded method in jest?

When working with the jsonwebtoken library to verify tokens in my module, I encountered a situation where the verify method is exported multiple times with different signatures. export function verify(token: string, secretOrPublicKey: Secret, options?: Ve ...