Module

Module Authors

Add your own modules integration to the Nuxt DevTools.

Nuxt DevTools is designed to be extensible. You can add your own modules integration to the DevTools.

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).

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 to the DevTools.

You can use the utility kit provided by Nuxt DevTools to register your custom tab:

import { addCustomTab } from '@nuxt/devtools-kit'

addCustomTab({
  // unique identifier
  name: 'my-module',
  // title to display in the tab
  title: 'My Module',
  // any icon from Iconify, or a URL to an image
  icon: 'carbon:apps',
  // iframe view
  view: {
    type: 'iframe',
    src: '/url-to-your-module-view',
  },
})

Or if you prefer to use Nuxt hooks:

nuxt.hook('devtools:customTabs', (tabs) => {
  tabs.push({
    // unique identifier
    name: 'my-module',
    // title to display in the tab
    title: 'My Module',
    // any icon from Iconify, or a URL to an image
    icon: 'carbon:apps',
    // iframe view
    view: {
      type: 'iframe',
      src: '/url-to-your-module-view',
    },
  })
})

Learn more about DevTools Utility Kit.

Lazy Service Launching

If the view you are contributing is heavy to load, you can have the tab first and let user launch it when they need it.

let isReady = false
const promise: Promise<any> | null = null

async function launchService() {
  // ...launch your service
  isReady = true
}

nuxt.hook('devtools:customTabs', (tabs) => {
  tabs.push({
    name: 'my-module',
    title: 'My Module',
    view: isReady
      ? {
          type: 'iframe',
          src: '/url-to-your-module-view',
        }
      : {
          type: 'launch',
          description: 'Launch My Module',
          actions: [{
            label: 'Start',
            async handle() {
              if (!promise)
                promise = launchService()
              await promise
            },
          }]
        },
  })
})

It will first display a launch page with a button to start the service. When user click the button, the handle() will be called, and the view will be updated to iframe.

When you need to refresh the custom tabs, you can call nuxt.callHook('devtools:customTabs:refresh') and the hooks on devtools:customTabs will be revaluated again.

API for Custom View

Please refer to Iframe Client.

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 your server code.

To do that, we recommend to define your types in a shared TypeScript file first:

// rpc-types.ts

export interface ServerFunctions {
  getMyModuleOptions: () => MyModuleOptions
}

export interface ClientFunctions {
  showNotification: (message: string) => void
}

And then in your module code:

import { defineNuxtModule } from '@nuxt/kit'
import { extendServerRpc, onDevToolsInitialized } from '@nuxt/devtools-kit'
import type { ClientFunctions, ServerFunctions } from './rpc-types'

const RPC_NAMESPACE = 'my-module-rpc'

export default defineNuxtModule({
  setup(options, nuxt) {
    // wait for DevTools to be initialized
    onDevToolsInitialized(async () => {
      const rpc = extendServerRpc<ClientFunctions, ServerFunctions>(RPC_NAMESPACE, {
        // register server RPC functions
        getMyModuleOptions() {
          return options
        },
      })

      // call client RPC functions
      // since it might have multiple clients connected, we use `broadcast` to call all of them
      await rpc.broadcast.showNotification('Hello from My Module!')
    })
  }
})

And on the client side, you can do:

import { onDevtoolsClientConnected } from '@nuxt/devtools-kit/iframe-client'
import type { ClientFunctions, ServerFunctions } from './rpc-types'

const RPC_NAMESPACE = 'my-module-rpc'

onDevtoolsClientConnected(async (client) => {
  const rpc = client.devtools.extendClientRpc(RPC_NAMESPACE, {
    showNotification(message) {
      console.log(message)
    },
  })

  // call server RPC functions
  const options = await rpc.getMyModuleOptions()
})

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: