Tracking User Pages · Nuxt Skew Protection · Nuxt SEO

[NuxtSEO Pro](https://nuxtseo.com/ "Home")

- [Modules](https://nuxtseo.com/docs/nuxt-seo/getting-started/introduction)
- [Tools](https://nuxtseo.com/tools)
- [Pro](https://nuxtseo.com/pro)
- [Learn SEO](https://nuxtseo.com/learn-seo/nuxt) [Releases](https://nuxtseo.com/releases)

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

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

[User Guides](https://nuxtseo.com/docs/skew-protection/getting-started/introduction)

[API](https://nuxtseo.com/docs/skew-protection/api/use-skew-protection)

[Releases](https://nuxtseo.com/docs/skew-protection/releases/v1)

Skew Protection

- [Switch to Skew Protection](https://nuxtseo.com/docs/skew-protection/getting-started/introduction)
- [Switch to Nuxt SEO](https://nuxtseo.com/docs/nuxt-seo/getting-started/introduction)
- [Switch to Robots](https://nuxtseo.com/docs/robots/getting-started/introduction)
- [Switch to Sitemap](https://nuxtseo.com/docs/sitemap/getting-started/introduction)
- [Switch to OG Image](https://nuxtseo.com/docs/og-image/getting-started/introduction)
- [Switch to Schema.org](https://nuxtseo.com/docs/schema-org/getting-started/introduction)
- [Switch to Link Checker](https://nuxtseo.com/docs/link-checker/getting-started/introduction)
- [Switch to SEO Utils](https://nuxtseo.com/docs/seo-utils/getting-started/introduction)
- [Switch to Site Config](https://nuxtseo.com/docs/site-config/getting-started/introduction)
- [Switch to AI Ready](https://nuxtseo.com/docs/ai-ready/getting-started/introduction)

Search…```k`` /`

v1.1.1

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

### Getting Started

- [Introduction](https://nuxtseo.com/docs/skew-protection/getting-started/introduction)
- [Installation](https://nuxtseo.com/docs/skew-protection/getting-started/installation)

### Core Concepts

- [Check for Update Strategy](https://nuxtseo.com/docs/skew-protection/guides/update-strategies)
- [Update Notifications](https://nuxtseo.com/docs/skew-protection/guides/immediate-updates)
- [Performance](https://nuxtseo.com/docs/skew-protection/guides/performance)
- [Persistent Storage](https://nuxtseo.com/docs/skew-protection/guides/storage-configuration)
- [Notification UI](https://nuxtseo.com/docs/skew-protection/guides/ui-examples)
- [Cookie Consent](https://nuxtseo.com/docs/skew-protection/guides/cookie-consent)
- [View Active Connections](https://nuxtseo.com/docs/skew-protection/guides/live-connections)
- [Tracking User Pages](https://nuxtseo.com/docs/skew-protection/guides/route-tracking)

### Providers

- [External Providers](https://nuxtseo.com/docs/skew-protection/providers/external)
- [Cloudflare](https://nuxtseo.com/docs/skew-protection/providers/cloudflare)

Core Concepts

# Tracking User Pages

[Copy for LLMs](https://nuxtseo.com/docs/skew-protection/guides/route-tracking.md)

Track which pages your users are currently viewing in real-time. This enables targeted version invalidation for specific routes without affecting users on other pages.

Route tracking requires `connectionTracking: true` and only works with `sse` or `ws` update strategies.

Route data is only available to authorized connections for privacy. Regular users cannot see which pages other users are viewing.

## [Setup](#setup)

Enable route tracking in your Nuxt config:

nuxt.config.ts

```
export default defineNuxtConfig({
  skewProtection: {
    connectionTracking: true,
    routeTracking: true
  }
})
```

### [Authorization Hook](#authorization-hook)

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

server/plugins/skew-auth.ts

```
export default defineNitroPlugin((nitroApp) => {
  nitroApp.hooks.hook('skew:authorize-stats', async ({ event, authorize }) => {
    // With nuxt-auth-utils
    const session = await getUserSession(event)
    if (session.user?.role === 'admin') {
      authorize()
    }
  })
})
```

## [Real-time Stats via useActiveConnections](#real-time-stats-via-useactiveconnections)

For live updates, use the `useActiveConnections` composable on authorized pages:

pages/admin/dashboard.vue

```
<script setup lang="ts">
const { total, versions, routes, authorized } = useActiveConnections()

const sortedRoutes = computed(() => {
  return Object.entries(routes.value)
    .sort(([, a], [, b]) => b - a)
    .slice(0, 10)
})
</script>

<template>
  <div v-if="authorized" class="live-pages">
    <h3>Most Active Pages ({{ total }} users)</h3>
    <table>
      <tr v-for="[route, count] in sortedRoutes" :key="route">
        <td>{{ route }}</td>
        <td>{{ count }} viewers</td>
      </tr>
    </table>
  </div>
  <div v-else>
    Not authorized for live stats
  </div>
</template>
```

## [API Endpoint (Alternative)](#api-endpoint-alternative)

For non-WebSocket access (CI/CD, external tools), expose stats via an API endpoint:

server/api/admin/stats.get.ts

```
export default defineEventHandler(async (event) => {
  const authHeader = getHeader(event, 'authorization')
  if (authHeader !== \`Bearer ${process.env.ADMIN_SECRET}\`) {
    throw createError({ statusCode: 401 })
  }

  return new Promise((resolve) => {
    const nitroApp = useNitroApp()
    // @ts-expect-error custom hook
    nitroApp.hooks.callHook('skew:stats', (stats) => {
      resolve(stats)
    })
  })
})
```

The stats object contains:

```
interface Stats {
  total: number // Total active connections
  versions: Record<string, number> // Users per build version
  routes: Record<string, number> // Users per route path
}
```

## [Invalidating Users on Specific Routes](#invalidating-users-on-specific-routes)

Force users on a specific page to refresh when you deploy critical changes to that page.

### [Server Plugin for Route Invalidation](#server-plugin-for-route-invalidation)

server/plugins/route-invalidation.ts

```
import { defineNitroPlugin } from 'nitropack/runtime'

export default defineNitroPlugin((nitroApp) => {
  const connections = new Map<string, { route: string, send: (data: unknown) => void }>()

  nitroApp.hooks.hook('skew:connection:open', ({ id, route, send }) => {
    connections.set(id, { route: route || '/', send })
  })

  nitroApp.hooks.hook('skew:connection:route-update', ({ id, route }) => {
    const conn = connections.get(id)
    if (conn)
      conn.route = route
  })

  nitroApp.hooks.hook('skew:connection:close', ({ id }) => {
    connections.delete(id)
  })

  // Expose function to invalidate specific routes
  // @ts-expect-error extending global
  globalThis.invalidateRoute = (routePattern: string | RegExp) => {
    const version = useRuntimeConfig().app.buildId
    for (const [, conn] of connections) {
      const matches = typeof routePattern === 'string'
        ? conn.route === routePattern || conn.route.startsWith(routePattern)
        : routePattern.test(conn.route)

      if (matches) {
        conn.send({ type: 'version', version, force: true })
      }
    }
  }
})
```

### [API Endpoint for Invalidation](#api-endpoint-for-invalidation)

server/api/admin/invalidate-route.post.ts

```
export default defineEventHandler(async (event) => {
  const { route, secret } = await readBody(event)

  if (secret !== process.env.ADMIN_SECRET) {
    throw createError({ statusCode: 401 })
  }

  // @ts-expect-error global function from plugin
  globalThis.invalidateRoute?.(route)

  return { ok: true, route }
})
```

### [Usage from CI/CD](#usage-from-cicd)

After deploying changes to a specific page:

```
# Invalidate all users on /checkout
curl -X POST https://yoursite.com/api/admin/invalidate-route \
  -H "Content-Type: application/json" \
  -d '{"route": "/checkout", "secret": "your-admin-secret"}'

# Invalidate all users on /blog/* routes
curl -X POST https://yoursite.com/api/admin/invalidate-route \
  -H "Content-Type: application/json" \
  -d '{"route": "/blog/", "secret": "your-admin-secret"}'
```

## [Performance Considerations](#performance-considerations)

Route tracking sends a message to the server on every client-side navigation. For high-traffic sites:

- The module tracks routes per-connection, not per-pageview
- Messages are small (~50 bytes per navigation)
- Consider disabling for sites with rapid navigation patterns

## [Limitations](#limitations)

- Same limitations as [connection tracking](https://nuxtseo.com/docs/skew-protection/guides/live-connections#limitations)
- Route paths only (the module does not track query strings or hashes)
- Client-side navigations only (full page loads reconnect with new route)
- Route data is server-side only (not exposed to clients for privacy)

[Edit this page](https://github.com/nuxt-seo-pro/nuxt-skew-protection/edit/main/docs/content/2.guides/7.route-tracking.md)

[Markdown For LLMs](https://nuxtseo.com/docs/skew-protection/guides/route-tracking.md)

Did this page help you?

[View Active Connections Monitor active connections and version distribution in real-time.](https://nuxtseo.com/docs/skew-protection/guides/live-connections) [Nuxt Hooks Learn how to use Nuxt hooks to respond to skew protection events.](https://nuxtseo.com/docs/skew-protection/api/nuxt-hooks)

On this page

- [Setup](#setup)
- [Real-time Stats via useActiveConnections](#real-time-stats-via-useactiveconnections)
- [API Endpoint (Alternative)](#api-endpoint-alternative)
- [Invalidating Users on Specific Routes](#invalidating-users-on-specific-routes)
- [Performance Considerations](#performance-considerations)
- [Limitations](#limitations)

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

### [NuxtSEO](https://nuxtseo.com/ "Home")

- [Getting Started](https://nuxtseo.com/docs/nuxt-seo/getting-started/introduction)
- [MCP](https://nuxtseo.com/docs/nuxt-seo/guides/mcp)

Modules

- [Robots](https://nuxtseo.com/docs/robots/getting-started/introduction)
- [Sitemap](https://nuxtseo.com/docs/sitemap/getting-started/introduction)
- [OG Image](https://nuxtseo.com/docs/og-image/getting-started/introduction)
- [Schema.org](https://nuxtseo.com/docs/schema-org/getting-started/introduction)
- [Link Checker](https://nuxtseo.com/docs/link-checker/getting-started/introduction)
- [SEO Utils](https://nuxtseo.com/docs/seo-utils/getting-started/introduction)
- [Site Config](https://nuxtseo.com/docs/site-config/getting-started/introduction)
- [Skew Protection](https://nuxtseo.com/docs/skew-protection/getting-started/introduction)
- [AI Ready](https://nuxtseo.com/docs/ai-ready/getting-started/introduction)

### [NuxtSEO Pro](https://nuxtseo.com/pro "Home")

- [Getting Started](https://nuxtseo.com/pro)
- [Dashboard](https://nuxtseo.com/pro/dashboard)
- [Pro MCP](https://nuxtseo.com/docs/nuxt-seo-pro/mcp/installation)

### [Learn SEO](https://nuxtseo.com/learn-seo "Learn SEO")

Nuxt

- [Mastering Meta](https://nuxtseo.com/learn-seo/nuxt/mastering-meta)
- [Controlling Crawlers](https://nuxtseo.com/learn-seo/nuxt/controlling-crawlers)
- [Launch & Listen](https://nuxtseo.com/learn-seo/nuxt/launch-and-listen)
- [Routes & Rendering](https://nuxtseo.com/learn-seo/nuxt/routes-and-rendering)
- [Staying Secure](https://nuxtseo.com/learn-seo/nuxt/routes-and-rendering/security)

Vue

- [Vue SEO Guide](https://nuxtseo.com/learn-seo/vue)
- [Mastering Meta](https://nuxtseo.com/learn-seo/vue/mastering-meta)
- [Controlling Crawlers](https://nuxtseo.com/learn-seo/vue/controlling-crawlers)
- [SPA SEO](https://nuxtseo.com/learn-seo/vue/spa)
- [SSR Frameworks](https://nuxtseo.com/learn-seo/vue/ssr-frameworks)
- [SEO Checklist](https://nuxtseo.com/learn-seo/checklist)
- [Pre-Launch Warmup](https://nuxtseo.com/learn-seo/pre-launch-warmup)
- [Backlinks & Authority](https://nuxtseo.com/learn-seo/backlinks)

### [Tools](https://nuxtseo.com/tools "SEO Tools")

- [Social Share Debugger](https://nuxtseo.com/tools/social-share-debugger)
- [Robots.txt Generator](https://nuxtseo.com/tools/robots-txt-generator)
- [Meta Tag Checker](https://nuxtseo.com/tools/meta-tag-checker)
- [HTML to Markdown](https://nuxtseo.com/tools/html-to-markdown)
- [XML Sitemap Validator](https://nuxtseo.com/tools/xml-sitemap-validator)
- [Schema.org Validator](https://nuxtseo.com/tools/schema-validator)
- [Keyword Idea Generator](https://nuxtseo.com/tools/keyword-generator)
- [Keyword Research](https://nuxtseo.com/tools/keyword-research)
- [SERP Analyzer](https://nuxtseo.com/tools/serp-analyzer)
- [Domain Rankings](https://nuxtseo.com/tools/domain-rankings)

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