next.js: Public files not accessible on i18n domains

Verify canary release

  • I verified that the issue exists in the latest Next.js canary release

Provide environment information

Operating System:
      Platform: darwin
      Arch: arm64
      Version: Darwin Kernel Version 22.6.0: Wed Jul  5 22:22:05 PDT 2023; root:xnu-8796.141.3~6/RELEASE_ARM64_T6000
    Binaries:
      Node: 20.2.0
      npm: 9.6.4
      Yarn: 1.22.19
      pnpm: 8.7.0
    Relevant Packages:
      next: 13.4.20-canary.12
      eslint-config-next: 13.4.19
      react: 18.2.0
      react-dom: 18.2.0
      typescript: 5.2.2
    Next.js Config:
      output: N/A

Which area(s) of Next.js are affected? (leave empty if unsure)

Internationalization (i18n), Routing (next/router, next/navigation, next/link)

Link to the code that reproduces this issue or a replay of the bug

https://app.replay.io/recording/reproduction--e17b7c87-6019-40b2-b719-1e9b9ce80b13

To Reproduce

  • Create new next app
  • Add robots.txt in public folder
  • Setup basic i18n (see example below)
  • Make sure you are on different domains (as example)
  • Go to default domain /robots.txt
  • See the robots.txt output
  • Go to different domain /robots.txt
  • See 404
  i18n: {
    defaultLocale: "en",
    locales: ["en", "nl-NL"],
    domains: [
      {
        domain: "com.rob.ticketswap.pizza",
        defaultLocale: "en",
        http: false,
      },
      {
        domain: "nl.rob.ticketswap.pizza",
        defaultLocale: "nl-NL",
        http: false,
      },
    ],
    localeDetection: false,
  },

Describe the Bug

This bug presented itself specifically in Next v13.

Public files are no longer accessible on all domains that are not the default domain (default locale domain).

Expected Behavior

All files in public folder should be accessible on every domain that is setup in the i18n config.

Which browser are you using? (if relevant)

No response

How are you deploying your application? (if relevant)

No response

About this issue

  • Original URL
  • State: closed
  • Created 10 months ago
  • Reactions: 11
  • Comments: 32 (8 by maintainers)

Commits related to this issue

Most upvoted comments

Having the same issue with the latest versions of next (13.5.4, 13.5.5 and 13.5.6)

I managed to fix this for now by patching the next package with the solution of this PR

diff --git a/node_modules/next/dist/server/lib/router-utils/filesystem.js b/node_modules/next/dist/server/lib/router-utils/filesystem.js
index 635fcdc..f56164e 100644
--- a/node_modules/next/dist/server/lib/router-utils/filesystem.js
+++ b/node_modules/next/dist/server/lib/router-utils/filesystem.js
@@ -348,7 +348,7 @@ async function setupFsCheck(opts) {
                 let locale;
                 let curItemPath = itemPath;
                 let curDecodedItemPath = decodedItemPath;
-                const isDynamicOutput = type === "pageFile" || type === "appFile";
+                const isDynamicOutput = type === 'pageFile' || type === 'appFile' || type === 'publicFolder'
                 if (i18n) {
                     const localeResult = handleLocale(itemPath, // legacy behavior allows visiting static assets under
                     // default locale but no other locale

I have the same issue in NextJS up to latest version 14.0.1, in dev mode this is not so important, but for production builds via docker I wrote this fix in the Dockerfile. It involves copying the public directory into a locale subdirectory Original Dockerfile https://github.com/vercel/next.js/blob/canary/examples/with-docker/Dockerfile

...
COPY --from=builder /app/public ./public
COPY --from=builder /app/public ./public/{locale} # <-- added this line
...

@kamesdev You can also use patch-package

I don’t want to jump to conclusions, but it seems to me that next@13.4.12 is the last version where this issue isn’t present.

@persocon

Such aggressive and disrespectful language is not constructive and doesn’t help at all. Get it together dude.

@kamesdev - we also use the fix with v13.5.6 and it works really great.

We added this line in our Dockerfile to “patch” nextjs: RUN sed -i 's/const isDynamicOutput.*/const isDynamicOutput = type === "pageFile" || type === "appFile" || type === "publicFolder";/g' /frontend/node_modules/next/dist/server/lib/router-utils/filesystem.js

@arielvieira - thank you very much for this workaround!!

Nice, i will tryout on our next release, this might work.

@kamesdev If you don’t use docker i assume you still have a release process for a versel/heroku something and that reference to a script within your application right? Generaly its associated to your package.json scripts

just make sure to add a pre-install/pre-build step where you do sed -i 's/const isDynamicOutput.*/const isDynamicOutput = type === "pageFile" || type === "appFile" || type === "publicFolder";/g' /frontend/node_modules/next/dist/server/lib/router-utils/filesystem.js

https://vercel.com/docs/deployments/configure-a-build