hozana/next-translate-routes

404 req when deployed on Vercel

Opened this issue · 8 comments

hi,

I am using Next JS 13.4.7 with old Pages directory for routing. Also using next-translate-routes for URL translation which works great locally. But when I upload to vercel and I am visiting pages I see 404 in console and in network tab.

The pages are still getting all data and showing correctly, just that when next is fetching data from cache it fetches 2 times:

  1. /_next/data/ZAjS6fXQOKhw0BLn1dIOk/lt/contacts.json
  2. /_next/data/ZAjS6fXQOKhw0BLn1dIOk/lt/kontaktai.json

This is the same page only the first time it fetches with the same route name as it is declared in pages folder - "contacts" it gets status OK 304.
And the second time it fetches looking for the translated version - "kontaktai.json" and it gets status 404.

Locally I noticed that next is also fetching both of them "contacts.json" and "kontaktai.json" and both times it gets status code OK 304.
But why is it not working when deployed? Any ideas?

We have noticed a similar issue, or likely the same issue.

For us it can be reproduced in any production build.

With some static pages, client side navigation will result in a failed HEAD request (404) in a similar manner as stated in the issue description. It seems that the issue takes places on static pages that use next-translate-routes for translating pathnames (with some further details at the end of the message).

(GET) /_next/data/[hash]/[locale]/file-path-name.json ✅
(HEAD) /_next/data/[hash]/[locale]/translated-name.json ❌
(GET) /_next/data/[hash]/fr/coffee-shops.json ✅
(HEAD) /_next/data/[hash]/fr/cafes.json ❌

I'm not fully certain where the HEAD request is fired from or why, but I suspect that it has to do with Nextjs' router trying to sniff some details about the page we are navigating into.

We are using next version 13.2.4. The HEAD request is probably configured in this function:
https://github.com/vercel/next.js/blob/05f6de10869021dbb6124e174778e2108c9b4e8e/packages/next/src/shared/lib/router/router.ts#L497

Here's an example from our .next/server/pages for the coffee shops page. The language used for folder and file names under pages is en, but fr is used as the default and only locale.

// .next/server/pages

pages/
├─ fr/
│  ├─ coffee_shops.json
│  ├─ coffee_shops.html
│  ├─ coffee_shops/
│  │  ├─ cafe-armand.json
│  │  ├─ cafe-armand.html
├─ coffee_shops/
│  ├─ [slug].json
├─ coffee_shops.json

If I configure the application to support en, I do not get HEAD 404 errors when that locale is selected (likely because it matches with the file langauge inside pages.

Curiously while

(HEAD) /_next/data/[hash]/fr/cafes.json ❌

fails, the following example does not fail:

(HEAD) /_next/data/[hash]/fr/cafes/cafe-armand.json?slug=cafe-armand ✅

@Viktor-as @Jokinen I'm facing the same issue as you're describing when deploying to Vercel. By any chance, did you guys manage to solve this?

@Viktor-as @Jokinen I'm facing the same issue as you're describing when deploying to Vercel. By any chance, did you guys manage to solve this?

Hey @NSpehler , well I found some workaround for this. In src/pages/_app.tsx I have this code:

const App = ({ Component, pageProps }: AppProps) => {
  if (typeof window === 'object') {
    const { fetch: originalFetch } = window;
    const nextDataRequestRegex =
      /\/_next\/data\/[^/]+\/[^/]+\/([^/]+)(?!\.json)\/?/;
    window.fetch = async (...args) => {
      const [url] = args;
      const match = url.toString().match(nextDataRequestRegex);
      if (match) {
        const word = match[1];
        const cleanedWord = word.replace(/\.json$/, '');
        if (excludeArray.includes(cleanedWord)) {
          return Promise.reject();
        }
      }
      return originalFetch(...args);
    };
  }

  return ( ...

this intercepts and prevents those unnecessary fetches.
Lets say Next tries to fetch this URL /_next/data/ZAjS6fXQOKhw0BLn1dIOk/lt/kontaktai.json
const word will be kontaktai.json
then const cleanedWord will be kontaktai
excludeArray is an array of my pages translations that I do not want to unnecessary fetch, like ['kontaktai', ...]

so when the fetch matches my words (page translations) in excludeArray the fetch is rejected

Would any of you test with next-translate-routes@1.11.0-0? I added something that may fix your problem...

@cvolant that version gives an error. I tried 0-2 and 0-3. App crashes on load.

Yes, I also saw that 1.11.0-0 crashes in some configs. That is why I tried with different solutions up to 1.11.0-3, but still no luck. I will tell you as soon as I get a working version. I hope I will find some time to work on this soon.

As commented in another issue, I released 1.11.0-5 to fix the issue. I hope it works now, but I had to drop the support old next versions (<13.5.0)...
As for this HEAD request, it is a Next issue, filed here. You can thumb up the issue.

The issue happens to me on 1.11.0-5 and next 14.2.3 on Vercel on server side generated pages when I navigate to them via next/router. Directly accessing it works fine. Also static pages work fine.