Skip to content

Commit 8912a29

Browse files
committed
fix 404 export
1 parent a89725b commit 8912a29

File tree

2 files changed

+35
-2
lines changed

2 files changed

+35
-2
lines changed

packages/next/src/export/index.ts

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -783,7 +783,39 @@ async function exportAppImpl(
783783
Object.keys(prerenderManifest.routes).map(async (unnormalizedRoute) => {
784784
// Special handling: map app /_not-found to 404.html (and 404/index.html when trailingSlash)
785785
if (unnormalizedRoute === '/_not-found') {
786-
return
786+
const { srcRoute } = prerenderManifest!.routes[unnormalizedRoute]
787+
const appPageName = mapAppRouteToPage.get(srcRoute || '')
788+
const pageName = appPageName || srcRoute || unnormalizedRoute
789+
const isAppPath = Boolean(appPageName)
790+
const route = normalizePagePath(unnormalizedRoute)
791+
792+
const pagePath = getPagePath(pageName, distDir, undefined, isAppPath)
793+
const distPagesDir = join(
794+
pagePath,
795+
pageName
796+
.slice(1)
797+
.split('/')
798+
.map(() => '..')
799+
.join('/')
800+
)
801+
802+
const orig = join(distPagesDir, route)
803+
const htmlSrc = `${orig}.html`
804+
805+
// write 404.html at root
806+
const htmlDest404 = join(outDir, '404.html')
807+
await fs.mkdir(dirname(htmlDest404), { recursive: true })
808+
await fs.copyFile(htmlSrc, htmlDest404)
809+
810+
// When trailingSlash, also write 404/index.html
811+
if (subFolders) {
812+
const htmlDest404Index = join(outDir, '404', 'index.html')
813+
await fs.mkdir(dirname(htmlDest404Index), { recursive: true })
814+
await fs.copyFile(htmlSrc, htmlDest404Index)
815+
}
816+
if (!options.buildExport) {
817+
await fs.rm(htmlSrc)
818+
}
787819
}
788820
// Skip 500.html in static export
789821
if (unnormalizedRoute === '/_global-error') {

test/e2e/app-dir/actions-unrecognized/actions-unrecognized.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,8 @@ describe('unrecognized server actions', () => {
159159
// FIXME: Currently, an unrecognized id in an MPA action results in a 500.
160160
// This is not ideal, and ignores all nested `error.js` files, only showing the topmost one.
161161
expect(response.status()).toBe(500)
162-
expect(response.headers()['content-type']).toStartWith('text/html')
162+
expect(response.headers()['content-type']).toStartWith('text/plain')
163+
expect(await response.text()).toBe('Internal Server Error')
163164
// In dev, the 500 page doesn't have any SSR'd html, so it won't show anything without JS.
164165
if (!isNextDev) {
165166
expect(await browser.elementByCss('body').text()).toContain(

0 commit comments

Comments
 (0)