Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions .github/workflows/docs-screenshots.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: docs-screenshots

# Regenerates the screenshots in `docs/images/` (`pnpm docs:screenshots`) and
# opens a pull request when they changed. Run it from the Actions tab after a
# UI change; one runner keeps the rendering consistent across runs.
on:
workflow_dispatch:

permissions: {}

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
screenshots:
if: github.repository == 'nuxt/devtools'
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
contents: write
pull-requests: write
steps:
- uses: actions/checkout@v7
with:
persist-credentials: false
- uses: pnpm/action-setup@v6
- uses: actions/setup-node@v7
with:
node-version: lts/*
cache: pnpm
- run: npm install -g corepack@latest
- run: corepack enable
- run: pnpm install
- run: pnpm build
- run: pnpm exec playwright install --with-deps chromium
- run: pnpm docs:screenshots
- name: Open a pull request
env:
GH_TOKEN: ${{ github.token }}
BASE: ${{ github.ref_name }}
BRANCH: docs/screenshots-${{ github.run_id }}
run: |
if [ -z "$(git status --porcelain -- docs/images)" ]; then
echo "Screenshots are up to date."
exit 0
fi
git config user.name 'github-actions[bot]'
git config user.email '41898282+github-actions[bot]@users.noreply.github.com'
git switch -c "$BRANCH"
git add docs/images
git commit -m 'docs: update screenshots'
git push "https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" "$BRANCH"
gh pr create --base "$BASE" --head "$BRANCH" \
--title 'docs: update screenshots' \
--body "Regenerated by \`pnpm docs:screenshots\` in the [docs-screenshots workflow](${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID})."
12 changes: 12 additions & 0 deletions docs/1.features.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,14 @@ Appears while the current page holds an error, and shows it with its stack trace

Shows the state and data payloads of your page: keyed state from `useState()` and the data fetched with `useAsyncData()` and `useFetch()`, which you can re-fetch.

![Payload tab](./images/payload.webp)

### Runtime Configs

Shows your App Config and runtime config. App Config and public runtime config can be edited live; private runtime config is read-only, as it is never exposed to the client.

![Runtime Configs tab](./images/runtime-configs.webp)

### Plugins

Shows the plugins of your app, with their mode (client or server) and initialization time.
Expand All @@ -65,6 +69,8 @@ Shows the plugins of your app, with their mode (client or server) and initializa

Records when auto-imported composables run and when the route changes, to help you understand the order in which things happen. It is opt-in: until it is enabled, the tab offers to enable it for you, which updates your `nuxt.config` and restarts Nuxt.

![Timeline tab](./images/timeline.webp)

```ts [nuxt.config.ts]
export default defineNuxtConfig({
devtools: {
Expand Down Expand Up @@ -95,14 +101,20 @@ The Open Graph panel, powered by [`@devframes/plugin-og`](https://npmx.dev/packa

Shows all the [Nitro](https://nitro.build) routes of your project, with a playground to send requests to your endpoints and inspect their responses.

![Server Routes tab](./images/server-routes.webp)

### Server Tasks

Appears when Nitro's `experimental.tasks` is enabled and your project defines [tasks](https://nitro.build/guide/tasks). Pass task payloads, run them, and see their results.

![Server Tasks tab](./images/server-tasks.webp)

### Storage

Shows the [Nitro storage](https://nitro.build/guide/storage) mounts of your project. You can create, edit, and delete their items.

![Storage tab](./images/storage.webp)

## Modules

Tabs contributed by the Nuxt modules you install (for example `@nuxt/fonts`, `@nuxt/scripts` or `nuxt-og-image`) appear in this section. See the [Module Authors Guide](/modules/devtools/module-authors) to add your own.
Expand Down
10 changes: 10 additions & 0 deletions docs/8.contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,14 @@ On the module side, the source TypeScript files are used directly, so you don't

The documentation lives in the [`docs/`](https://github.com/nuxt/devtools/tree/main/docs) directory and is published on [nuxt.com/modules/devtools](/modules/devtools). Keep images next to the pages in `docs/images/` and link them with a relative path, such as `![Overview tab](./images/overview.webp)`.

The DevTools screenshots are generated from the [`docs` playground](https://github.com/nuxt/devtools/tree/main/playgrounds/docs), a small shop with pages, components, server routes, a task and a storage mount. After a UI change, regenerate them with:

```sh
pnpm build
pnpm exec playwright install chromium
pnpm docs:screenshots
```

Each screenshot is a step in [`tests/docs-screenshots/screenshots.spec.ts`](https://github.com/nuxt/devtools/blob/main/tests/docs-screenshots/screenshots.spec.ts): add one there to document a new tab. The `docs-screenshots` workflow, run from the Actions tab, does the same on CI and opens a pull request with the updated images.

To preview your changes, run the [nuxt.com](https://github.com/nuxt/nuxt.com) dev server with `NUXT_DEVTOOLS_PATH` set to your local clone of this repo. Pull requests changing `docs/` can also be previewed on nuxt.com once a maintainer adds the `preview:enabled` label.
Binary file modified docs/images/components.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/images/hooks.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/images/imports.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/images/modules.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/images/overview.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/images/pages.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/payload.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/runtime-configs.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/server-routes.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/server-tasks.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/storage.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/timeline.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion knip.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"local.ts",
"scripts/*.{js,mjs,ts}",
"taze.config.ts",
"tests/e2e/**/*.ts"
"tests/{e2e,docs-screenshots}/**/*.ts"
],
"project": [
"*.{js,mjs,ts}",
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"test:e2e:prebuild": "pnpm -C playgrounds/empty exec nuxt build && pnpm -C playgrounds/spa exec nuxt build",
"test:e2e:ui": "playwright test --config tests/e2e/playwright.config.ts --ui",
"test:e2e:ecosystem": "playwright test --config playgrounds-ecosystem/tests/playwright.config.ts",
"docs:screenshots": "playwright test --config tests/docs-screenshots/playwright.config.ts",
"typecheck": "vue-tsc --noEmit",
"postinstall": "simple-git-hooks && skills experimental_sync -y -r",
"dev:prepare": "pnpm -r --filter=\"./packages/*\" run dev:prepare"
Expand Down
6 changes: 6 additions & 0 deletions playgrounds/docs/app/app.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export default defineAppConfig({
theme: {
primary: 'green',
},
announcement: 'Free shipping on orders over €50',
})
5 changes: 5 additions & 0 deletions playgrounds/docs/app/app.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<template>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</template>
9 changes: 9 additions & 0 deletions playgrounds/docs/app/assets/main.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
html {
background: #0b0b0b;
color: #e5e5e5;
font-family: ui-sans-serif, system-ui, sans-serif;
}

body {
margin: 0;
}
22 changes: 22 additions & 0 deletions playgrounds/docs/app/components/AppHeader.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<script setup lang="ts">
const { public: { siteName } } = useRuntimeConfig()
const { announcement } = useAppConfig()
</script>

<template>
<header flex items-center gap-6 border-b border-neutral-800 pb-4>
<NuxtLink to="/" text-xl text-green-400 font-bold>
{{ siteName }}
</NuxtLink>
<nav flex gap-4 text-sm>
<NuxtLink to="/products">
Products
</NuxtLink>
<NuxtLink to="/about">
About
</NuxtLink>
</nav>
<span flex-1 text-xs op50>{{ announcement }}</span>
<CartButton />
</header>
</template>
7 changes: 7 additions & 0 deletions playgrounds/docs/app/components/CartButton.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<script setup lang="ts">
const { count } = useCart()
</script>

<template>
<span text-sm>Cart ({{ count }})</span>
</template>
9 changes: 9 additions & 0 deletions playgrounds/docs/app/components/PriceTag.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<script setup lang="ts">
const props = defineProps<{ price: number }>()
const { public: { currency } } = useRuntimeConfig()
const formatted = computed(() => new Intl.NumberFormat('en', { style: 'currency', currency }).format(props.price))
</script>

<template>
<span font-mono>{{ formatted }}</span>
</template>
24 changes: 24 additions & 0 deletions playgrounds/docs/app/components/ProductCard.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<script setup lang="ts">
import type { Product } from '~~/server/utils/products'

defineProps<{ product: Product }>()

const { add } = useCart()
</script>

<template>
<article flex flex-col gap-2 border border-neutral-800 rounded-lg p-4>
<NuxtLink :to="`/products/${product.id}`" font-semibold>
{{ product.name }}
</NuxtLink>
<p text-sm op60>
{{ product.description }}
</p>
<div flex items-center justify-between>
<PriceTag :price="product.price" />
<button text-sm text-green-400 @click="add(product.id)">
Add to cart
</button>
</div>
</article>
</template>
9 changes: 9 additions & 0 deletions playgrounds/docs/app/composables/useCart.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export function useCart() {
const items = useState<number[]>('cart', () => [])

return {
items,
count: computed(() => items.value.length),
add: (id: number) => items.value.push(id),
}
}
3 changes: 3 additions & 0 deletions playgrounds/docs/app/composables/useProducts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function useProducts() {
return useFetch('/api/products', { key: 'products' })
}
8 changes: 8 additions & 0 deletions playgrounds/docs/app/layouts/default.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<template>
<div mx-auto max-w-5xl p-6>
<AppHeader />
<main py-6>
<slot />
</main>
</div>
</template>
3 changes: 3 additions & 0 deletions playgrounds/docs/app/middleware/analytics.global.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default defineNuxtRouteMiddleware(() => {
useState('page-views', () => 0).value++
})
3 changes: 3 additions & 0 deletions playgrounds/docs/app/middleware/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default defineNuxtRouteMiddleware(() => {
// Every visitor may browse the shop; a real app would check a session here.
})
10 changes: 10 additions & 0 deletions playgrounds/docs/app/pages/about.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<template>
<section>
<h1 text-3xl font-bold>
About
</h1>
<p op60>
Nuxt Shop is the playground the Nuxt DevTools docs screenshots are taken from.
</p>
</section>
</template>
20 changes: 20 additions & 0 deletions playgrounds/docs/app/pages/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<script setup lang="ts">
const { data: products } = await useProducts()

useSeoMeta({
title: 'Nuxt Shop',
description: 'A small shop built with Nuxt.',
ogImage: '/og.png',
})
</script>

<template>
<section flex flex-col gap-6>
<h1 text-3xl font-bold>
Featured products
</h1>
<div grid grid-cols-3 gap-4>
<ProductCard v-for="product in products?.slice(0, 3)" :key="product.id" :product="product" />
</div>
</section>
</template>
20 changes: 20 additions & 0 deletions playgrounds/docs/app/pages/products/[id].vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<script setup lang="ts">
definePageMeta({
middleware: 'auth',
})

const route = useRoute()
const { data: product } = await useFetch(`/api/products/${route.params.id}`)
</script>

<template>
<section v-if="product" flex flex-col gap-4>
<h1 text-3xl font-bold>
{{ product.name }}
</h1>
<p op60>
{{ product.description }}
</p>
<PriceTag :price="product.price" />
</section>
</template>
14 changes: 14 additions & 0 deletions playgrounds/docs/app/pages/products/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<script setup lang="ts">
const { data: products } = await useProducts()
</script>

<template>
<section flex flex-col gap-6>
<h1 text-3xl font-bold>
Products
</h1>
<div grid grid-cols-3 gap-4>
<ProductCard v-for="product in products" :key="product.id" :product="product" />
</div>
</section>
</template>
7 changes: 7 additions & 0 deletions playgrounds/docs/app/plugins/currency.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default defineNuxtPlugin(() => {
return {
provide: {
locale: 'en',
},
}
})
45 changes: 45 additions & 0 deletions playgrounds/docs/nuxt.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// The app the docs screenshots are taken from (`pnpm docs:screenshots`):
// a small shop, so every DevTools tab has something realistic to show.
const devtoolsModule = process.env.NUXT_DEVTOOLS_LOCAL ? '../../local' : '@nuxt/devtools'

export default defineNuxtConfig({
modules: [
devtoolsModule,
'@unocss/nuxt',
'@vueuse/nuxt',
],

devtools: {
timeline: {
enabled: true,
},
},

app: {
head: {
title: 'Nuxt Shop',
htmlAttrs: { lang: 'en', class: 'dark' },
},
},

css: ['~/assets/main.css'],

runtimeConfig: {
stripeSecretKey: '',
public: {
siteName: 'Nuxt Shop',
currency: 'EUR',
},
},

nitro: {
experimental: {
tasks: true,
},
storage: {
shop: { driver: 'fs', base: './.data/shop' },
},
},

compatibilityDate: '2026-10-01',
})
13 changes: 13 additions & 0 deletions playgrounds/docs/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"version": "4.0.0",
"private": true,
"scripts": {
"play:dev": "nuxt dev"
},
"devDependencies": {
"@nuxt/devtools": "workspace:^",
"@unocss/nuxt": "catalog:buildtools",
"@vueuse/nuxt": "catalog:buildtools",
"nuxt": "catalog:buildtools"
}
}
Loading
Loading