File tree 8 files changed +186
-0
lines changed
test/e2e/app-dir/not-found-with-pages-i18n
8 files changed +186
-0
lines changed Original file line number Diff line number Diff line change @@ -3294,6 +3294,16 @@ export default async function build(
3294
3294
orig ,
3295
3295
path . join ( distDir , 'server' , updatedRelativeDest )
3296
3296
)
3297
+
3298
+ // since the app router not found is prioritized over pages router,
3299
+ // we have to ensure the app router entries are available for all locales
3300
+ if ( i18n ) {
3301
+ for ( const locale of i18n . locales ) {
3302
+ const curPath = `/${ locale } /404`
3303
+ pagesManifest [ curPath ] = updatedRelativeDest
3304
+ }
3305
+ }
3306
+
3297
3307
pagesManifest [ '/404' ] = updatedRelativeDest
3298
3308
}
3299
3309
} )
Original file line number Diff line number Diff line change
1
+ import { notFound } from 'next/navigation'
2
+
3
+ export async function generateStaticParams ( ) {
4
+ return [ ]
5
+ }
6
+
7
+ async function validateSlug ( slug : string [ ] ) {
8
+ try {
9
+ const isValidPath =
10
+ slug . length === 1 && ( slug [ 0 ] === 'about' || slug [ 0 ] === 'contact' )
11
+
12
+ if ( ! isValidPath ) {
13
+ return false
14
+ }
15
+
16
+ return true
17
+ } catch ( error ) {
18
+ throw error
19
+ }
20
+ }
21
+
22
+ export default async function CatchAll ( {
23
+ params,
24
+ } : {
25
+ params : Promise < { slug : string [ ] } >
26
+ } ) {
27
+ const { slug } = await params
28
+ const slugArray = Array . isArray ( slug ) ? slug : [ slug ]
29
+
30
+ // Validate the slug
31
+ const isValid = await validateSlug ( slugArray )
32
+
33
+ // If not valid, show 404
34
+ if ( ! isValid ) {
35
+ notFound ( )
36
+ }
37
+
38
+ return (
39
+ < div >
40
+ < h1 > Catch All</ h1 >
41
+ < p > This is a catch all page added to the APP router</ p >
42
+ </ div >
43
+ )
44
+ }
Original file line number Diff line number Diff line change
1
+ export const metadata = {
2
+ title : 'Next.js' ,
3
+ description : 'Generated by Next.js' ,
4
+ }
5
+
6
+ export default function RootLayout ( {
7
+ children,
8
+ } : {
9
+ children : React . ReactNode
10
+ } ) {
11
+ return (
12
+ < html lang = "en" >
13
+ < body > { children } </ body >
14
+ </ html >
15
+ )
16
+ }
Original file line number Diff line number Diff line change
1
+ import React from 'react'
2
+
3
+ const NotFound = ( ) => (
4
+ < div >
5
+ < h1 > APP ROUTER - 404 PAGE</ h1 >
6
+ < p > This page is using the APP ROUTER</ p >
7
+ </ div >
8
+ )
9
+
10
+ export default NotFound
Original file line number Diff line number Diff line change
1
+ /**
2
+ * @type {import('next').NextConfig }
3
+ */
4
+ const nextConfig = {
5
+ i18n : {
6
+ locales : [ 'en-GB' , 'en' ] ,
7
+ defaultLocale : 'en' ,
8
+ localeDetection : false ,
9
+ } ,
10
+ }
11
+
12
+ module . exports = nextConfig
Original file line number Diff line number Diff line change
1
+ import { nextTestSetup } from 'e2e-utils'
2
+
3
+ describe ( 'not-found-with-pages' , ( ) => {
4
+ const { next, isNextStart } = nextTestSetup ( {
5
+ files : __dirname ,
6
+ } )
7
+
8
+ if ( isNextStart ) {
9
+ it ( 'should write all locales to the pages manifest' , async ( ) => {
10
+ const pagesManifest = JSON . parse (
11
+ await next . readFile ( '.next/server/pages-manifest.json' )
12
+ )
13
+
14
+ expect ( pagesManifest [ '/404' ] ) . toBe ( 'pages/404.html' )
15
+ expect ( pagesManifest [ '/en/404' ] ) . toBe ( 'pages/404.html' )
16
+ expect ( pagesManifest [ '/en-GB/404' ] ) . toBe ( 'pages/404.html' )
17
+ } )
18
+ }
19
+
20
+ it ( 'should prefer the app router 404 over the pages router 404 when both are present' , async ( ) => {
21
+ const browser = await next . browser ( '/app-dir/foo' )
22
+ expect ( await browser . elementByCss ( 'h1' ) . text ( ) ) . toBe (
23
+ 'APP ROUTER - 404 PAGE'
24
+ )
25
+
26
+ await browser . loadPage ( next . url )
27
+ expect ( await browser . elementByCss ( 'h1' ) . text ( ) ) . toBe (
28
+ 'APP ROUTER - 404 PAGE'
29
+ )
30
+ } )
31
+ } )
Original file line number Diff line number Diff line change
1
+ import React from 'react'
2
+ import { GetStaticProps } from 'next'
3
+
4
+ interface NotFoundProps {
5
+ message : string
6
+ }
7
+
8
+ const NotFound = ( { message } : NotFoundProps ) => (
9
+ < div >
10
+ < h1 > PAGES ROUTER - 404 PAGE</ h1 >
11
+ < p > This page is using the PAGES ROUTER</ p >
12
+ < p > { message } </ p >
13
+ </ div >
14
+ )
15
+
16
+ export const getStaticProps : GetStaticProps < NotFoundProps > = async ( ) => {
17
+ return {
18
+ props : {
19
+ message : 'Custom message fetched at build time' ,
20
+ } ,
21
+ }
22
+ }
23
+
24
+ export default NotFound
Original file line number Diff line number Diff line change
1
+ import React from 'react'
2
+
3
+ export const getStaticProps = ( { params } : { params : { slug : string [ ] } } ) => {
4
+ try {
5
+ const slugArray = Array . isArray ( params . slug ) ? params . slug : [ params . slug ]
6
+
7
+ const isValidPath =
8
+ slugArray . length === 1 &&
9
+ ( slugArray [ 0 ] === 'about' || slugArray [ 0 ] === 'contact' )
10
+
11
+ if ( ! isValidPath ) {
12
+ return {
13
+ notFound : true ,
14
+ }
15
+ }
16
+
17
+ return {
18
+ props : {
19
+ slug : params . slug ,
20
+ } ,
21
+ }
22
+ } catch ( error ) {
23
+ throw error
24
+ }
25
+ }
26
+
27
+ export const getStaticPaths = async ( ) => ( {
28
+ paths : [ ] ,
29
+ fallback : 'blocking' ,
30
+ } )
31
+
32
+ const CatchAll = ( ) => (
33
+ < div >
34
+ < h1 > Catch All</ h1 >
35
+ < p > This is a catch all page added to the pages router</ p >
36
+ </ div >
37
+ )
38
+
39
+ export default CatchAll
You can’t perform that action at this time.
0 commit comments