- {{ formatNumber(module.stats.downloads) }}+
+ {{ formatNumber(mod.stats.downloads) }}+
Monthly Downloads
@@ -255,7 +256,7 @@ watch(projectsSectionVisible, () => {
- {{ formatNumber(module.stats.stars) }}+
+ {{ formatNumber(mod.stats.stars) }}+
Stars
diff --git a/packages/devtools-kit/src/_types/options.ts b/packages/devtools-kit/src/_types/options.ts
index 376aa65c2..26b0a87c3 100644
--- a/packages/devtools-kit/src/_types/options.ts
+++ b/packages/devtools-kit/src/_types/options.ts
@@ -163,6 +163,7 @@ export interface NuxtDevToolsOptions {
scale: number
showExperimentalFeatures: boolean
showHelpButtons: boolean
+ showPanel: boolean | null
sidebarExpanded: boolean
sidebarScrollable: boolean
}
diff --git a/packages/devtools/client/pages/index.vue b/packages/devtools/client/pages/index.vue
index dc4df16be..78e83f07f 100644
--- a/packages/devtools/client/pages/index.vue
+++ b/packages/devtools/client/pages/index.vue
@@ -6,9 +6,16 @@ definePageMeta({
})
const telemetry = ref(true)
+const enableFloatPanel = ref(true)
+
+const {
+ showPanel,
+} = useDevToolsUIOptions()
function visit() {
telemetryEnabled.value = telemetry.value
+ if (showPanel.value == null && enableFloatPanel.value)
+ showPanel.value = true
isFirstVisit.value = false
}
@@ -34,9 +41,14 @@ function visit() {
-
- Send anonymous statistics, help us improving DevTools
-
+
+
+ Show floating panel from now on
+
+
+ Send anonymous statistics, help us improving DevTools
+
+
diff --git a/packages/devtools/client/pages/settings.vue b/packages/devtools/client/pages/settings.vue
index 99d41972a..4d00640ce 100644
--- a/packages/devtools/client/pages/settings.vue
+++ b/packages/devtools/client/pages/settings.vue
@@ -7,7 +7,7 @@ definePageMeta({
const {
interactionCloseOnOutsideClick,
- // showExperimentalFeatures,
+ showPanel,
showHelpButtons,
scale,
hiddenTabs,
@@ -107,7 +107,7 @@ watchEffect(() => {
toggleTabCategory(name, v)"
+ @update:model-value="(v: boolean) => toggleTabCategory(name, v)"
>
{{ name }}
@@ -120,7 +120,7 @@ watchEffect(() => {
toggleTab(tab.name, v)"
+ @update:model-value="(v: boolean) => toggleTab(tab.name, v)"
>
@@ -197,10 +197,14 @@ watchEffect(() => {
Show help buttons
+
+ Always show the floating panel
+
+
Minimize floating panel on inactive
-
+
diff --git a/packages/devtools/src/constant.ts b/packages/devtools/src/constant.ts
index c2e361da9..08ca31b49 100644
--- a/packages/devtools/src/constant.ts
+++ b/packages/devtools/src/constant.ts
@@ -34,6 +34,7 @@ export const defaultTabOptions: NuxtDevToolsOptions = {
interactionCloseOnOutsideClick: false,
showExperimentalFeatures: false,
showHelpButtons: true,
+ showPanel: null,
scale: 1,
minimizePanelInactive: 5000,
hiddenTabs: [],
diff --git a/packages/devtools/src/module-main.ts b/packages/devtools/src/module-main.ts
index 794e81f66..aed0bf9a6 100644
--- a/packages/devtools/src/module-main.ts
+++ b/packages/devtools/src/module-main.ts
@@ -2,17 +2,18 @@ import { existsSync } from 'node:fs'
import os from 'node:os'
import { join } from 'pathe'
import type { Nuxt } from 'nuxt/schema'
-import { addPlugin, addVitePlugin, logger } from '@nuxt/kit'
+import { addPlugin, addTemplate, addVitePlugin, logger } from '@nuxt/kit'
import type { ViteDevServer } from 'vite'
import { searchForWorkspaceRoot } from 'vite'
import sirv from 'sirv'
import { colors } from 'consola/utils'
import { version } from '../package.json'
-import type { ModuleOptions } from './types'
+import type { ModuleOptions, NuxtDevToolsOptions } from './types'
import { setupRPC } from './server-rpc'
import { clientDir, isGlobalInstall, packageDir, runtimeDir } from './dirs'
-import { ROUTE_ANALYZE, ROUTE_AUTH, ROUTE_AUTH_VERIFY, ROUTE_CLIENT } from './constant'
+import { ROUTE_ANALYZE, ROUTE_AUTH, ROUTE_AUTH_VERIFY, ROUTE_CLIENT, defaultTabOptions } from './constant'
import { getDevAuthToken } from './dev-auth'
+import { readLocalOptions } from './utils/local-options'
export async function enableModule(options: ModuleOptions, nuxt: Nuxt) {
// Disable in test mode
@@ -30,8 +31,14 @@ export async function enableModule(options: ModuleOptions, nuxt: Nuxt) {
return
}
+ // Determine if user aware devtools, by checking the presentation in the config
+ const enabledExplicitly = (nuxt.options.devtools === true)
+ || (nuxt.options.devtools && nuxt.options.devtools.enabled)
+ || !!nuxt.options.modules.find(m => m === '@nuxt/devtools' || m === '@nuxt/devtools-edge')
+
await nuxt.callHook('devtools:before')
+ // Make unimport exposing more information, like the usage of each auto imported function
nuxt.options.imports.collectMeta = true
addPlugin({
@@ -44,6 +51,25 @@ export async function enableModule(options: ModuleOptions, nuxt: Nuxt) {
mode: 'server',
})
+ // Mainly for the injected runtime plugin to access the settings
+ // Usage `import settings from '#build/devtools/settings'`
+ addTemplate({
+ filename: 'devtools/settings.mjs',
+ async getContents() {
+ const uiOptions = await readLocalOptions(
+ {
+ ...defaultTabOptions.ui,
+ // When not enabled explicitly, we hide the panel by default
+ showPanel: enabledExplicitly ? true : null,
+ },
+ { root: nuxt.options.rootDir },
+ )
+ return `export default ${JSON.stringify({
+ ui: uiOptions,
+ })}`
+ },
+ })
+
// Inject inline script
nuxt.hook('nitro:config', (config) => {
config.externals = config.externals || {}
diff --git a/packages/devtools/src/runtime/plugins/view/Main.vue b/packages/devtools/src/runtime/plugins/view/Main.vue
index a527d5731..c812ac8ba 100644
--- a/packages/devtools/src/runtime/plugins/view/Main.vue
+++ b/packages/devtools/src/runtime/plugins/view/Main.vue
@@ -1,7 +1,8 @@