diff --git a/errors/failed-to-fetch-devpagesmanifest.md b/errors/failed-to-fetch-devpagesmanifest.md new file mode 100644 index 000000000000..3a19a0879e71 --- /dev/null +++ b/errors/failed-to-fetch-devpagesmanifest.md @@ -0,0 +1,18 @@ +# Failed to fetch devPagesManifest + +#### Why This Error Occurred + +The network request to load `_devPagesManifest.json` did not succeed. + +The dev pages manifest file is used by `next/link` to retrieve the list of pages to be (pre-)loaded by Next.js. +If it fails, Next.js cannot properly navigate and link between pages. + +#### Possible Ways to Fix It + +- Make sure your browser developer tools, extensions, and any other network tools aren't blocking that request. +- If you're running your Next.js application through a proxy, nginx, or other network layer, make sure links like `/_next/*` are configured to be allowed. + +### Useful Links + +- [Original GitHub Issue Thread](https://github.com/vercel/next.js/issues/16874) +- [GitHub Issue Thread With Reproduction](https://github.com/vercel/next.js/issues/38047) diff --git a/errors/manifest.json b/errors/manifest.json index 9bc09eebbd1b..199d52a52bac 100644 --- a/errors/manifest.json +++ b/errors/manifest.json @@ -715,6 +715,10 @@ { "title": "invalid-next-config", "path": "/errors/invalid-next-config.md" + }, + { + "title": "failed-to-fetch-devpagesmanifest", + "path": "/errors/failed-to-fetch-devpagesmanifest.md" } ] } diff --git a/packages/next/client/page-loader.ts b/packages/next/client/page-loader.ts index 22e6963c4588..5599b3106de4 100644 --- a/packages/next/client/page-loader.ts +++ b/packages/next/client/page-loader.ts @@ -58,23 +58,22 @@ export default class PageLoader { if (window.__DEV_PAGES_MANIFEST) { return window.__DEV_PAGES_MANIFEST.pages } else { - if (!this.promisedDevPagesManifest) { - // TODO: Decide what should happen when fetching fails instead of asserting - // @ts-ignore - this.promisedDevPagesManifest = fetch( - `${this.assetPrefix}/_next/static/development/_devPagesManifest.json` - ) - .then((res) => res.json()) - .then((manifest: { pages: string[] }) => { - window.__DEV_PAGES_MANIFEST = manifest - return manifest.pages - }) - .catch((err) => { - console.log(`Failed to fetch devPagesManifest`, err) - }) - } - // TODO Remove this assertion as this could be undefined - return this.promisedDevPagesManifest! + this.promisedDevPagesManifest ||= fetch( + `${this.assetPrefix}/_next/static/development/_devPagesManifest.json` + ) + .then((res) => res.json()) + .then((manifest: { pages: string[] }) => { + window.__DEV_PAGES_MANIFEST = manifest + return manifest.pages + }) + .catch((err) => { + console.log(`Failed to fetch devPagesManifest:`, err) + throw new Error( + `Failed to fetch _devPagesManifest.json. Is something blocking that network request?\n` + + 'Read more: https://nextjs.org/docs/messages/failed-to-fetch-devpagesmanifest' + ) + }) + return this.promisedDevPagesManifest } } }