lik3yoo
lik3yoo

Reputation: 11

How to change the language without refreshing the page using next-intl client component

I want to change the language without refreshing the page by change cookie in next.js using next-intl without i18n routing, and in client component。this is my code https://github.com/lik3yoo/next-app/blob/main/src/app/login/page.tsx#L33

At the server component , can use unstable_setRequestLocale, but at client component, I didn't find a solution. Can you help me, Thanks

Upvotes: 0

Views: 1107

Answers (1)

Tyrell Curry
Tyrell Curry

Reputation: 381

Here is the approach for achieving this:

Create a config.ts file in the src folder. eg src/config.ts:

export type Locale = (typeof locales)[number];

export const locales = ['zh', 'en'] as const;
export const defaultLocale: Locale = 'zh';

Create a directory in src called services. Within that directory create locale.ts. eg. src/services/locale.ts:

'use server';

import { cookies } from 'next/headers';
import { Locale, defaultLocale } from '../config';

// In this example the locale is read from a cookie. You could alternatively
// also read it from a database, backend service, or any other source.
const COOKIE_NAME = 'NEXT_LOCALE';

export async function getUserLocale() {
  return cookies().get(COOKIE_NAME)?.value || defaultLocale;
}

export async function setUserLocale(locale: Locale) {
  cookies().set(COOKIE_NAME, locale);
}

Replace your i18n.ts file with this:

import { getRequestConfig } from "next-intl/server"
import { getUserLocale } from './services/locale';

export default getRequestConfig(async () => {

  const locale = await getUserLocale();

  return {
    locale,
    messages: (await import(`../messages/${locale}.json`)).default,
  }
})

Now, import these files in your login/page.tsx:

import { useTransition } from 'react';
import { setUserLocale } from "@/src/services/locale"
import { Locale } from "@/src/config"

Add this within your Login() component, I placed it right under the const t = useTranslations("loginPage"):

  const [isPending, startTransition] = useTransition();

Finally, update your changeLanguage function:

const changeLanguage = (value: "en" | "zh") => {
    console.log(value)
    // 修改浏览器cookie
    const locale = value as Locale;
    startTransition(() => {
      setUserLocale(locale);
    });
  }

I got this solution by exploring this next-intl demo.

Please let me know if you have any questions :).

Upvotes: 0

Related Questions