#Nitro server plugin to cache Nuxt images: how to respond with a file from disk?

1 messages · Page 1 of 1 (latest)

brave fog
#

Hi, I am writing a server plugin like below. I am using the @nuxt/image module with the ipx provider. I would like it to save its generated image files to disk, and serve those files whenever the exact same file is requested.

This example below works. I get served files from disk. But I am using a new Response and doing event.respondWith(res); which keeps resulting in this error in the CLI:

[nuxt] [request error] [unhandled] [500] Cannot set headers after they are sent to the client
at ServerResponse.setHeader (node:_http_outgoing:659:11)
  at setResponseHeaders (./node_modules/h3/dist/index.mjs:778:20)

My knowledge of Nitro is limited; if I were to create a plugin like this, is this the correct way? How can I respond with the image file inside the request hook without getting [500] Cannot set headers after they are sent to the client ? Should I use another method to create this functionality? Help is greatly appreciated 🙂

// server/plugins/cache.ts
export default defineNitroPlugin(async (nitroApp) => {
    await mkdir(cacheFolder, { recursive: true });

    nitroApp.hooks.hook('request', async (event) => {
        const { path } = event;

        if (!path.startsWith('/_ipx/')) return;

        const targetCacheFilePath = getCacheKey(path);
        const exists = existsSync(targetCacheFilePath);

        if (exists) {
            const file = await readFile(targetCacheFilePath);
            const res = new Response(file, {
                status: 200,
                headers: {
                    'X-Nuxt-Image-Cache': 'HIT',
                },
            });

            await event.respondWith(res);
            console.log('Image served from cache:', targetCacheFilePath);
            return;
        }
    });

        nitroApp.hooks.hook('afterResponse', async (event, response) => {
         // save generated image file to disk, not important right now
    });
});
#

Complete error:

ERROR  [nuxt] [request error] [unhandled] [500] Cannot set headers after they are sent to the client
  at ServerResponse.setHeader (node:_http_outgoing:659:11)
  at setResponseHeaders (./node_modules/h3/dist/index.mjs:778:20)
  at Object.handler (./node_modules/nitropack/dist/runtime/route-rules.mjs:19:7)
  at ./node_modules/h3/dist/index.mjs:1963:31
  at async Object.callAsync (./node_modules/unctx/dist/index.mjs:72:16)
  at async Server.toNodeHandle (./node_modules/h3/dist/index.mjs:2250:7)