h3-compression icon indicating copy to clipboard operation
h3-compression copied to clipboard

`beforeResponse` hook does not work for Nuxt3 `/server/api`

Open andrewspy opened this issue 11 months ago • 4 comments

I wanted to compress a large JSON response from /server/api, but useCompression() does not seem to work with beforeResponse hook in Nuxt3. Code as follow:

nitro.hooks.hook('beforeResponse', async (event, response) => {
  if (!event.path.startsWith('/api/')) return

  await useCompression(event, response)
})

According to Nitro doc below, it should work as expected, did I miss something? Thanks!

https://nitro.build/guide/plugins#available-hooks

andrewspy avatar Feb 18 '25 19:02 andrewspy

I think the reason for this is that useCompression needs an accept-encoding header which it doesn't have i guess. The easiest way i think is to use the routeRules in nuxt.config or you add it in your api response. Can you check this please? Thank you!

CodeDredd avatar Feb 19 '25 20:02 CodeDredd

@CodeDredd I did a nuxt preview locally and it does have accept-encoding header as follows:

Request headers

GET /api/query HTTP/1.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate, br, zstd
Cache-Control: no-cache
Connection: keep-alive
Host: localhost:3000
Pragma: no-cache
...

Respond headers

HTTP/1.1 200 OK
Vary: Accept-Encoding
content-type: application/json
Date: Thu, 20 Feb 2025 02:56:11 GMT
Connection: keep-alive
Keep-Alive: timeout=5
Content-Length: 35

andrewspy avatar Feb 20 '25 03:02 andrewspy

@CodeDredd Here's a minimal reproduction on Stackbliz, however, it does not work on Stackbliz due to missing req headers for your reference:

https://stackblitz.com/edit/h3-compression-with-api?file=app.vue

Note:

  • This reproduction does not work on stackbliz due to missing req headers

  • To reproduce locally, copy the following files:

    • /server/plugins/compression.ts
    • /server/api/query.ts
  • On localhost (npm run build && npm run preview),

    • localhost:3000/ does compress.
    • localhost:3000/api/query does not compress.

andrewspy avatar Feb 20 '25 03:02 andrewspy

perhaps its because your response content-type is json and the library support just plaintext reference

I am also wondering if we can compress JSON response some how 🤔

poke19962008 avatar Oct 11 '25 11:10 poke19962008