I'm working on a Next.js project where we have a language dropdown for users to select their preferred language. The current implementation uses the router.push method from next/router to update the language and redirect to the current page without reloading. However, this creates a new entry in the browser history.
Here's the relevant code:
import { useRouter } from 'next/router';
import setLanguage from 'next-translate/setLanguage';
export const LanguageDropdown = () => {
const { locales, locale } = useRouter();
const updateLanguage = async (language: string) => {
window.localStorage.setItem('language-selected', language.toLowerCase());
// Assuming setLanguage is a function that updates the language in your app
await setLanguage(language.toLowerCase());
};
return (
<select onChange={(e) => updateLanguage(e.target.value)} value={locale}>
{locales?.map((lang) => (
<option key={lang} value={lang}>
{lang.toUpperCase()}
</option>
))}
</select>
);
};
The problem is that when a user changes the language, a new entry is created in the history. If the user then navigates back, they land on the previously set language and are then redirected to the new language. I would like to prevent this behavior and not create a new history entry when the language is changed.
Any suggestions on how to achieve this would be greatly appreciated.
Based on the current setLanguage
function's implementation it doesn't appear this is possible as it uses router.push
to PUSH a new entry onto the history stack.
import Router from 'next/router' export default async function setLanguage( locale: string, scroll = true ): Promise<boolean> { return await Router.push( { pathname: Router.pathname, query: Router.query, }, Router.asPath, { locale, scroll } ) }
But this hook is simple enough you could create your own that allows for PUSH or REPLACE navigation actions.
Example:
import Router from 'next/router';
export default async function setLanguage(
locale: string,
{ scroll = true, replace = false } = { scroll: true, replace: false },
): Promise<boolean> {
return await Router[replace ? "replace" : "push"](
{
pathname: Router.pathname,
query: Router.query,
},
Router.asPath,
{ locale, scroll }
)
}
import { useRouter } from 'next/router';
import setLanguage from '../path/to/setLanguage';
export const LanguageDropdown = () => {
const { locales, locale } = useRouter();
const updateLanguage = async (language: string) => {
const selectedLanguage = language.toLowerCase();
window.localStorage.setItem('language-selected', selectedLanguage);
// Set language and redirect
await setLanguage(selectedLanguage, { replace: true });
};
return (
<select onChange={(e) => updateLanguage(e.target.value)} value={locale}>
{locales?.map((lang) => (
<option key={lang} value={lang}>
{lang.toUpperCase()}
</option>
))}
</select>
);
};