Files
agent-skills/skills/nuxt/references/advanced-hooks.md
Jason Woltje f5792c40be feat: Complete fleet — 94 skills across 10+ domains
Pulled ALL skills from 15 source repositories:
- anthropics/skills: 16 (docs, design, MCP, testing)
- obra/superpowers: 14 (TDD, debugging, agents, planning)
- coreyhaines31/marketingskills: 25 (marketing, CRO, SEO, growth)
- better-auth/skills: 5 (auth patterns)
- vercel-labs/agent-skills: 5 (React, design, Vercel)
- antfu/skills: 16 (Vue, Vite, Vitest, pnpm, Turborepo)
- Plus 13 individual skills from various repos

Mosaic Stack is not limited to coding — the Orchestrator and
subagents serve coding, business, design, marketing, writing,
logistics, analysis, and more.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 16:27:42 -06:00

6.0 KiB

name, description
name description
lifecycle-hooks Nuxt and Nitro hooks for extending build-time and runtime behavior

Lifecycle Hooks

Nuxt provides hooks to tap into the build process, application lifecycle, and server runtime.

Build-time Hooks (Nuxt)

Used in nuxt.config.ts or modules:

In nuxt.config.ts

// nuxt.config.ts
export default defineNuxtConfig({
  hooks: {
    'build:before': () => {
      console.log('Build starting...')
    },
    'pages:extend': (pages) => {
      // Add custom pages
      pages.push({
        name: 'custom',
        path: '/custom',
        file: '~/pages/custom.vue',
      })
    },
    'components:dirs': (dirs) => {
      // Add component directories
      dirs.push({ path: '~/extra-components' })
    },
  },
})

In Modules

// modules/my-module.ts
export default defineNuxtModule({
  setup(options, nuxt) {
    nuxt.hook('ready', async (nuxt) => {
      console.log('Nuxt is ready')
    })

    nuxt.hook('close', async (nuxt) => {
      console.log('Nuxt is closing')
    })

    nuxt.hook('modules:done', () => {
      console.log('All modules loaded')
    })
  },
})

Common Build Hooks

Hook When
ready Nuxt initialization complete
close Nuxt is closing
modules:done All modules installed
build:before Before build starts
build:done Build complete
pages:extend Pages routes resolved
components:dirs Component dirs being resolved
imports:extend Auto-imports being resolved
nitro:config Before Nitro config finalized
vite:extend Vite context created
vite:extendConfig Before Vite config finalized

App Hooks (Runtime)

Used in plugins and composables:

In Plugins

// plugins/lifecycle.ts
export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.hook('app:created', (vueApp) => {
    console.log('Vue app created')
  })

  nuxtApp.hook('app:mounted', (vueApp) => {
    console.log('App mounted')
  })

  nuxtApp.hook('page:start', () => {
    console.log('Page navigation starting')
  })

  nuxtApp.hook('page:finish', () => {
    console.log('Page navigation finished')
  })

  nuxtApp.hook('page:loading:start', () => {
    console.log('Page loading started')
  })

  nuxtApp.hook('page:loading:end', () => {
    console.log('Page loading ended')
  })
})

Common App Hooks

Hook When
app:created Vue app created
app:mounted Vue app mounted (client only)
app:error Fatal error occurred
page:start Page navigation starting
page:finish Page navigation finished
page:loading:start Loading indicator should show
page:loading:end Loading indicator should hide
link:prefetch Link is being prefetched

Using Runtime Hooks

// composables/usePageTracking.ts
export function usePageTracking() {
  const nuxtApp = useNuxtApp()

  nuxtApp.hook('page:finish', () => {
    trackPageView(useRoute().path)
  })
}

Server Hooks (Nitro)

Used in server plugins:

// server/plugins/hooks.ts
export default defineNitroPlugin((nitroApp) => {
  // Modify HTML before sending
  nitroApp.hooks.hook('render:html', (html, { event }) => {
    html.head.push('<meta name="custom" content="value">')
    html.bodyAppend.push('<script>console.log("injected")</script>')
  })

  // Modify response
  nitroApp.hooks.hook('render:response', (response, { event }) => {
    console.log('Sending response:', response.statusCode)
  })

  // Before request
  nitroApp.hooks.hook('request', (event) => {
    console.log('Request:', event.path)
  })

  // After response
  nitroApp.hooks.hook('afterResponse', (event) => {
    console.log('Response sent')
  })
})

Common Nitro Hooks

Hook When
request Request received
beforeResponse Before sending response
afterResponse After response sent
render:html Before HTML is sent
render:response Before response is finalized
error Error occurred

Custom Hooks

Define Custom Hook Types

// types/hooks.d.ts
import type { HookResult } from '@nuxt/schema'

declare module '#app' {
  interface RuntimeNuxtHooks {
    'my-app:event': (data: MyEventData) => HookResult
  }
}

declare module '@nuxt/schema' {
  interface NuxtHooks {
    'my-module:init': () => HookResult
  }
}

declare module 'nitropack/types' {
  interface NitroRuntimeHooks {
    'my-server:event': (data: any) => void
  }
}

Call Custom Hooks

// In a plugin
export default defineNuxtPlugin((nuxtApp) => {
  // Call custom hook
  nuxtApp.callHook('my-app:event', { type: 'custom' })
})

// In a module
export default defineNuxtModule({
  setup(options, nuxt) {
    nuxt.callHook('my-module:init')
  },
})

useRuntimeHook

Call hooks at runtime from components:

<script setup lang="ts">
// Register a callback for a runtime hook
useRuntimeHook('app:error', (error) => {
  console.error('App error:', error)
})
</script>

Hook Examples

Page View Tracking

// plugins/analytics.client.ts
export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.hook('page:finish', () => {
    const route = useRoute()
    analytics.track('pageview', {
      path: route.path,
      title: document.title,
    })
  })
})

Performance Monitoring

// plugins/performance.client.ts
export default defineNuxtPlugin((nuxtApp) => {
  let navigationStart: number

  nuxtApp.hook('page:start', () => {
    navigationStart = performance.now()
  })

  nuxtApp.hook('page:finish', () => {
    const duration = performance.now() - navigationStart
    console.log(`Navigation took ${duration}ms`)
  })
})

Inject HTML

// server/plugins/inject.ts
export default defineNitroPlugin((nitroApp) => {
  nitroApp.hooks.hook('render:html', (html) => {
    html.head.push(`
      <script>
        window.APP_CONFIG = ${JSON.stringify(config)}
      </script>
    `)
  })
})