Thanh-Quy Nguyen
Thanh-Quy Nguyen

Reputation: 3275

NextJS special characters routes do not work from browser

Using NextJS, I am defining some routes in getStaticPaths by making an API call:

/**
 * @dev Fetches the article route and exports the title and id to define the available routes
 */
const getAllArticles = async () => {
    const result = await fetch("https://some_api_url");
    const articles = await result.json();

    return articles.results.map((article) => {
        const articleTitle = `${article.title}`;

        return {
            params: {
                title: articleName,
                id: `${article.id}`,
            },
        };
    });
};

/**
 * @dev Defines the paths available to reach directly
 */
export async function getStaticPaths() {
    const paths = await getAllArticles();
    return {
        paths,
        fallback: false,
    };
}

Everything works most of the time: I can access most of the articles, Router.push works with all URLs defined.

However, when the article name includes a special character such as &, Router.push keeps working, but copy/pasting the URL that worked from inside the app to another tab returns a page:

An unexpected error has occurred.

In the Network tab of the inspector, a 404 get request error (in Network) appears.

The component code is mostly made of API calls such as:

await API.put(`/set_article/${article.id}`, { object });

With API being defined by axios.

Any idea why it happens and how to make the getStaticPaths work with special characters?

Upvotes: 3

Views: 13694

Answers (1)

Tomalak
Tomalak

Reputation: 338416

When you transport values in URLs, they need to be URL-encoded. (When you transport values in HTML, they need to be HTML encoded. In JSON, they need to be JSON-encoded. And so on. Any text-based system that can transport structured data has an encoding scheme that you need to apply to data. URLs are not an exception.)

Turn your raw values in your client code

await API.put(`/set_article/${article.id}`)

into encoded ones

await API.put(`/set_article/${encodeURIComponent(article.id)}`)

It might be tempting, but don't pre-encode the values on the server-side. Do this on the client end, at the time you actually use them in a URL.

Upvotes: 6

Related Questions