0
# DevTools Kit Extensions
1
2
Developer toolkit for extending devtools with custom tabs, RPC functions, terminals, and initialization hooks for module authors and advanced users.
3
4
## Capabilities
5
6
### Custom Tab Management
7
8
Add custom tabs to the devtools interface for module-specific functionality.
9
10
```typescript { .api }
11
/**
12
* Add a custom tab to devtools interface
13
* Provide a function to pass a factory that can be updated dynamically
14
* @param tab - Tab configuration or factory function
15
* @param nuxt - Nuxt instance (optional, uses current context)
16
*/
17
function addCustomTab(
18
tab: ModuleCustomTab | (() => ModuleCustomTab | Promise<ModuleCustomTab>),
19
nuxt?: Nuxt
20
): void;
21
22
/**
23
* Retrigger update for custom tabs
24
* Causes 'devtools:customTabs' hook to be called again
25
* @param nuxt - Nuxt instance (optional)
26
*/
27
function refreshCustomTabs(nuxt?: Nuxt): Promise<void>;
28
```
29
30
**Usage Examples:**
31
32
```typescript
33
import { addCustomTab, refreshCustomTabs } from "@nuxt/devtools-kit";
34
35
// Static tab configuration
36
addCustomTab({
37
name: 'my-module',
38
title: 'My Module',
39
icon: 'carbon:apps',
40
view: {
41
type: 'iframe',
42
src: '/__my-module'
43
}
44
});
45
46
// Dynamic tab with factory function
47
addCustomTab(async () => {
48
const config = await getModuleConfig();
49
return {
50
name: 'dynamic-module',
51
title: config.displayName,
52
icon: config.icon,
53
view: {
54
type: 'iframe',
55
src: config.devUrl
56
}
57
};
58
});
59
60
// Refresh tabs after configuration change
61
refreshCustomTabs();
62
```
63
64
### Server RPC Extensions
65
66
Extend the devtools server with custom RPC functions for bidirectional communication.
67
68
```typescript { .api }
69
/**
70
* Extend server RPC with custom functions for devtools communication
71
* @param namespace - Unique namespace for RPC functions
72
* @param functions - Object containing server-side functions
73
* @param nuxt - Nuxt instance (optional)
74
* @returns BirpcGroup for client-server communication
75
*/
76
function extendServerRpc<ClientFunctions = Record<string, never>, ServerFunctions = Record<string, never>>(
77
namespace: string,
78
functions: ServerFunctions,
79
nuxt?: Nuxt
80
): BirpcGroup<ClientFunctions, ServerFunctions>;
81
```
82
83
**Usage Examples:**
84
85
```typescript
86
import { extendServerRpc } from "@nuxt/devtools-kit";
87
88
// Define server-side functions
89
const serverFunctions = {
90
async getModuleData() {
91
return await fetchModuleData();
92
},
93
94
async updateConfiguration(config: ModuleConfig) {
95
await saveConfiguration(config);
96
return { success: true };
97
},
98
99
async executeCommand(command: string) {
100
const result = await exec(command);
101
return result;
102
}
103
};
104
105
// Define client-side function types
106
interface ClientFunctions {
107
onConfigurationChanged(config: ModuleConfig): void;
108
onDataUpdated(data: any): void;
109
}
110
111
// Extend RPC with custom namespace
112
const rpc = extendServerRpc<ClientFunctions, typeof serverFunctions>(
113
'my-module',
114
serverFunctions
115
);
116
117
// Call client functions from server
118
rpc.onConfigurationChanged(newConfig);
119
120
// Client can call server functions via:
121
// rpc.getModuleData()
122
// rpc.updateConfiguration(config)
123
```
124
125
### Subprocess Management
126
127
Create and manage subprocesses that are handled by the devtools terminal interface.
128
129
```typescript { .api }
130
/**
131
* Create a subprocess that is managed by the DevTools terminal interface
132
* @param execaOptions - Command execution options
133
* @param tabOptions - Terminal tab configuration
134
* @param nuxt - Nuxt instance (optional)
135
* @returns Controller object for managing the subprocess
136
*/
137
function startSubprocess(
138
execaOptions: SubprocessOptions,
139
tabOptions: TerminalState,
140
nuxt?: Nuxt
141
): SubprocessController;
142
143
interface SubprocessController {
144
/** Get the current process instance */
145
getProcess: () => ExecaChildProcess<string>;
146
/** Terminate the subprocess */
147
terminate: () => void;
148
/** Restart the subprocess */
149
restart: () => void;
150
/** Clear terminal output buffer */
151
clear: () => void;
152
}
153
```
154
155
**Usage Examples:**
156
157
```typescript
158
import { startSubprocess } from "@nuxt/devtools-kit";
159
160
// Start a build watcher
161
const buildWatcher = startSubprocess(
162
{
163
command: 'npm',
164
args: ['run', 'build:watch'],
165
cwd: process.cwd(),
166
env: { NODE_ENV: 'development' }
167
},
168
{
169
id: 'build-watcher',
170
name: 'Build Watcher',
171
description: 'Watches and rebuilds on file changes',
172
icon: 'carbon:build-tool',
173
restartable: true,
174
terminatable: true
175
}
176
);
177
178
// Start a test runner
179
const testRunner = startSubprocess(
180
{
181
command: 'vitest',
182
args: ['--watch', '--reporter=verbose']
183
},
184
{
185
id: 'test-runner',
186
name: 'Test Runner',
187
description: 'Continuous test execution',
188
icon: 'carbon:test-tool',
189
restartable: true,
190
terminatable: false // Prevent accidental termination
191
}
192
);
193
194
// Control subprocess
195
buildWatcher.restart();
196
testRunner.clear();
197
buildWatcher.terminate();
198
```
199
200
### DevTools Initialization Hook
201
202
Hook into devtools initialization for setup and configuration.
203
204
```typescript { .api }
205
/**
206
* Register callback for when DevTools is initialized
207
* @param fn - Callback function receiving initialization info
208
* @param nuxt - Nuxt instance (optional)
209
*/
210
function onDevToolsInitialized(
211
fn: (info: NuxtDevtoolsInfo) => void,
212
nuxt?: Nuxt
213
): void;
214
```
215
216
**Usage Examples:**
217
218
```typescript
219
import { onDevToolsInitialized } from "@nuxt/devtools-kit";
220
221
onDevToolsInitialized((info) => {
222
console.log(`DevTools v${info.version} initialized`);
223
console.log(`Package path: ${info.packagePath}`);
224
console.log(`Time metrics enabled: ${info.timeMetrics}`);
225
226
// Setup module-specific devtools integration
227
setupCustomIntegration(info);
228
});
229
230
// Advanced initialization with module configuration
231
onDevToolsInitialized((info) => {
232
if (info.timeMetrics) {
233
enablePerformanceTracking();
234
}
235
236
// Register custom hooks based on devtools capabilities
237
registerCustomHooks(info.version);
238
});
239
```
240
241
### Type Definitions
242
243
Core interfaces for devtools extensions.
244
245
```typescript { .api }
246
interface ModuleCustomTab {
247
/** The name of the tab, must be unique */
248
name: string;
249
/** Icon of the tab, support any Iconify icons, or a url to an image */
250
icon?: string;
251
/** Title of the tab */
252
title: string;
253
/** Main view of the tab */
254
view: ModuleView;
255
/** Category of the tab (default: 'app') */
256
category?: TabCategory;
257
/** Insert static vnode to the tab entry (advanced option) */
258
extraTabVNode?: VNode;
259
/** Require local authentication to access the tab (default: false) */
260
requireAuth?: boolean;
261
}
262
263
interface ModuleIframeView {
264
/** Iframe view */
265
type: 'iframe';
266
/** Url of the iframe */
267
src: string;
268
/** Persist the iframe instance even if the tab is not active (default: true) */
269
persistent?: boolean;
270
}
271
272
interface ModuleLaunchView {
273
/** A view for module to lazy launch some actions */
274
type: 'launch';
275
title?: string;
276
icon?: string;
277
description: string;
278
/** Action buttons */
279
actions: ModuleLaunchAction[];
280
}
281
282
interface ModuleVNodeView {
283
/** Vue's VNode view */
284
type: 'vnode';
285
/** Send vnode to the client, they must be static and serializable */
286
vnode: VNode;
287
}
288
289
type ModuleView = ModuleIframeView | ModuleLaunchView | ModuleVNodeView;
290
291
interface ModuleLaunchAction {
292
/** Label of the action button */
293
label: string;
294
/** Additional HTML attributes to the action button */
295
attrs?: Record<string, string>;
296
/** Indicate if the action is pending, will show a loading indicator and disable the button */
297
pending?: boolean;
298
/** Function to handle the action, this is executed on the server side */
299
handle?: () => void | Promise<void>;
300
/** Treat the action as a link, will open the link in a new tab */
301
src?: string;
302
}
303
304
type TabCategory = 'pinned' | 'app' | 'vue-devtools' | 'analyze' | 'server' | 'modules' | 'documentation' | 'advanced';
305
306
interface TerminalState {
307
/** Unique identifier for terminal */
308
id: string;
309
/** Display name in terminal tab */
310
name: string;
311
/** Optional description */
312
description?: string;
313
/** Icon for terminal tab */
314
icon?: string;
315
/** Allow restart action */
316
restartable?: boolean;
317
/** Allow terminate action */
318
terminatable?: boolean;
319
/** Current terminal output buffer */
320
buffer?: string;
321
}
322
323
interface SubprocessOptions {
324
/** Command to execute */
325
command: string;
326
/** Command arguments */
327
args?: string[];
328
/** Working directory */
329
cwd?: string;
330
/** Environment variables */
331
env?: Record<string, string>;
332
/** Additional execa options */
333
[key: string]: any;
334
}
335
336
interface NuxtDevtoolsInfo {
337
/** DevTools version */
338
version: string;
339
/** Path to devtools package */
340
packagePath: string;
341
/** Whether time metrics are enabled */
342
timeMetrics: boolean;
343
}
344
345
interface BirpcGroup<ClientFunctions, ServerFunctions> {
346
/** Call server function from client */
347
[K in keyof ServerFunctions]: ServerFunctions[K];
348
} & {
349
/** Call client function from server */
350
[K in keyof ClientFunctions]: ClientFunctions[K];
351
}
352
```
353
354
### Nuxt Hooks Integration
355
356
The devtools kit integrates with Nuxt's hook system:
357
358
```typescript
359
// Available hooks for devtools integration
360
nuxt.hook('devtools:customTabs', (tabs: ModuleCustomTab[]) => {
361
// Called when custom tabs are collected
362
});
363
364
nuxt.hook('devtools:customTabs:refresh', () => {
365
// Called when tabs need to be refreshed
366
});
367
368
nuxt.hook('devtools:initialized', (info: NuxtDevtoolsInfo) => {
369
// Called when devtools is fully initialized
370
});
371
372
nuxt.hook('devtools:terminal:write', ({ id, data }: { id: string, data: string }) => {
373
// Called when terminal output is written
374
});
375
376
nuxt.hook('devtools:terminal:exit', ({ id, code }: { id: string, code: number }) => {
377
// Called when terminal process exits
378
});
379
380
nuxt.hook('devtools:terminal:register', (terminal: TerminalState) => {
381
// Called when terminal is registered
382
});
383
384
nuxt.hook('devtools:terminal:remove', ({ id }: { id: string }) => {
385
// Called when terminal is removed
386
});
387
```