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
This commit is contained in:
ThatGuySam 2026-04-06 11:00:53 -05:00
parent 6cfbfbf530
commit d39a2a1d6c

View file

@ -1,43 +1,33 @@
import fs from 'fs-extra' import youtubeVideosText from '~/static/api/youtube-videos.json?raw'
import path from 'path' import appListText from '~/static/app-list.json?raw'
import { fileURLToPath } from 'url' import deviceListText from '~/static/device-list.json?raw'
import gameListText from '~/static/game-list.json?raw'
import { import {
buildVideoListingFromFetchedVideo, buildVideoListingFromFetchedVideo,
makeVideoSlug makeVideoSlug
} from '~/helpers/build-video-list.js' } from '~/helpers/build-video-list.js'
import { youtubeVideoPath } from '~/helpers/api/youtube/build.js'
const currentModuleDirectory = path.dirname( fileURLToPath( import.meta.url ) )
const appListPath = path.join( currentModuleDirectory, '../static/app-list.json' )
const gameListPath = path.join( currentModuleDirectory, '../static/game-list.json' )
const deviceListPath = path.join( currentModuleDirectory, '../static/device-list.json' )
const trailingCommaPattern = /,\s*([\]}])/g const trailingCommaPattern = /,\s*([\]}])/g
const parsedDeviceList = JSON.parse( deviceListText.replace( trailingCommaPattern, '$1' ) )
function parseGeneratedJsonFile ( filePath ) { const parsedAppList = JSON.parse( appListText.replace( trailingCommaPattern, '$1' ) )
const fileContents = fs.readFileSync( filePath, 'utf8' ) const parsedGameList = JSON.parse( gameListText.replace( trailingCommaPattern, '$1' ) )
const parsedYoutubeVideos = JSON.parse( youtubeVideosText )
return JSON.parse( fileContents.replace( trailingCommaPattern, '$1' ) )
}
export function getDeviceListingBySlug ( slug ) { export function getDeviceListingBySlug ( slug ) {
const deviceList = parseGeneratedJsonFile( deviceListPath ) return parsedDeviceList.find( device => device.slug === slug ) || null
return deviceList.find( device => device.slug === slug ) || null
} }
function getAllVideoAppsList () { function getAllVideoAppsList () {
return [ return [
...parseGeneratedJsonFile( appListPath ), ...parsedAppList,
...parseGeneratedJsonFile( gameListPath ) ...parsedGameList
] ]
} }
export async function getVideoListingBySlug ( slug ) { export async function getVideoListingBySlug ( slug ) {
const fetchedVideos = await fs.readJson( youtubeVideoPath )
const allVideoAppsList = getAllVideoAppsList() const allVideoAppsList = getAllVideoAppsList()
for ( const [ videoId, fetchedVideo ] of Object.entries( fetchedVideos ) ) { for ( const [ videoId, fetchedVideo ] of Object.entries( parsedYoutubeVideos ) ) {
if ( makeVideoSlug( fetchedVideo.title, videoId ) !== slug ) continue if ( makeVideoSlug( fetchedVideo.title, videoId ) !== slug ) continue
return await buildVideoListingFromFetchedVideo( fetchedVideo, videoId, allVideoAppsList ) return await buildVideoListingFromFetchedVideo( fetchedVideo, videoId, allVideoAppsList )