Repository: nuxt/nuxt
File: packages/nuxt/src/core/nitro.ts (TypeScript)

Code before:
      'process.env.NUXT_COMPONENT_ISLANDS': !!nuxt.options.experimental.componentIslands,
      'process.dev': nuxt.options.dev,
      __VUE_PROD_DEVTOOLS__: false
    },
    rollupConfig: {
      output: {},
      plugins: []
    }
  } satisfies NitroConfig)

  // Resolve user-provided paths
  nitroConfig.srcDir = resolve(nuxt.options.rootDir, nuxt.options.srcDir, nitroConfig.srcDir!)

  // Add app manifest handler and prerender configuration
  // TODO: expose build id to nitro
  const buildId = randomUUID()
  if (nitroConfig.prerender?.routes) {
    const manifestPrefix = '/_builds'
    nitroConfig.prerender.routes.push(joinURL(manifestPrefix, 'latest.json'))
    nitroConfig.prerender.routes.push(joinURL(manifestPrefix, `meta.${buildId}.json`))
    nitroConfig.devHandlers!.push({
      route: joinURL(manifestPrefix, '**'),
      handler: defineEventHandler(() => ({
        id: 'dev',
        timestamp: Date.now(),
        routeRules: {},
        prerendered: []
      }))
    })

    if (!nuxt.options.dev) {
      const timestamp = Date.now()
      nitroConfig.virtual!['#app-manifest'] = () => `
        export const hashId = ${JSON.stringify(buildId)}
        export const buildTimestamp = ${JSON.stringify(timestamp)}
      `
      nitroConfig.handlers!.push({
        route: joinURL(manifestPrefix, '**'),
        handler: resolve(distDir, 'core/runtime/nitro/manifest')
      })
    }
  }

  // Add fallback server for `ssr: false`
  if (!nuxt.options.ssr) {
    nitroConfig.virtual!['#build/dist/server/server.mjs'] = 'export default () => {}'
    // In case a non-normalized absolute path is called for on Windows
    if (process.platform === 'win32') {
      nitroConfig.virtual!['#build/dist/server/server.mjs'.replace(/\//g, '\\')] = 'export default () => {}'
    }
  }

Review comment (security):
Maybe WIP? In dev mode, route rules such as redirect can be applied as well and we can directly give them from handler. Even if not used by nuxt, returning them can be useful also for module authors to leverage

Code after:
      plugins: []
    }
  } satisfies NitroConfig)

  // Resolve user-provided paths
  nitroConfig.srcDir = resolve(nuxt.options.rootDir, nuxt.options.srcDir, nitroConfig.srcDir!)
  nitroConfig.ignore = [...(nitroConfig.ignore || []), ...resolveIgnorePatterns(nitroConfig.srcDir)]

  // Add app manifest handler and prerender configuration
  if (nuxt.options.experimental.appManifest) {
    // @ts-expect-error untyped nuxt property
    const buildId = nuxt.options.appConfig.nuxt!.buildId ||= randomUUID()
    const buildTimestamp = Date.now()

    const manifestPrefix = joinURL(nuxt.options.app.buildAssetsDir, 'builds')
    const tempDir = join(nuxt.options.buildDir, 'manifest')

    nitroConfig.publicAssets!.unshift(
      // build manifest
      {
        dir: join(tempDir, 'meta'),
        maxAge: 31536000 /* 1 year */,
        baseURL: joinURL(manifestPrefix, 'meta')
      },
      // latest build
      {
        dir: tempDir,
        maxAge: 1,
        baseURL: manifestPrefix
      }
    )

    nuxt.hook('nitro:build:before', async (nitro) => {
      const routeRules = {} as Record<string, any>
      const _routeRules = nitro.options.routeRules
      for (const key in _routeRules) {
        if (key === '/__nuxt_error') { continue }
        const filteredRules = Object.entries(_routeRules[key])
          .filter(([key, value]) => ['prerender', 'redirect'].includes(key) && value)
          .map(([key, value]: any) => {
            if (key === 'redirect') {
              return [key, typeof value === 'string' ? value : value.to]
            }
            return [key, value]
          })
        if (filteredRules.length > 0) {
          routeRules[key] = Object.fromEntries(filteredRules)
        }
      }

      // Add pages prerendered but not covered by route rules