From e5f5ddd350b7db31c2fa07a4cf6d0d8fd4136107 Mon Sep 17 00:00:00 2001 From: Daniel Choudhury Date: Tue, 17 Oct 2023 22:09:00 +0700 Subject: [PATCH] fix(fastify): Dont fallback to index html if requesting static assets (#9272) Attempts to fix an issue we found on teamstream with @KrisCoulson **The summary:** if you are requesting an asset (e.g. .js, jpeg, ico) file - we should _not_ respond with the index html. The response is meant to be for any routes that haven't been prerendered, and is an SPA fallback (so client side routing takes over). Because the 200 response here can get cached (intheory 200 means, all ok, so cloudflare or CDN would be correct to cache it), it can lead to problems where trying to load dynamically loaded chunks causes fatal errors. The change in this PR just throws a 404, when a .js file is being requested and it doesn't exist - mainly to prevent caching. --- packages/fastify/src/web.ts | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/packages/fastify/src/web.ts b/packages/fastify/src/web.ts index 46116ab4754a..8814ee604fff 100644 --- a/packages/fastify/src/web.ts +++ b/packages/fastify/src/web.ts @@ -6,6 +6,7 @@ import fg from 'fast-glob' import type { FastifyInstance, FastifyReply, + FastifyRequest, HookHandlerDoneFunction, } from 'fastify' @@ -47,10 +48,21 @@ export async function redwoodFastifyWeb( const indexPath = getFallbackIndexPath() // For SPA routing, fallback on unmatched routes and let client-side routing take over. - fastify.setNotFoundHandler({}, function (_, reply: FastifyReply) { - reply.header('Content-Type', 'text/html; charset=UTF-8') - reply.sendFile(indexPath) - }) + fastify.setNotFoundHandler( + {}, + function (req: FastifyRequest, reply: FastifyReply) { + const requestedExtension = path.extname(req.url) + // If it's requesting some sort of asset, e.g. .js or .jpg files + // Html files should fallback to the index.html + if (requestedExtension !== '' && requestedExtension !== '.html') { + reply.code(404) + return reply.send('Not Found') + } + + reply.header('Content-Type', 'text/html; charset=UTF-8') + return reply.sendFile(indexPath) + } + ) done() }