[{"data":1,"prerenderedAt":1272},["ShallowReactive",2],{"navigation":3,"docs-/module/utils-kit":37,"docs-/module/utils-kit-surround":600},[4,17,30],{"title":5,"_path":6,"children":7},"Guide","/guide",[8,11,14],{"title":9,"_path":10},"Getting Started","/guide/getting-started",{"title":12,"_path":13},"Features","/guide/features",{"title":15,"_path":16},"Composables","/guide/composables",{"title":18,"_path":19,"children":20},"Module","/module",[21,24,27],{"title":22,"_path":23},"Module Authors","/module/guide",{"title":25,"_path":26},"Utility Kit","/module/utils-kit",{"title":28,"_path":29},"UI Kit","/module/ui-kit",{"title":31,"_path":32,"children":33},"Development","/development",[34],{"title":35,"_path":36},"Contribution Guide","/development/contributing",{"_path":26,"_dir":38,"_draft":39,"_partial":39,"_locale":40,"title":25,"description":41,"body":42,"_type":594,"_id":595,"_source":596,"_file":597,"_stem":598,"_extension":599},"module",false,"","Utility kit for easier DevTools integrations.",{"type":43,"children":44,"toc":576},"root",[45,62,74,84,105,115,126,138,146,151,212,220,230,243,253,266,274,282,292,297,305,318,328,333,338,346,367,376,397,407,432,442,447,455,465,477,485,495,507,517,535,543,553,563,571],{"type":46,"tag":47,"props":48,"children":49},"element","p",{},[50,53,60],{"type":51,"value":52},"text","Since v0.3.0, we are now providing a utility kit for easier DevTools integrations, similar to ",{"type":46,"tag":54,"props":55,"children":57},"code",{"className":56},[],[58],{"type":51,"value":59},"@nuxt/kit",{"type":51,"value":61},".",{"type":46,"tag":63,"props":64,"children":69},"pre",{"className":65,"code":66,"language":67,"meta":40,"style":68},"language-bash","npm i @nuxt/devtools-kit\n","bash","undefined",[70],{"type":46,"tag":54,"props":71,"children":72},{"__ignoreMap":40},[73],{"type":51,"value":66},{"type":46,"tag":63,"props":75,"children":79},{"className":76,"code":77,"language":78,"meta":40,"style":68},"language-ts","import { addCustomTab } from '@nuxt/devtools-kit'\n","ts",[80],{"type":46,"tag":54,"props":81,"children":82},{"__ignoreMap":40},[83],{"type":51,"value":77},{"type":46,"tag":47,"props":85,"children":86},{},[87,89,95,97,103],{"type":51,"value":88},"We recommend module authors to install ",{"type":46,"tag":54,"props":90,"children":92},{"className":91},[],[93],{"type":51,"value":94},"@nuxt/devtools-kit",{"type":51,"value":96}," as a dependency and ",{"type":46,"tag":54,"props":98,"children":100},{"className":99},[],[101],{"type":51,"value":102},"@nuxt/devtools",{"type":51,"value":104}," as a dev dependency.",{"type":46,"tag":106,"props":107,"children":109},"h2",{"id":108},"nuxtdevtools-kit",[110],{"type":46,"tag":54,"props":111,"children":113},{"className":112},[],[114],{"type":51,"value":94},{"type":46,"tag":116,"props":117,"children":119},"h3",{"id":118},"addcustomtab",[120],{"type":46,"tag":54,"props":121,"children":123},{"className":122},[],[124],{"type":51,"value":125},"addCustomTab()",{"type":46,"tag":47,"props":127,"children":128},{},[129,131,137],{"type":51,"value":130},"A shorthand for calling the hook ",{"type":46,"tag":54,"props":132,"children":134},{"className":133},[],[135],{"type":51,"value":136},"devtools:customTabs",{"type":51,"value":61},{"type":46,"tag":63,"props":139,"children":141},{"className":76,"code":140,"language":78,"meta":40,"style":68},"import { addCustomTab } from '@nuxt/devtools-kit'\n\naddCustomTab(() => ({\n  // unique identifier\n  name: 'my-module',\n  // title to display in the tab\n  title: 'My Module',\n  // any icon from Iconify, or a URL to an image\n  icon: 'carbon:apps',\n  // iframe view\n  view: {\n    type: 'iframe',\n    src: '/url-to-your-module-view',\n  },\n}))\n",[142],{"type":46,"tag":54,"props":143,"children":144},{"__ignoreMap":40},[145],{"type":51,"value":140},{"type":46,"tag":47,"props":147,"children":148},{},[149],{"type":51,"value":150},"The iframe view supports the following options:",{"type":46,"tag":152,"props":153,"children":154},"ul",{},[155,167,186],{"type":46,"tag":156,"props":157,"children":158},"li",{},[159,165],{"type":46,"tag":54,"props":160,"children":162},{"className":161},[],[163],{"type":51,"value":164},"src",{"type":51,"value":166},": URL of the iframe",{"type":46,"tag":156,"props":168,"children":169},{},[170,176,178,184],{"type":46,"tag":54,"props":171,"children":173},{"className":172},[],[174],{"type":51,"value":175},"persistent",{"type":51,"value":177},": Whether to persist the iframe instance when switching tabs (default: ",{"type":46,"tag":54,"props":179,"children":181},{"className":180},[],[182],{"type":51,"value":183},"true",{"type":51,"value":185},")",{"type":46,"tag":156,"props":187,"children":188},{},[189,195,197,203,205,211],{"type":46,"tag":54,"props":190,"children":192},{"className":191},[],[193],{"type":51,"value":194},"permissions",{"type":51,"value":196},": Additional permissions to allow in the iframe (merged with default ",{"type":46,"tag":54,"props":198,"children":200},{"className":199},[],[201],{"type":51,"value":202},"clipboard-write",{"type":51,"value":204}," and ",{"type":46,"tag":54,"props":206,"children":208},{"className":207},[],[209],{"type":51,"value":210},"clipboard-read",{"type":51,"value":185},{"type":46,"tag":63,"props":213,"children":215},{"className":76,"code":214,"language":78,"meta":40,"style":68},"const view: ModuleIframeView = {\n  type: 'iframe',\n  src: '/url-to-your-module-view',\n  persistent: true,\n  permissions: ['camera', 'microphone'],\n}\n",[216],{"type":46,"tag":54,"props":217,"children":218},{"__ignoreMap":40},[219],{"type":51,"value":214},{"type":46,"tag":116,"props":221,"children":223},{"id":222},"refreshcustomtabs",[224],{"type":46,"tag":54,"props":225,"children":227},{"className":226},[],[228],{"type":51,"value":229},"refreshCustomTabs()",{"type":46,"tag":47,"props":231,"children":232},{},[233,235,241],{"type":51,"value":234},"A shorthand for call hook ",{"type":46,"tag":54,"props":236,"children":238},{"className":237},[],[239],{"type":51,"value":240},"devtools:customTabs:refresh",{"type":51,"value":242},". It will refresh all custom tabs.",{"type":46,"tag":116,"props":244,"children":246},{"id":245},"startsubprocess",[247],{"type":46,"tag":54,"props":248,"children":250},{"className":249},[],[251],{"type":51,"value":252},"startSubprocess()",{"type":46,"tag":47,"props":254,"children":255},{},[256,258,264],{"type":51,"value":257},"Start a sub process using ",{"type":46,"tag":54,"props":259,"children":261},{"className":260},[],[262],{"type":51,"value":263},"execa",{"type":51,"value":265}," and create a terminal tab in DevTools.",{"type":46,"tag":63,"props":267,"children":269},{"className":76,"code":268,"language":78,"meta":40,"style":68},"import { startSubprocess } from '@nuxt/devtools-kit'\n\nconst subprocess = startSubprocess(\n  {\n    command: 'code-server',\n    args: [\n      'serve-local',\n      '--accept-server-license-terms',\n      '--without-connection-token',\n      `--port=${port}`,\n    ],\n  },\n  {\n    id: 'devtools:vscode',\n    name: 'VS Code Server',\n    icon: 'logos-visual-studio-code',\n  },\n)\n",[270],{"type":46,"tag":54,"props":271,"children":272},{"__ignoreMap":40},[273],{"type":51,"value":268},{"type":46,"tag":63,"props":275,"children":277},{"className":76,"code":276,"language":78,"meta":40,"style":68},"subprocess.restart()\nsubprocess.terminate()\n",[278],{"type":46,"tag":54,"props":279,"children":280},{"__ignoreMap":40},[281],{"type":51,"value":276},{"type":46,"tag":116,"props":283,"children":285},{"id":284},"extendserverrpc",[286],{"type":46,"tag":54,"props":287,"children":289},{"className":288},[],[290],{"type":51,"value":291},"extendServerRpc()",{"type":46,"tag":47,"props":293,"children":294},{},[295],{"type":51,"value":296},"Extend the server RPC with your own methods.",{"type":46,"tag":63,"props":298,"children":300},{"className":76,"code":299,"language":78,"meta":40,"style":68},"import { extendServerRpc } from '@nuxt/devtools-kit'\n\nconst rpc = extendServerRpc('my-module', {\n  async myMethod() {\n    return 'hello'\n  },\n})\n",[301],{"type":46,"tag":54,"props":302,"children":303},{"__ignoreMap":40},[304],{"type":51,"value":299},{"type":46,"tag":47,"props":306,"children":307},{},[308,310,317],{"type":51,"value":309},"Learn more about ",{"type":46,"tag":311,"props":312,"children":314},"a",{"href":313},"/module/guide#custom-rpc-functions",[315],{"type":51,"value":316},"Custom RPC functions",{"type":51,"value":61},{"type":46,"tag":106,"props":319,"children":321},{"id":320},"nuxtdevtools-kitiframe-client",[322],{"type":46,"tag":54,"props":323,"children":325},{"className":324},[],[326],{"type":51,"value":327},"@nuxt/devtools-kit/iframe-client",{"type":46,"tag":47,"props":329,"children":330},{},[331],{"type":51,"value":332},"To provide complex interactions for your module integrations, we recommend to host your own view and display it in devtools via iframe.",{"type":46,"tag":47,"props":334,"children":335},{},[336],{"type":51,"value":337},"To get the infomation from the devtools and the client app, you can do this in your client app:",{"type":46,"tag":63,"props":339,"children":341},{"className":76,"code":340,"language":78,"meta":40,"style":68},"import { useDevtoolsClient } from '@nuxt/devtools-kit/iframe-client'\n\nexport const devtoolsClient = useDevtoolsClient()\n",[342],{"type":46,"tag":54,"props":343,"children":344},{"__ignoreMap":40},[345],{"type":51,"value":340},{"type":46,"tag":47,"props":347,"children":348},{},[349,351,357,359,365],{"type":51,"value":350},"When the iframe been served with the same origin (CORS limitation), devtools will automatically inject ",{"type":46,"tag":54,"props":352,"children":354},{"className":353},[],[355],{"type":51,"value":356},"__NUXT_DEVTOOLS__",{"type":51,"value":358}," to the iframe's window object. You can access it as a ref using ",{"type":46,"tag":54,"props":360,"children":362},{"className":361},[],[363],{"type":51,"value":364},"useDevtoolsClient()",{"type":51,"value":366}," utility.",{"type":46,"tag":116,"props":368,"children":370},{"id":369},"usedevtoolsclient",[371],{"type":46,"tag":54,"props":372,"children":374},{"className":373},[],[375],{"type":51,"value":364},{"type":46,"tag":47,"props":377,"children":378},{},[379,381,387,389,395],{"type":51,"value":380},"It will return a ref of ",{"type":46,"tag":54,"props":382,"children":384},{"className":383},[],[385],{"type":51,"value":386},"NuxtDevtoolsIframeClient",{"type":51,"value":388}," object that are intially ",{"type":46,"tag":54,"props":390,"children":392},{"className":391},[],[393],{"type":51,"value":394},"null",{"type":51,"value":396}," and will be updated when the connection is ready.",{"type":46,"tag":47,"props":398,"children":399},{},[400,405],{"type":46,"tag":54,"props":401,"children":403},{"className":402},[],[404],{"type":51,"value":386},{"type":51,"value":406}," contains two properties:",{"type":46,"tag":152,"props":408,"children":409},{},[410,421],{"type":46,"tag":156,"props":411,"children":412},{},[413,419],{"type":46,"tag":54,"props":414,"children":416},{"className":415},[],[417],{"type":51,"value":418},"host",{"type":51,"value":420},": APIs to communicate with the main app in browser",{"type":46,"tag":156,"props":422,"children":423},{},[424,430],{"type":46,"tag":54,"props":425,"children":427},{"className":426},[],[428],{"type":51,"value":429},"devtools",{"type":51,"value":431},": APIs to communicate with the devtools",{"type":46,"tag":47,"props":433,"children":434},{},[435,440],{"type":46,"tag":54,"props":436,"children":438},{"className":437},[],[439],{"type":51,"value":418},{"type":51,"value":441}," can be undefined when devtools are accessed standalone or from a different origin.",{"type":46,"tag":47,"props":443,"children":444},{},[445],{"type":51,"value":446},"For example, you can get the router instance from the client app:",{"type":46,"tag":63,"props":448,"children":450},{"className":76,"code":449,"language":78,"meta":40,"style":68},"const router = computed(() => devtoolsClient.value?.host?.nuxt.vueApp.config.globalProperties?.$router)\n",[451],{"type":46,"tag":54,"props":452,"children":453},{"__ignoreMap":40},[454],{"type":51,"value":449},{"type":46,"tag":116,"props":456,"children":458},{"id":457},"ondevtoolsclientconnected",[459],{"type":46,"tag":54,"props":460,"children":462},{"className":461},[],[463],{"type":51,"value":464},"onDevtoolsClientConnected()",{"type":46,"tag":47,"props":466,"children":467},{},[468,470,475],{"type":51,"value":469},"Similiar to ",{"type":46,"tag":54,"props":471,"children":473},{"className":472},[],[474],{"type":51,"value":364},{"type":51,"value":476}," but as a callback style:",{"type":46,"tag":63,"props":478,"children":480},{"className":76,"code":479,"language":78,"meta":40,"style":68},"import { onDevtoolsClientConnected } from '@nuxt/devtools-kit/iframe-client'\n\nonDevtoolsClientConnected(async (client) => {\n  // client is NuxtDevtoolsIframeClient\n\n  const config = client.devtools.rpc.getServerConfig()\n  // ...\n})\n",[481],{"type":46,"tag":54,"props":482,"children":483},{"__ignoreMap":40},[484],{"type":51,"value":479},{"type":46,"tag":106,"props":486,"children":488},{"id":487},"nuxtdevtools-kithost-client",[489],{"type":46,"tag":54,"props":490,"children":492},{"className":491},[],[493],{"type":51,"value":494},"@nuxt/devtools-kit/host-client",{"type":46,"tag":47,"props":496,"children":497},{},[498,500,505],{"type":51,"value":499},"When you have iframe for your devtools view, sometimes you need to communicate with the devtools host (the main app in browser) with a runtime plugin. You can use ",{"type":46,"tag":54,"props":501,"children":503},{"className":502},[],[504],{"type":51,"value":494},{"type":51,"value":506}," to do that.",{"type":46,"tag":116,"props":508,"children":510},{"id":509},"usedevtoolshostclient",[511],{"type":46,"tag":54,"props":512,"children":514},{"className":513},[],[515],{"type":51,"value":516},"useDevtoolsHostClient()",{"type":46,"tag":47,"props":518,"children":519},{},[520,521,527,528,533],{"type":51,"value":380},{"type":46,"tag":54,"props":522,"children":524},{"className":523},[],[525],{"type":51,"value":526},"NuxtDevtoolsHostClient",{"type":51,"value":388},{"type":46,"tag":54,"props":529,"children":531},{"className":530},[],[532],{"type":51,"value":394},{"type":51,"value":534}," and will be updated when the host is initialized by NuxtDevtools.",{"type":46,"tag":63,"props":536,"children":538},{"className":76,"code":537,"language":78,"meta":40,"style":68},"import { useDevtoolsHostClient } from '@nuxt/devtools-kit/host-client'\n\nexport default defineNuxtPlugin({\n  name: 'my-module:devtools',\n  setup(nuxtApp) {\n    const devtoolsHost = useDevtoolsHostClient()\n\n    // ...\n  }\n})\n",[539],{"type":46,"tag":54,"props":540,"children":541},{"__ignoreMap":40},[542],{"type":51,"value":537},{"type":46,"tag":116,"props":544,"children":546},{"id":545},"ondevtoolshostclientconnected",[547],{"type":46,"tag":54,"props":548,"children":550},{"className":549},[],[551],{"type":51,"value":552},"onDevtoolsHostClientConnected()",{"type":46,"tag":47,"props":554,"children":555},{},[556,557,562],{"type":51,"value":469},{"type":46,"tag":54,"props":558,"children":560},{"className":559},[],[561],{"type":51,"value":516},{"type":51,"value":476},{"type":46,"tag":63,"props":564,"children":566},{"className":76,"code":565,"language":78,"meta":40,"style":68},"import { onDevtoolsHostClientConnected } from '@nuxt/devtools-kit/host-client'\n\nonDevtoolsHostClientConnected(async (host) => {\n\n})\n",[567],{"type":46,"tag":54,"props":568,"children":569},{"__ignoreMap":40},[570],{"type":51,"value":565},{"type":46,"tag":572,"props":573,"children":574},"style",{},[575],{"type":51,"value":40},{"title":40,"searchDepth":577,"depth":577,"links":578},2,[579,586,590],{"id":108,"depth":577,"text":94,"children":580},[581,583,584,585],{"id":118,"depth":582,"text":125},3,{"id":222,"depth":582,"text":229},{"id":245,"depth":582,"text":252},{"id":284,"depth":582,"text":291},{"id":320,"depth":577,"text":327,"children":587},[588,589],{"id":369,"depth":582,"text":364},{"id":457,"depth":582,"text":464},{"id":487,"depth":577,"text":494,"children":591},[592,593],{"id":509,"depth":582,"text":516},{"id":545,"depth":582,"text":552},"markdown","content:2.module:1.utils-kit.md","content","2.module/1.utils-kit.md","2.module/1.utils-kit","md",[601,967],{"_path":23,"_dir":38,"_draft":39,"_partial":39,"_locale":40,"title":22,"description":602,"body":603,"_type":594,"_id":964,"_source":596,"_file":965,"_stem":966,"_extension":599},"Add your own modules integration to the Nuxt DevTools.",{"type":43,"children":604,"toc":953},[605,610,616,621,629,634,640,645,650,658,663,671,677,702,710,723,733,739,744,752,765,785,791,803,809,814,819,827,832,840,845,853,859,864,874,880,885,949],{"type":46,"tag":47,"props":606,"children":607},{},[608],{"type":51,"value":609},"Nuxt DevTools is designed to be extensible. You can add your own modules integration to the DevTools.",{"type":46,"tag":106,"props":611,"children":613},{"id":612},"starter-template",[614],{"type":51,"value":615},"Starter Template",{"type":46,"tag":47,"props":617,"children":618},{},[619],{"type":51,"value":620},"If you want to try integrating with Nuxt DevTools, you can run",{"type":46,"tag":63,"props":622,"children":624},{"className":65,"code":623,"language":67,"meta":40,"style":68},"npx nuxi init my-module -t module-devtools\n",[625],{"type":46,"tag":54,"props":626,"children":627},{"__ignoreMap":40},[628],{"type":51,"value":623},{"type":46,"tag":47,"props":630,"children":631},{},[632],{"type":51,"value":633},"to create a new module starter with Nuxt DevTools integration pre-configured (contributing a fully custom view as a tab).",{"type":46,"tag":106,"props":635,"children":637},{"id":636},"contributing-to-view",[638],{"type":51,"value":639},"Contributing to View",{"type":46,"tag":47,"props":641,"children":642},{},[643],{"type":51,"value":644},"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.",{"type":46,"tag":47,"props":646,"children":647},{},[648],{"type":51,"value":649},"You can use the utility kit provided by Nuxt DevTools to register your custom tab:",{"type":46,"tag":63,"props":651,"children":653},{"className":76,"code":652,"language":78,"meta":40,"style":68},"import { addCustomTab } from '@nuxt/devtools-kit'\n\naddCustomTab({\n  // unique identifier\n  name: 'my-module',\n  // title to display in the tab\n  title: 'My Module',\n  // any icon from Iconify, or a URL to an image\n  icon: 'carbon:apps',\n  // iframe view\n  view: {\n    type: 'iframe',\n    src: '/url-to-your-module-view',\n  },\n})\n",[654],{"type":46,"tag":54,"props":655,"children":656},{"__ignoreMap":40},[657],{"type":51,"value":652},{"type":46,"tag":47,"props":659,"children":660},{},[661],{"type":51,"value":662},"Or if you prefer to use Nuxt hooks:",{"type":46,"tag":63,"props":664,"children":666},{"className":76,"code":665,"language":78,"meta":40,"style":68},"nuxt.hook('devtools:customTabs', (tabs) => {\n  tabs.push({\n    // unique identifier\n    name: 'my-module',\n    // title to display in the tab\n    title: 'My Module',\n    // any icon from Iconify, or a URL to an image\n    icon: 'carbon:apps',\n    // iframe view\n    view: {\n      type: 'iframe',\n      src: '/url-to-your-module-view',\n    },\n  })\n})\n",[667],{"type":46,"tag":54,"props":668,"children":669},{"__ignoreMap":40},[670],{"type":51,"value":665},{"type":46,"tag":116,"props":672,"children":674},{"id":673},"iframe-permissions",[675],{"type":51,"value":676},"Iframe Permissions",{"type":46,"tag":47,"props":678,"children":679},{},[680,682,687,688,693,695,700],{"type":51,"value":681},"By default, iframes have ",{"type":46,"tag":54,"props":683,"children":685},{"className":684},[],[686],{"type":51,"value":202},{"type":51,"value":204},{"type":46,"tag":54,"props":689,"children":691},{"className":690},[],[692],{"type":51,"value":210},{"type":51,"value":694}," permissions enabled. You can add additional permissions using the ",{"type":46,"tag":54,"props":696,"children":698},{"className":697},[],[699],{"type":51,"value":194},{"type":51,"value":701}," option:",{"type":46,"tag":63,"props":703,"children":705},{"className":76,"code":704,"language":78,"meta":40,"style":68},"const view: ModuleIframeView = {\n  type: 'iframe',\n  src: '/url-to-your-module-view',\n  // Additional permissions to allow in the iframe\n  permissions: ['camera', 'microphone', 'geolocation'],\n}\n",[706],{"type":46,"tag":54,"props":707,"children":708},{"__ignoreMap":40},[709],{"type":51,"value":704},{"type":46,"tag":47,"props":711,"children":712},{},[713,715,721],{"type":51,"value":714},"These permissions will be merged with the default ones and set on the iframe's ",{"type":46,"tag":54,"props":716,"children":718},{"className":717},[],[719],{"type":51,"value":720},"allow",{"type":51,"value":722}," attribute.",{"type":46,"tag":47,"props":724,"children":725},{},[726,727,732],{"type":51,"value":309},{"type":46,"tag":311,"props":728,"children":729},{"href":26},[730],{"type":51,"value":731},"DevTools Utility Kit",{"type":51,"value":61},{"type":46,"tag":106,"props":734,"children":736},{"id":735},"lazy-service-launching",[737],{"type":51,"value":738},"Lazy Service Launching",{"type":46,"tag":47,"props":740,"children":741},{},[742],{"type":51,"value":743},"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.",{"type":46,"tag":63,"props":745,"children":747},{"className":76,"code":746,"language":78,"meta":40,"style":68},"let isReady = false\nconst promise: Promise\u003Cany> | null = null\n\nasync function launchService() {\n  // ...launch your service\n  isReady = true\n}\n\nnuxt.hook('devtools:customTabs', (tabs) => {\n  tabs.push({\n    name: 'my-module',\n    title: 'My Module',\n    view: isReady\n      ? {\n          type: 'iframe',\n          src: '/url-to-your-module-view',\n        }\n      : {\n          type: 'launch',\n          description: 'Launch My Module',\n          actions: [{\n            label: 'Start',\n            async handle() {\n              if (!promise)\n                promise = launchService()\n              await promise\n            },\n          }]\n        },\n  })\n})\n",[748],{"type":46,"tag":54,"props":749,"children":750},{"__ignoreMap":40},[751],{"type":51,"value":746},{"type":46,"tag":47,"props":753,"children":754},{},[755,757,763],{"type":51,"value":756},"It will first display a launch page with a button to start the service. When user click the button, the ",{"type":46,"tag":54,"props":758,"children":760},{"className":759},[],[761],{"type":51,"value":762},"handle()",{"type":51,"value":764}," will be called, and the view will be updated to iframe.",{"type":46,"tag":47,"props":766,"children":767},{},[768,770,776,778,783],{"type":51,"value":769},"When you need to refresh the custom tabs, you can call ",{"type":46,"tag":54,"props":771,"children":773},{"className":772},[],[774],{"type":51,"value":775},"nuxt.callHook('devtools:customTabs:refresh')",{"type":51,"value":777}," and the hooks on ",{"type":46,"tag":54,"props":779,"children":781},{"className":780},[],[782],{"type":51,"value":136},{"type":51,"value":784}," will be revaluated again.",{"type":46,"tag":106,"props":786,"children":788},{"id":787},"api-for-custom-view",[789],{"type":51,"value":790},"API for Custom View",{"type":46,"tag":47,"props":792,"children":793},{},[794,796,802],{"type":51,"value":795},"Please refer to ",{"type":46,"tag":311,"props":797,"children":799},{"href":798},"/module/utils-kit#nuxtdevtools-kitiframe-client",[800],{"type":51,"value":801},"Iframe Client",{"type":51,"value":61},{"type":46,"tag":106,"props":804,"children":806},{"id":805},"custom-rpc-functions",[807],{"type":51,"value":808},"Custom RPC Functions",{"type":46,"tag":47,"props":810,"children":811},{},[812],{"type":51,"value":813},"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.",{"type":46,"tag":47,"props":815,"children":816},{},[817],{"type":51,"value":818},"To do that, we recommend to define your types in a shared TypeScript file first:",{"type":46,"tag":63,"props":820,"children":822},{"className":76,"code":821,"language":78,"meta":40,"style":68},"// rpc-types.ts\n\nexport interface ServerFunctions {\n  getMyModuleOptions: () => MyModuleOptions\n}\n\nexport interface ClientFunctions {\n  showNotification: (message: string) => void\n}\n",[823],{"type":46,"tag":54,"props":824,"children":825},{"__ignoreMap":40},[826],{"type":51,"value":821},{"type":46,"tag":47,"props":828,"children":829},{},[830],{"type":51,"value":831},"And then in your module code:",{"type":46,"tag":63,"props":833,"children":835},{"className":76,"code":834,"language":78,"meta":40,"style":68},"import type { ClientFunctions, ServerFunctions } from './rpc-types'\nimport { extendServerRpc, onDevToolsInitialized } from '@nuxt/devtools-kit'\nimport { defineNuxtModule } from '@nuxt/kit'\n\nconst RPC_NAMESPACE = 'my-module-rpc'\n\nexport default defineNuxtModule({\n  setup(options, nuxt) {\n    // wait for DevTools to be initialized\n    onDevToolsInitialized(async () => {\n      const rpc = extendServerRpc\u003CClientFunctions, ServerFunctions>(RPC_NAMESPACE, {\n        // register server RPC functions\n        getMyModuleOptions() {\n          return options\n        },\n      })\n\n      // call client RPC functions\n      // since it might have multiple clients connected, we use `broadcast` to call all of them\n      await rpc.broadcast.showNotification('Hello from My Module!')\n    })\n  }\n})\n",[836],{"type":46,"tag":54,"props":837,"children":838},{"__ignoreMap":40},[839],{"type":51,"value":834},{"type":46,"tag":47,"props":841,"children":842},{},[843],{"type":51,"value":844},"And on the embedded iframe client side, you can do:",{"type":46,"tag":63,"props":846,"children":848},{"className":76,"code":847,"language":78,"meta":40,"style":68},"import type { ClientFunctions, ServerFunctions } from './rpc-types'\nimport { onDevtoolsClientConnected } from '@nuxt/devtools-kit/iframe-client'\n\nconst RPC_NAMESPACE = 'my-module-rpc'\n\nonDevtoolsClientConnected(async (client) => {\n  const rpc = client.devtools.extendClientRpc(RPC_NAMESPACE, {\n    showNotification(message) {\n      console.log(message)\n    },\n  })\n\n  // call server RPC functions\n  const options = await rpc.getMyModuleOptions()\n})\n",[849],{"type":46,"tag":54,"props":850,"children":851},{"__ignoreMap":40},[852],{"type":51,"value":847},{"type":46,"tag":106,"props":854,"children":856},{"id":855},"trying-local-changes",[857],{"type":51,"value":858},"Trying Local Changes",{"type":46,"tag":47,"props":860,"children":861},{},[862],{"type":51,"value":863},"You can clone Nuxt DevTools repo and try your changes locally.",{"type":46,"tag":47,"props":865,"children":866},{},[867,868,873],{"type":51,"value":795},{"type":46,"tag":311,"props":869,"children":871},{"href":870},"/development/contributing#trying-local-changes",[872],{"type":51,"value":858},{"type":51,"value":61},{"type":46,"tag":106,"props":875,"children":877},{"id":876},"examples",[878],{"type":51,"value":879},"Examples",{"type":46,"tag":47,"props":881,"children":882},{},[883],{"type":51,"value":884},"Here are a few examples of how to integrate Nuxt DevTools in modules:",{"type":46,"tag":152,"props":886,"children":887},{},[888,899,909,919,929,939],{"type":46,"tag":156,"props":889,"children":890},{},[891],{"type":46,"tag":311,"props":892,"children":896},{"href":893,"rel":894},"https://github.com/nuxt/devtools/blob/a8d372bd10d34d8c2fba2613558df2b9b99d6ff9/packages/devtools/src/integrations/vscode.ts#L140-L172",[895],"nofollow",[897],{"type":51,"value":898},"Built-in VS Code integration with lazy initialize",{"type":46,"tag":156,"props":900,"children":901},{},[902],{"type":46,"tag":311,"props":903,"children":906},{"href":904,"rel":905},"https://github.com/vueuse/vueuse/blob/ce28cef154489c73abe308104bef8568594a9bcd/packages/nuxt/index.ts#L89-L99",[895],[907],{"type":51,"value":908},"VueUse adds a docs tab",{"type":46,"tag":156,"props":910,"children":911},{},[912],{"type":46,"tag":311,"props":913,"children":916},{"href":914,"rel":915},"https://github.com/unocss/unocss/blob/25021a751494e99e85cfd82cca3855cdf78f6a12/packages/nuxt/src/index.ts#L81-L94",[895],[917],{"type":51,"value":918},"UnoCSS Inspector",{"type":46,"tag":156,"props":920,"children":921},{},[922],{"type":46,"tag":311,"props":923,"children":926},{"href":924,"rel":925},"https://github.com/nuxt/test-utils/blob/fd024f45f752c2faa4c9e0cc1fc1f8b3eae59553/src/module.ts#L150-L192",[895],[927],{"type":51,"value":928},"Nuxt Test Utils",{"type":46,"tag":156,"props":930,"children":931},{},[932],{"type":46,"tag":311,"props":933,"children":936},{"href":934,"rel":935},"https://github.com/nuxt-modules/og-image/blob/551b5474b44b8ff3190643e861c0b453813683b0/src/build/devtools.ts#L65-L80",[895],[937],{"type":51,"value":938},"Nuxt OG Image Playground",{"type":46,"tag":156,"props":940,"children":941},{},[942],{"type":46,"tag":311,"props":943,"children":946},{"href":944,"rel":945},"https://github.com/arashsheyda/nuxt-mongoose/blob/89d50bd977de0f4edfdbe3ed150d0dca4d040709/src/devtools.ts#L38-L48",[895],[947],{"type":51,"value":948},"Nuxt Mongoose",{"type":46,"tag":572,"props":950,"children":951},{},[952],{"type":51,"value":40},{"title":40,"searchDepth":577,"depth":577,"links":954},[955,956,959,960,961,962,963],{"id":612,"depth":577,"text":615},{"id":636,"depth":577,"text":639,"children":957},[958],{"id":673,"depth":582,"text":676},{"id":735,"depth":577,"text":738},{"id":787,"depth":577,"text":790},{"id":805,"depth":577,"text":808},{"id":855,"depth":577,"text":858},{"id":876,"depth":577,"text":879},"content:2.module:0.guide.md","2.module/0.guide.md","2.module/0.guide",{"_path":29,"_dir":38,"_draft":39,"_partial":39,"_locale":40,"title":28,"description":968,"body":969,"_type":594,"_id":1269,"_source":596,"_file":1270,"_stem":1271,"_extension":599},"UI Kit is for module authors to build a custom view.",{"type":43,"children":970,"toc":1261},[971,987,1004,1010,1022,1028,1036,1044,1050,1080,1093,1103,1145,1153,1158,1166,1171,1179,1193,1199,1212,1218,1231,1236,1244,1257],{"type":46,"tag":972,"props":973,"children":974},"callout",{},[975],{"type":46,"tag":47,"props":976,"children":977},{},[978,980,985],{"type":51,"value":979},"We suggest you to read the ",{"type":46,"tag":311,"props":981,"children":982},{"href":23},[983],{"type":51,"value":984},"Module Authors Guide",{"type":51,"value":986}," first.",{"type":46,"tag":47,"props":988,"children":989},{},[990,992,1003],{"type":51,"value":991},"DevTools UI Kit is for module authors to build the custom view with the similiar look and feel as built-in DevTools UI. The source code can be found under ",{"type":46,"tag":311,"props":993,"children":996},{"href":994,"rel":995},"https://github.com/nuxt/devtools/tree/main/packages/devtools-ui-kit",[895],[997],{"type":46,"tag":54,"props":998,"children":1000},{"className":999},[],[1001],{"type":51,"value":1002},"packages/devtools-ui-kit",{"type":51,"value":61},{"type":46,"tag":106,"props":1005,"children":1007},{"id":1006},"installation",[1008],{"type":51,"value":1009},"Installation",{"type":46,"tag":47,"props":1011,"children":1012},{},[1013,1015,1020],{"type":51,"value":1014},"We recommend to use the ",{"type":46,"tag":311,"props":1016,"children":1018},{"href":1017},"/module/guide#starter-template",[1019],{"type":51,"value":615},{"type":51,"value":1021}," for authoring a DevTools integration for your module, which has the set up built in and ready to use.",{"type":46,"tag":116,"props":1023,"children":1025},{"id":1024},"manual-install",[1026],{"type":51,"value":1027},"Manual Install",{"type":46,"tag":63,"props":1029,"children":1031},{"className":65,"code":1030,"language":67,"meta":40,"style":68},"npm i @nuxt/devtools-ui-kit\n",[1032],{"type":46,"tag":54,"props":1033,"children":1034},{"__ignoreMap":40},[1035],{"type":51,"value":1030},{"type":46,"tag":63,"props":1037,"children":1039},{"className":76,"code":1038,"language":78,"meta":40,"style":68},"export default defineNuxtConfig({\n  modules: [\n    '@nuxt/devtools-ui-kit'\n  ]\n})\n",[1040],{"type":46,"tag":54,"props":1041,"children":1042},{"__ignoreMap":40},[1043],{"type":51,"value":1038},{"type":46,"tag":106,"props":1045,"children":1047},{"id":1046},"usage",[1048],{"type":51,"value":1049},"Usage",{"type":46,"tag":47,"props":1051,"children":1052},{},[1053,1055,1061,1063,1070,1071,1078],{"type":51,"value":1054},"Under the hood, ",{"type":46,"tag":54,"props":1056,"children":1058},{"className":1057},[],[1059],{"type":51,"value":1060},"@nuxt/devtools-ui-kit",{"type":51,"value":1062}," is an unbundled component library powered by ",{"type":46,"tag":311,"props":1064,"children":1067},{"href":1065,"rel":1066},"https://github.com/unocss/unocss",[895],[1068],{"type":51,"value":1069},"UnoCSS",{"type":51,"value":204},{"type":46,"tag":311,"props":1072,"children":1075},{"href":1073,"rel":1074},"https://vueuse.org/",[895],[1076],{"type":51,"value":1077},"VueUse",{"type":51,"value":1079},". Components are auto imported.",{"type":46,"tag":47,"props":1081,"children":1082},{},[1083,1085,1091],{"type":51,"value":1084},"In this library, we introduced the ",{"type":46,"tag":54,"props":1086,"children":1088},{"className":1087},[],[1089],{"type":51,"value":1090},"n",{"type":51,"value":1092}," attribute for every component to customize the styles and variations. For example, to make a red button:",{"type":46,"tag":63,"props":1094,"children":1098},{"className":1095,"code":1096,"language":1097,"meta":40,"style":68},"language-html","\u003CNButton n=\"red\" />\n","html",[1099],{"type":46,"tag":54,"props":1100,"children":1101},{"__ignoreMap":40},[1102],{"type":51,"value":1096},{"type":46,"tag":47,"props":1104,"children":1105},{},[1106,1108,1114,1116,1121,1122,1128,1130,1136,1138,1143],{"type":51,"value":1107},"to make it larger, add the size specifier (",{"type":46,"tag":54,"props":1109,"children":1111},{"className":1110},[],[1112],{"type":51,"value":1113},"sm",{"type":51,"value":1115},", ",{"type":46,"tag":54,"props":1117,"children":1119},{"className":1118},[],[1120],{"type":51,"value":599},{"type":51,"value":1115},{"type":46,"tag":54,"props":1123,"children":1125},{"className":1124},[],[1126],{"type":51,"value":1127},"lg",{"type":51,"value":1129}," or ",{"type":46,"tag":54,"props":1131,"children":1133},{"className":1132},[],[1134],{"type":51,"value":1135},"xl",{"type":51,"value":1137},") the ",{"type":46,"tag":54,"props":1139,"children":1141},{"className":1140},[],[1142],{"type":51,"value":1090},{"type":51,"value":1144}," attribute:",{"type":46,"tag":63,"props":1146,"children":1148},{"className":1095,"code":1147,"language":1097,"meta":40,"style":68},"\u003CNButton n=\"red xl\" />\n",[1149],{"type":46,"tag":54,"props":1150,"children":1151},{"__ignoreMap":40},[1152],{"type":51,"value":1147},{"type":46,"tag":47,"props":1154,"children":1155},{},[1156],{"type":51,"value":1157},"You can apply the same specifiers to any other component, for example:",{"type":46,"tag":63,"props":1159,"children":1161},{"className":1095,"code":1160,"language":1097,"meta":40,"style":68},"\u003CNCheckbox n=\"red xl\" />\n",[1162],{"type":46,"tag":54,"props":1163,"children":1164},{"__ignoreMap":40},[1165],{"type":51,"value":1160},{"type":46,"tag":47,"props":1167,"children":1168},{},[1169],{"type":51,"value":1170},"Apply it to parent components could make a local theme scope",{"type":46,"tag":63,"props":1172,"children":1174},{"className":1095,"code":1173,"language":1097,"meta":40,"style":68},"\u003CNCard n=\"green-500\">\n  \u003C!-- both of them are themed green -->\n  \u003CNCheckbox>i accept the terms & conditions\u003C/NCheckbox>\n  \u003CNButton>Submit\u003C/NButton>\n\u003C/NCard>\n",[1175],{"type":46,"tag":54,"props":1176,"children":1177},{"__ignoreMap":40},[1178],{"type":51,"value":1173},{"type":46,"tag":47,"props":1180,"children":1181},{},[1182,1184,1191],{"type":51,"value":1183},"Please check our ",{"type":46,"tag":311,"props":1185,"children":1188},{"href":1186,"rel":1187},"https://ui-kit.devtools.nuxtjs.org/",[895],[1189],{"type":51,"value":1190},"Online Demo",{"type":51,"value":1192}," for more components usages.",{"type":46,"tag":106,"props":1194,"children":1196},{"id":1195},"components",[1197],{"type":51,"value":1198},"Components",{"type":46,"tag":47,"props":1200,"children":1201},{},[1202,1204,1211],{"type":51,"value":1203},"Check ",{"type":46,"tag":311,"props":1205,"children":1208},{"href":1206,"rel":1207},"https://github.com/nuxt/devtools/blob/main/packages/devtools-ui-kit/src/components",[895],[1209],{"type":51,"value":1210},"all components",{"type":51,"value":61},{"type":46,"tag":106,"props":1213,"children":1215},{"id":1214},"theming",[1216],{"type":51,"value":1217},"Theming",{"type":46,"tag":47,"props":1219,"children":1220},{},[1221,1223,1229],{"type":51,"value":1222},"Powered by ",{"type":46,"tag":311,"props":1224,"children":1227},{"href":1225,"rel":1226},"https://github.com/antfu/unocss",[895],[1228],{"type":51,"value":1069},{"type":51,"value":1230},", you can use Tailwind/Windi CSS utilities to quickly customize the look and feel of components.",{"type":46,"tag":47,"props":1232,"children":1233},{},[1234],{"type":51,"value":1235},"It's also possible to override the default theme globally, for example:",{"type":46,"tag":63,"props":1237,"children":1239},{"className":76,"code":1238,"language":78,"meta":40,"style":68},"// nuxt.config.js\nexport default defineNuxtConfig({\n  modules: [\n    '@nuxt/devtools-ui-kit'\n  ],\n  unocss: {\n    shortcuts: {\n      'n-button-base': 'border n-border-base rounded shadow-sm op80 !outline-none',\n      'n-button-hover': 'op100 !border-context text-context',\n      'n-button-active': 'n-active-base bg-context/5',\n    }\n  }\n})\n",[1240],{"type":46,"tag":54,"props":1241,"children":1242},{"__ignoreMap":40},[1243],{"type":51,"value":1238},{"type":46,"tag":47,"props":1245,"children":1246},{},[1247,1249,1256],{"type":51,"value":1248},"You can find all the default values and available entries in ",{"type":46,"tag":311,"props":1250,"children":1253},{"href":1251,"rel":1252},"https://github.com/nuxt/devtools/blob/main/packages/devtools-ui-kit/src/unocss.ts",[895],[1254],{"type":51,"value":1255},"src/unocss.ts",{"type":51,"value":61},{"type":46,"tag":572,"props":1258,"children":1259},{},[1260],{"type":51,"value":40},{"title":40,"searchDepth":577,"depth":577,"links":1262},[1263,1266,1267,1268],{"id":1006,"depth":577,"text":1009,"children":1264},[1265],{"id":1024,"depth":582,"text":1027},{"id":1046,"depth":577,"text":1049},{"id":1195,"depth":577,"text":1198},{"id":1214,"depth":577,"text":1217},"content:2.module:2.ui-kit.md","2.module/2.ui-kit.md","2.module/2.ui-kit",1787397683209]