Can you use serveStatic within onNotFound of a serveStatic handler?

I have a scenario where my match-all route attempts to serve that static asset from the build dir. In the event that the asset can’t be found, I would like to serve a default asset. Take the following paths for example:


/about/build/about doesn’t exist, so onNotFound should serve /build/index.html
/users/build/about doesn’t exist, so onNotFound should serve /build/index.html

The last 2 routes are client-side and instead of individually defining them to serve index.html, I’d like it to just default to a specific asset.

.match('/:path*', ({ serveStatic, request }) => {
  console.log(`attempting to serve ${request.path}`);
  serveStatic('build/:path*', {
    onNotFound: () => {
      console.log('serving default index.html');

In this handler, the first log is always called, but never reaches the second if the asset can’t be found. The response is just a 404. Is this intended?

I think there might be a bug where the assets referenced in onNotFound aren’t automatically copied up to the cloud. You could work around this by explicitly listing them in xdn.config.js under includeFiles: Moovweb XDN Documentation - xdn.config.js

To clarify, the issue is more around what it takes for onNotFound to be called and not necessarily about the inner assets of serveStatic being copied.

For example, should something like this be possible?

.get('/foo', ({ serveStatic, send }) => {
  // known non-existant resource
  serveStatic('foo.html', { 
    onNotFound: () => {
      console.log('not found')
      return send('foo not found')

This issue has been logged as XDN-8849.