Change the locale on the current path with a query in Next.js by utilizing the router

Managing locale changes centrally can be tricky. When a user selects a new locale from a list, I use useRouter to redirect them to the current page in the selected locale like this:

var router = useRouter();

const changeLocale = (selectedLocale) => {
    router.push({
            pathname: router.pathname,
            query: router.query
        }, { locale });
}

<div onClick={() => changeLocale('fr')}>Fr</div>

This method works smoothly for URLs without parameters. However, when dealing with URLs containing parameters, things get a bit more complicated. For instance, when a user clicks on a conference that leads to a specific conference page using a Link:

<Link
    href={{
        pathname: '/conference/[id]',
        query: { id: conf.id }
    }}

For example, clicking on a conference may lead the user to example.com/conference/5. But changing the locale on that page results in a duplicated URL like example.com/conference/5?id=5. This duplication of parameters can cause issues. Omitting the query parameter in router.push triggers an error message:

Error: The provided href (/conference/[id]) value is missing query values (id) to be interpolated properly. Read more: https://nextjs.org/docs/messages/href-interpolation-failed

Is there a more effective way to handle rerouting while preserving the URL structure and parameters?

Answer №1

This solution worked perfectly for me:

    const updateLocale = (newLocale) => {
        router.navigate({
            route: router.currentRoute,
            parameters: router.params
        }, router.path, { locale: newLocale });
    }

Essentially, the only modification I made was to the second argument of the router.navigate function.

I found this technique in the documentation:

If you want to change just the locale while keeping all other routing details intact, such as dynamic route queries or hidden href query values, you can pass an object for the href parameter:

import { useRouter } from 'next/router'
const router = useRouter()
const { currentPath, fullPath, queryParams } = router
// Update only the locale and retain all other route specifics including href's query
router.navigate({ path: currentPath, queryParams }, fullPath, { locale: updatedLocale })

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

Having trouble with PHP Storm and Vue component not working? Or encountering issues with unresolved function or method in your

I have been struggling with this issue for days and cannot seem to find a solution online. Being new to Vue.js, I am currently working on a TDD Laravel project: My goal is to add the standard Vue example-component to my app.blade.php as follows: app.bla ...

Implementing the row delete function in MUI DataGrid using JavaScript

My grid has a delete icon button in each row, but it's not deleting the row. Can someone please help me with this issue? I'm working on a todo app where each row should have its own delete button. I'm struggling to connect the deleteTodo co ...

Firebase: Saving data to a nonexistent object

I am currently facing a challenge in saving the result of a serviceId to a services object within a parent entity named provider1, especially since the services object has not been initialized yet. The structure of my Firebase data is as follows: "provid ...

How can I efficiently utilize HTML/CSS/JS to float items and create a grid that accommodates expandable items while minimizing wasted space?

After meticulously configuring a basic grid of divs using float, I've encountered an issue. When expanding an item in the right-hand column, the layout shifts awkwardly. My goal is to have boxes A and B seamlessly move up to fill the empty space, whi ...

Ways to conceal or deactivate button controls on videojs?

I am building an application using video.js and Vue. I am looking for a way to hide or disable certain controls like the play button, playback rate, and make the progress bar read-only. In the video.js documentation, I found that using controls: false hi ...

Looking to conceal the edges of a ThreeJS box primitive

I'm trying to figure out how to hide the edges displayed in a box primitive using ThreeJS. The edges only appear when I apply a texture to the faces. I've attempted various options such as setting wireframe=false, but the edges persist. Here&ap ...

Whenever I repeatedly click the button, the array will store a new value. My goal is for it to collect and store all values obtained from the function

After retrieving data from the listAPI value using an API, the output is displayed as follows: //output - console.log(listAPI) 5) [{…}, {…}, {…}, {…}, {…}] 0: {id: "1", name: "name 1", active: "true"} 1: {id: " ...

Displaying the most recent queries retrieved from a search API

Our web application built on angular.js utilizes a REST search API to query users within the system. The endpoint for searching users is: search/user?q='abc' Upon revisiting the web application, we aim to display the user's recent search ...

Transferring data from AJAX form in JavaScript to PHP function

My website features a login form that sends data, such as email address, to a PHP function and initiates the creation of a user. I am looking to include additional information on the page where the form is located. Here is the data I want to include in t ...

Having trouble identifying whether a file is a picture or video based solely on its extension

My current challenge involves determining whether an uploaded file is a video or a photo. This distinction is crucial as it dictates whether the file should be sent to my telegram bot as a video or photo attachment. Despite having what seems like a logica ...

The jQuery toggle function seems to be skipping alternate items

I have recently started learning Javascript and JQuery. Currently, I am working on creating a comment system where you can click reply to display the form. However, I'm facing an issue where the form only shows up for the first comment reply, not for ...

Create intricate text on the canvas by individually rendering each pixel

In my canvas project, I am using "fillText" to display a string such as "stackoverflow". After that, I extract the image data from the canvas to identify each pixel of the text. My goal is to capture the x position, y position, and color of each pixel. Th ...

Having trouble with the Ajax load function not functioning in your HTML code?

The issue has been resolved. Thank you to everyone who helped! Initially, I was attempting to run a file offline instead of on a web server (XAMPP server). Once I uploaded the file to the web server, it started working properly. I had been trying to load ...

Generate a new web component using JavaScript

My HTML table looks like this: <table id = "rpttable" name = "rpttable"> <thead> Column Headers here... </thead> <tbody id = "rptbody" name = "rptbody"> data here <3 .... </tbody> </table> And in my ...

Displaying altered textContent

I am working with an SVG stored as a string and making some adjustments to it. The final result is being displayed as text within targetDiv. <html lang="en"> <head> <title>Output Modified</title> </head> <body> ...

A pop-up window displaying an electron error message appears, but no errors are logged in the console

In a Nutshell: While developing a single-page website with Electron, I encountered the common issue of jQuery not being globally accessible. To tackle this problem, I decided to simplify it by using a quick start example, but unfortunately, I'm strugg ...

Strange occurrences observed on array mapping post-state alteration

Greetings to all during these challenging times! Currently, I am delving into Firebase and ReactJS and have encountered a peculiar issue involving state updates in React and the array map functionality in JavaScript. Below is the code snippet showcasing my ...

Angular binding causing decimal inaccuracies

Within my $scope, I have a variable tobing that can be either 2.00 or 2.20, and I am binding it to: <span>{{datasource.tobind}}</span> I want the displayed text to always show "2.00" or "2.20" with the two last digits, but Angular seems to au ...

Tips for determining if an array of objects, into which I am adding objects, contains a particular key value present in a different array of objects

I've been working on this and here is what I have tried so far: groceryList = []; ngOnInit() { this._recipesSub = this.recipesService.recipes.subscribe((receivedData) => { this.loadedRecipes = receivedData.recipes; }); } onCheckRecipe(e) { ...

What is the most effective way to retrieve both grouped data and all data from mongodb?

I have successfully retrieved totalAccount and totalBalance using the code snippet above. However, I am facing an issue where no other field or data besides those two are showing up. How can I modify this code to also fetch all the data from my collectio ...