Nuxt Hooks · Nuxt Skew Protection · Nuxt SEO

-
-
-
-

[Sign In](https://nuxtseo.com/auth/github)

[Nuxt SEO on GitHub](https://github.com/harlan-zw/nuxt-seo)

Skew Protection

-
-
-
-
-
-
-
-
-
-

Search…```k`` /`

v1.1.1

- [Discord Support](https://discord.com/invite/275MBUBvgP)

### Nuxt API

-
-
-
-
-

### Nitro API

-
-

Nuxt API

# Nuxt Hooks

[Copy for LLMs](https://nuxtseo.com/docs/skew-protection/api/nuxt-hooks.md)

## [`'skew:chunks-outdated'`](#skewchunks-outdated)

**Type:** `(payload: ChunksOutdatedPayload) => void | Promise<void>`

Triggered when the client detects that the server has deleted chunks from their current version.

```
interface ChunksOutdatedPayload {
  deletedChunks: string[]
  invalidatedModules: string[]
  passedReleases: string[]
}
```

```
export default defineNuxtConfig({
  hooks: {
    'skew:chunks-outdated': (payload) => {
      console.log('Outdated chunks:', payload.deletedChunks)
      console.log('Releases since client version:', payload.passedReleases)
    },
  },
})
```

## [`'skew:message'`](#skewmessage)

**Type:** `(message: { type: string, [key: string]: unknown }) => void | Promise<void>`

Triggered for every message received from the SSE or [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) connection. Useful for building custom functionality on top of the real-time connection.

plugins/skew-listener.client.ts

```
export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.hooks.hook('skew:message', (message) => {
    if (message.type === 'stats') {
      console.log('Active connections:', message.total)
      console.log('Version distribution:', message.versions)
    }

    if (message.type === 'connected') {
      console.log('Connected to server version:', message.version)
    }
  })
})
```

### [Message Types](#message-types)

| Type | Description | Payload |
| --- | --- | --- |
| `connected` | Initial connection acknowledgment | `{ version, timestamp }` |
| `keepalive` | Periodic heartbeat | `{ timestamp }` |
| `stats` | Connection statistics (requires authorization) | `{ total, versions, routes }` |
| `stats-unauthorized` | Sent when stats subscription is denied | `{}` |

The server only sends stats messages to connections that pass the `skew:authorize-stats` hook. See

 for setup.

## [Connection Config Hooks](#connection-config-hooks)

These hooks allow you to customize the connection configuration before the connection is established.

### [`'skew:ws:config'`](#skewwsconfig)

**Type:** `(config: SkewWebSocketConfig) => void | Promise<void>`

Customize WebSocket connection settings. The `options` type extends [`UseWebSocketOptions`](https://vueuse.org/core/useWebSocket/) from [VueUse](https://vueuse.org).

```
import type { UseWebSocketOptions } from '@vueuse/core'

interface SkewWebSocketConfig {
  url: string
  options: UseWebSocketOptions
}
```

plugins/skew-config.client.ts

```
export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.hook('skew:ws:config', (config) => {
    // Custom WebSocket URL
    config.url = 'wss://custom-endpoint.example.com/ws'

    // Adjust reconnection behavior
    config.options.autoReconnect = { retries: 5, delay: 10000 }
  })
})
```

**The module disables heartbeat by default** to reduce server load and allow Cloudflare Durable Objects to hibernate. Enable it only if your infrastructure has aggressive idle timeouts (some proxies close connections after 60s of inactivity).

plugins/enable-heartbeat.client.ts

```
export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.hook('skew:ws:config', (config) => {
    // Enable heartbeat for infrastructure with aggressive idle timeouts
    config.options.heartbeat = {
      message: JSON.stringify({ type: 'ping', timestamp: Date.now() }),
      interval: 30000, // ping every 30s
      pongTimeout: 10000 // expect pong within 10s
    }
  })
})
```

### [`'skew:sse:config'`](#skewsseconfig)

**Type:** `(config: SkewSSEConfig) => void | Promise<void>`

Customize Server-Sent Events connection settings. The `options` type extends [`UseEventSourceOptions`](https://vueuse.org/core/useEventSource/) from VueUse.

```
import type { UseEventSourceOptions } from '@vueuse/core'

interface SkewSSEConfig {
  url: string
  options: UseEventSourceOptions<string>
}
```

plugins/skew-config.client.ts

```
export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.hook('skew:sse:config', (config) => {
    // Custom SSE URL
    config.url = '/_custom/sse-endpoint'

    // Adjust reconnection behavior
    config.options.autoReconnect = { retries: 3, delay: 5000 }
  })
})
```

### [`'skew:adapter:config'`](#skewadapterconfig)

**Type:** `(config: SkewAdapterConfig) => void | Promise<void>`

Customize adapter-based connection settings (e.g., [Redis](https://redis.io), Upstash).

```
interface SkewAdapterConfig {
  channel: string
  adapterConfig: Record<string, unknown>
}
```

plugins/skew-config.client.ts

```
export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.hook('skew:adapter:config', (config) => {
    // Override the channel name
    config.channel = 'my-custom-channel'
  })
})
```

[Edit this page](https://github.com/nuxt-seo-pro/nuxt-skew-protection/edit/main/docs/content/3.api/1.nuxt-hooks.md)

[Markdown For LLMs](https://nuxtseo.com/docs/skew-protection/api/nuxt-hooks.md)

Did this page help you?

On this page

- ['skew:chunks-outdated'](#skewchunks-outdated)
- ['skew:message'](#skewmessage)
- [Connection Config Hooks](#connection-config-hooks)

[GitHub](https://github.com/harlan-zw/nuxt-seo) [ Discord](https://discord.com/invite/275MBUBvgP)

###

-
-

Modules

-
-
-
-
-
-
-
-
-

###

-
-
-

###

Nuxt

-
-
-
-
-

Vue

-
-
-
-
-
-
-
-

###

-
-
-
-
-
-
-
-
-
-

Copyright © 2023-2026 Harlan Wilton - [MIT License](https://github.com/harlan-zw/nuxt-seo/blob/main/license) · [mdream](https://mdream.dev)