11import { existsSync } from 'node:fs'
2- import { cp } from 'node:fs/promises'
3- import { extname , join } from 'node:path/posix'
2+ import { cp , mkdir , readFile , writeFile } from 'node:fs/promises'
3+ import { dirname , extname , join } from 'node:path/posix'
44
55import { NEXT_RUNTIME_STATIC_ASSETS } from './constants.js'
66import type { FrameworksAPIConfig , OnBuildCompleteContext } from './types.js'
@@ -15,11 +15,26 @@ export async function onBuildComplete(
1515 try {
1616 let distPathname = staticFile . pathname
1717 if ( extname ( distPathname ) === '' && extname ( staticFile . filePath ) === '.html' ) {
18+ // if it's fully static page, we need to also create empty _next/data JSON file
19+ // on Vercel this is done in routing layer, but we can't express that routing right now on Netlify
20+ const buildID = await readFile ( join ( ctx . distDir , 'BUILD_ID' ) , 'utf-8' )
21+ const dataFilePath = join (
22+ NEXT_RUNTIME_STATIC_ASSETS ,
23+ '_next' ,
24+ 'data' ,
25+ buildID ,
26+ `${ distPathname === '/' ? 'index' : distPathname } .json` ,
27+ )
28+ await mkdir ( dirname ( dataFilePath ) , { recursive : true } )
29+ await writeFile ( dataFilePath , '{}' )
30+
1831 // FEEDBACK: should this be applied in Next.js before passing to context to adapters?
19- if ( ctx . config . trailingSlash && ! distPathname . endsWith ( '/' ) ) {
20- distPathname += '/'
21- } else if ( ! ctx . config . trailingSlash && distPathname . endsWith ( '/' ) ) {
22- distPathname = distPathname . slice ( 0 , - 1 )
32+ if ( distPathname !== '/' ) {
33+ if ( ctx . config . trailingSlash && ! distPathname . endsWith ( '/' ) ) {
34+ distPathname += '/'
35+ } else if ( ! ctx . config . trailingSlash && distPathname . endsWith ( '/' ) ) {
36+ distPathname = distPathname . slice ( 0 , - 1 )
37+ }
2338 }
2439
2540 // if pathname is extension-less, but source file has an .html extension, preserve it
0 commit comments