Handles compression for H3
✔️ Zlib Compression: You can use zlib compression (brotli, gzip and deflate)
✔️ Stream Compression: You can use native stream compressions (gzip, deflate)
✔️ Compression Detection: It uses the best compression which is accepted
✔️ h3 v1 & v2: Works with both h3 v1 and v2
# Using npm
npm install h3-compression
# Using yarn
yarn add h3-compression
# Using pnpm
pnpm add h3-compressionimport { createServer } from 'node:http'
import { createApp, eventHandler, toNodeListener } from 'h3'
import { useCompressionStream } from 'h3-compression'
const app = createApp({ onBeforeResponse: useCompressionStream }) // or { onBeforeResponse: useCompression }
app.use(
'/',
eventHandler(() => 'Hello world!'),
)
createServer(toNodeListener(app)).listen(process.env.PORT || 3000)Example using listhen for an elegant listener:
import { createApp, eventHandler, toNodeListener } from 'h3'
import { listen } from 'listhen'
import { useCompressionStream } from 'h3-compression'
const app = createApp({ onBeforeResponse: useCompressionStream }) // or { onBeforeResponse: useCompression }
app.use(
'/',
eventHandler(() => 'Hello world!'),
)
listen(toNodeListener(app))In h3 v2 the response is an immutable web Response and the onBeforeResponse
hook was removed. Use the compression / compressionStream middleware instead — they read the
response returned by the next handler and replace it with a compressed one.
import { createServer } from 'node:http'
import { H3, toNodeHandler } from 'h3'
import { compression } from 'h3-compression'
const app = new H3()
app.use(compression()) // or app.use(compressionStream())
app.get('/', () => 'Hello world!')
createServer(toNodeHandler(app)).listen(process.env.PORT || 3000)You can also force a specific method (e.g. compression('gzip')) instead of detecting it from the
Accept-Encoding header.
Note
compressionStream uses the native CompressionStream,
which only supports gzip and deflate (no brotli).
If you want to use it in Nuxt you can define a nitro plugin.
server/plugins/compression.ts
import { useCompression } from 'h3-compression'
export default defineNitroPlugin((nitro) => {
nitro.hooks.hook('render:response', async (response, { event }) => {
// Skip internal nuxt routes (e.g. error page)
if (['/_nuxt', '/__nuxt'].some(prefix => getRequestURL(event).pathname.startsWith(prefix)))
return
if (!response.headers?.['content-type']?.startsWith('text/html'))
return
await useCompression(event, response)
})
})Note
useCompressionStream doesn't work right now in nitro. So you just can use useCompression
The render:response hook only runs for freshly rendered SSR pages. Responses served
from the Nitro route cache (routeRules with swr / isr) and /server/api handlers
go through the beforeResponse hook instead. Use it to compress those too:
server/plugins/compression.ts
import { useCompression } from 'h3-compression'
export default defineNitroPlugin((nitro) => {
nitro.hooks.hook('beforeResponse', async (event, response) => {
// Skip internal nuxt routes (e.g. error page)
if (['/_nuxt', '/__nuxt'].some(prefix => event.path.startsWith(prefix)))
return
await useCompression(event, response)
})
})useCompression compresses string, Buffer/Uint8Array and JSON (object) bodies and
skips everything else (e.g. streams), so binary assets are left untouched. If you only
want to compress specific content types, guard on response.headers?.['content-type']
before calling it.
H3-compression has a concept of composable utilities that accept event (from eventHandler((event) => {})) as their first argument and response as their second.
useGZipCompression(event, response)useDeflateCompression(event, response)useBrotliCompression(event, response)useCompression(event, response)
useGZipCompressionStream(event, response)useDeflateCompressionStream(event, response)useCompressionStream(event, response)
compression(method?)– middleware using zlib (brotli, gzip, deflate)compressionStream(method?)– middleware using the nativeCompressionStream(gzip, deflate)compressResponse(event, value, method?)– low-level helper returning a compressedResponsecompressResponseStream(event, value, method?)– low-level stream helper returning a compressedResponse
MIT License © 2023-PRESENT Gregor Becker