Skip to content

Commit d39a2a1

Browse files
committed
Bundle fallback data into SSR instead of reading repo-local files
The previous route fallback fix worked locally but still failed on production because the Netlify SSR runtime did not have repo-local JSON files available at the paths the helper searched. Switch the fallback helper to raw-import the generated app, game, device, and YouTube JSON inputs so the SSR bundle carries the data it needs at runtime, independent of function working directory or file packaging quirks. Constraint: Netlify SSR bundling does not reliably expose repo-local generated files as runtime-readable filesystem paths Rejected: Rely on Netlify included_files for SSR bundle data | the generated SSR function archive still omitted the fallback files Rejected: Fetch large fallback JSON over HTTP on each request | unnecessary network dependency for a server-side fallback path Confidence: medium Scope-risk: narrow Reversibility: clean Directive: Prefer bundler-native inclusion for SSR-only fallback data when runtime file availability is uncertain on Netlify Tested: vitest ./test/prebuild/config-node.test.js ./test/prebuild/site-listings.test.js; pnpm run netlify-build Not-tested: live production after redeploy
1 parent 6cfbfbf commit d39a2a1

1 file changed

Lines changed: 12 additions & 22 deletions

File tree

helpers/site-listings.js

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,33 @@
1-
import fs from 'fs-extra'
2-
import path from 'path'
3-
import { fileURLToPath } from 'url'
1+
import youtubeVideosText from '~/static/api/youtube-videos.json?raw'
2+
import appListText from '~/static/app-list.json?raw'
3+
import deviceListText from '~/static/device-list.json?raw'
4+
import gameListText from '~/static/game-list.json?raw'
45

56
import {
67
buildVideoListingFromFetchedVideo,
78
makeVideoSlug
89
} from '~/helpers/build-video-list.js'
9-
import { youtubeVideoPath } from '~/helpers/api/youtube/build.js'
10-
11-
const currentModuleDirectory = path.dirname( fileURLToPath( import.meta.url ) )
12-
const appListPath = path.join( currentModuleDirectory, '../static/app-list.json' )
13-
const gameListPath = path.join( currentModuleDirectory, '../static/game-list.json' )
14-
const deviceListPath = path.join( currentModuleDirectory, '../static/device-list.json' )
1510
const trailingCommaPattern = /,\s*([\]}])/g
16-
17-
function parseGeneratedJsonFile ( filePath ) {
18-
const fileContents = fs.readFileSync( filePath, 'utf8' )
19-
20-
return JSON.parse( fileContents.replace( trailingCommaPattern, '$1' ) )
21-
}
11+
const parsedDeviceList = JSON.parse( deviceListText.replace( trailingCommaPattern, '$1' ) )
12+
const parsedAppList = JSON.parse( appListText.replace( trailingCommaPattern, '$1' ) )
13+
const parsedGameList = JSON.parse( gameListText.replace( trailingCommaPattern, '$1' ) )
14+
const parsedYoutubeVideos = JSON.parse( youtubeVideosText )
2215

2316
export function getDeviceListingBySlug ( slug ) {
24-
const deviceList = parseGeneratedJsonFile( deviceListPath )
25-
26-
return deviceList.find( device => device.slug === slug ) || null
17+
return parsedDeviceList.find( device => device.slug === slug ) || null
2718
}
2819

2920
function getAllVideoAppsList () {
3021
return [
31-
...parseGeneratedJsonFile( appListPath ),
32-
...parseGeneratedJsonFile( gameListPath )
22+
...parsedAppList,
23+
...parsedGameList
3324
]
3425
}
3526

3627
export async function getVideoListingBySlug ( slug ) {
37-
const fetchedVideos = await fs.readJson( youtubeVideoPath )
3828
const allVideoAppsList = getAllVideoAppsList()
3929

40-
for ( const [ videoId, fetchedVideo ] of Object.entries( fetchedVideos ) ) {
30+
for ( const [ videoId, fetchedVideo ] of Object.entries( parsedYoutubeVideos ) ) {
4131
if ( makeVideoSlug( fetchedVideo.title, videoId ) !== slug ) continue
4232

4333
return await buildVideoListingFromFetchedVideo( fetchedVideo, videoId, allVideoAppsList )

0 commit comments

Comments
 (0)