Files
Jiachi LiuandGitHub 5c3a298dc7 [not-found] Add global-not-found convention (#78783)
### Feature

Introducing a new convention `global-not-found.js`, which let you build your own 404 page within app router. This convention is similar to `global-error.js` but for not found in general case, it's similar to `not-found.js` but including the layout.

App router has an implicit convention of building the 404 route, which is composing the top-level root `layout.js` and the root `not-found.js` to build up a 404 page. Since it's so implicit so that users don't have much control over it, which also lead to some confusing errors like `/_not-found` route is build failed due to various reason.

The `global-not-found.js` convention is aimed to help users to build 404 route in App Router easily and convenience. Currently it will be bound with a flag `experimental.globalNotFound` and later it will become the stable feature in next major release as it introduces a minor breaking change that we won't use root layout and root not-found to compose the 404 page. Instead, we'll either choose the builtin 404 page or users customized `global-not-found.js` to generate the 404 page when you enable the feature.

#### Advantages

Good new that if you were having struggles with creating 404 page for the multi root layouts app, such as the case below. Then `global-not-found.js` is your choose.

```
- (2024)/
   /layout.js
   /... # routes
- (2025)/
   /layout.js
   /... # routes
```

Closes NDX-1036
Related #59180


#### Follow up

The metadata and deployment will be followed up in new PRs
2025-05-10 00:33:17 +02:00

25 lines
980 B
TypeScript

import { nextTestSetup } from 'e2e-utils'
// TODO(global-not-found): remove this test when the feature is stable
describe('global-not-found - not-present', () => {
const { next } = nextTestSetup({
files: __dirname,
})
it('should render default 404 when global-not-found is not defined but enabled', async () => {
const browser = await next.browser('/does-not-exist')
const bodyText = await browser.elementByCss('body').text()
expect(bodyText).toBe('404\nThis page could not be found.')
})
it('should render custom not-found.js boundary when global-not-found is not defined but enabled', async () => {
const browser = await next.browser('/call-not-found')
const bodyText = await browser.elementByCss('body').text()
const htmlLang = await browser.elementByCss('html').getAttribute('lang')
// Render the root layout
expect(htmlLang).toBe('en')
// Render the not-found.js boundary
expect(bodyText).toBe('not-found.js')
})
})