Skip to content

Commit

Permalink
feat: composables useNuxtDevTools (nuxt#383)
Browse files Browse the repository at this point in the history
  • Loading branch information
antfu authored and Dev1436 committed Aug 12, 2023
1 parent c7ff1b9 commit 2c4bb52
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 1 deletion.
28 changes: 28 additions & 0 deletions docs/content/1.guide/2.composables.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Composables

In case you might want to open or control the Nuxt DevTools in your application on development, a composable `useNuxtDevtools` is registered with auto-import.

```vue
<script setup>
// Returns undefined in production mode or when the DevTools are not enabled
const devtoolsClient = useNuxtDevtools() // NuxtDevToolsHostClient | undefined
</script>
<template>
<button
v-if="devtoolsClient"
@click="devtoolsClient.devtools.navigate('/modules/components')"
>
<!-- Open the DevTools and navigate to the components tab -->
Open DevTools
</button>
</template>
```

When you have auto-import disabled, you can also import it explicitly:

```ts
import { useNuxtDevtools } from '#imports'
```

Checkout it's type definition for more available methods.
7 changes: 7 additions & 0 deletions packages/devtools/src/module-main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,13 @@ window.__NUXT_DEVTOOLS_TIME_METRIC__.appInit = Date.now()
config.server.watch.ignored.push('**/.nuxt/analyze/**')
})

nuxt.hook('imports:extend', (imports) => {
imports.push({
name: 'useNuxtDevTools',
from: join(runtimeDir, 'use-nuxt-devtools'),
})
})

// TODO: Use WS from nitro server when possible
nuxt.hook('vite:serverCreated', (server: ViteDevServer) => {
server.middlewares.use(ROUTE_ANALYZE, sirv(analyzeDir, { single: false, dev: true }))
Expand Down
2 changes: 2 additions & 0 deletions packages/devtools/src/runtime/plugins/view/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ export async function setupDevToolsClient({
},
})

window.__NUXT_DEVTOOLS_HOST__ = client

let iframe: HTMLIFrameElement | undefined

function syncClient() {
Expand Down
34 changes: 34 additions & 0 deletions packages/devtools/src/runtime/use-nuxt-devtools.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import type { Ref } from 'vue'
import { shallowRef } from 'vue'
import type { NuxtDevtoolsHostClient } from '../types'

/**
* Get Nuxt DevTools client for host app
*
* Returns undefined if not in development mode or the devtools is not enabled
*/
export function useNuxtDevTools(): Ref<NuxtDevtoolsHostClient | undefined> {
const r = shallowRef()
if (!process.dev)
return r

if (process.server)
return r

if (window.__NUXT_DEVTOOLS_HOST__) {
r.value = window.__NUXT_DEVTOOLS_HOST__
}
else {
Object.defineProperty(window, '__NUXT_DEVTOOLS_HOST__', {
set(value) {
r.value = value
},
get() {
return r.value
},
enumerable: false,
configurable: true,
})
}
return r
}
7 changes: 6 additions & 1 deletion packages/devtools/src/types/global.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { VueInspectorClient } from 'vite-plugin-vue-inspector'
import type { LoadingTimeMetric, NuxtDevtoolsIframeClient, NuxtDevtoolsGlobal as NuxtDevtoolsViewGlobal, PluginMetric, TimelineMetrics } from '.'
import type { LoadingTimeMetric, NuxtDevtoolsHostClient, NuxtDevtoolsIframeClient, NuxtDevtoolsGlobal as NuxtDevtoolsViewGlobal, PluginMetric, TimelineMetrics } from '.'

declare global {
interface Window {
Expand All @@ -8,6 +8,11 @@ declare global {
*/
__NUXT_DEVTOOLS__?: NuxtDevtoolsIframeClient

/**
* Nuxt DevTools client for host app
*/
__NUXT_DEVTOOLS_HOST__?: NuxtDevtoolsHostClient

/**
* Nuxt DevTools for receiving host client
*
Expand Down
12 changes: 12 additions & 0 deletions playgrounds/tab-seo/components/GlobalNav.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
<script setup lang="ts">
const nd = useNuxtDevTools()
</script>

<template>
<div px10 pt10 op50>
Click to navigate and see the SEO tab
<template v-if="nd">
<button
border="~ rounded gray/30" ml2 px2 hover="border-green text-green"
@click="nd.devtools.navigate('/modules/open-graph')"
>
Open devtools
</button>
</template>
</div>
<div px10 py5 flex="~ gap-4">
<NuxtLink to="/" active-class="text-green">
Expand Down

0 comments on commit 2c4bb52

Please sign in to comment.