Module Authors
Nuxt DevTools is designed to be extensible. You can add your own modules integration to the DevTools.
Nuxt DevTools v4 is built on Vite DevTools: your module registers dock entries (tabs), RPC functions and terminals on the same hosts every other Vite tool uses, from one hook, onDevtoolsReady(). If your module still uses the v3 API (addCustomTab, extendServerRpc, …), see the migration guide.
Starter Template
If you want to try integrating with Nuxt DevTools, you can run
npx nuxi init my-module -t module-devtools
to create a new module starter with Nuxt DevTools integration pre-configured (contributing a fully custom view as a tab). The module-starter playground in the DevTools repo is the same setup on the v4 API.
Contributing to View
Currently the only way to contribute to Nuxt DevTools View is via iframe. You need to serve your module's view yourself and then register it as a dock entry in the Nuxt group:
import { NUXT_DEVTOOLS_GROUP_ID, onDevtoolsReady } from '@nuxt/devtools-kit'
onDevtoolsReady((ctx) => {
ctx.docks.register({
// unique identifier
id: 'my-module',
// title to display in the dock
title: 'My Module',
// any icon from Iconify, or a URL to an image
icon: 'carbon:apps',
// iframe view
type: 'iframe',
url: '/url-to-your-module-view',
// show it inside the `Nuxt` group, next to the built-in tabs
groupId: NUXT_DEVTOOLS_GROUP_ID,
})
})
Set category (app, analyze, server, modules, documentation, advanced) to choose the section of the Nuxt group the entry appears in, or omit groupId to register a top-level dock next to Vue DevTools and Vite Inspect.
register() returns a handle to patch the entry later, for example to show a badge:
onDevtoolsReady((ctx) => {
const entry = ctx.docks.register({ id: 'my-module', /* ... */ })
entry.update({ badge: '3' })
})
Learn more about DevTools Utility Kit.
Lazy Service Launching
If the view you are contributing is heavy to load, register a launcher entry first and swap it for the iframe once the user starts it. Re-registering the same id with true as the second argument replaces the entry:
let promise: Promise<void> | undefined
onDevtoolsReady((ctx) => {
ctx.docks.register({
id: 'my-module',
title: 'My Module',
icon: 'carbon:apps',
type: 'launcher',
groupId: NUXT_DEVTOOLS_GROUP_ID,
launcher: {
title: 'Start My Module',
description: 'Starts the inspector server on demand.',
async onLaunch() {
promise ||= launchService()
await promise
ctx.docks.register({
id: 'my-module',
title: 'My Module',
icon: 'carbon:apps',
type: 'iframe',
url: '/url-to-your-module-view',
groupId: NUXT_DEVTOOLS_GROUP_ID,
}, true)
},
},
})
})
It will first display a launch page with a button to start the service. When the user clicks the button, onLaunch() is called, and the entry becomes the iframe.
Custom RPC Functions
Nuxt DevTools uses Remote Procedure Call (RPC) to communicate between the server and client. For modules you can also leverage that to communicate with your server code.
Scope the RPC host to your module so every function and event name is prefixed with your namespace (my-module: below) without repeating it:
import { onDevtoolsReady } from '@nuxt/devtools-kit'
import { defineNuxtModule } from '@nuxt/kit'
export default defineNuxtModule({
setup(options, nuxt) {
onDevtoolsReady((ctx) => {
const { rpc } = ctx.scope('my-module')
// register server RPC functions
rpc.register({
name: 'get-options',
type: 'query',
handler() {
return options
},
})
// call client RPC functions when something changes; `broadcast` reaches
// every connected client (none are connected yet when this hook runs)
nuxt.hook('builder:watch', (_event, path) => {
rpc.broadcast({ method: 'show-notification', args: [`${path} changed`], event: true })
})
})
},
})
type is 'query' for reads, 'action' for mutations, 'event' for fire-and-forget and 'static' for values that never change.
And on the embedded iframe client side, connect to Vite DevTools and use the same scope:
import { getDevToolsRpcClient } from '@vitejs/devtools-kit/client'
const kit = await getDevToolsRpcClient()
const { rpc } = kit.scope('my-module')
// register client RPC functions
rpc.register({
name: 'show-notification',
type: 'event',
handler(message: string) {
console.log(message)
},
})
// call server RPC functions
const options = await rpc.call('get-options')
See the iframe client section for how to reach the user's app from your iframe.
Trying Local Changes
You can clone Nuxt DevTools repo and try your changes locally.
Please refer to Trying Local Changes.
Examples
Here are a few examples of how to integrate Nuxt DevTools in modules: