Nuxt
Our own AI agent on nuxt.com, grounded in the official docs and the Nuxt ecosystem. We built it internally using the AI SDK, our MCP server, and Nuxt UI components.
First, we want to thank Kapa.ai, who have powered our AI Chat widget over the past few years through their sponsorship and continue to support our community through our Discord server.
We decided to build our own to showcase what's possible with Nuxt and offer a deeper integration with the framework and its ecosystem.
The Nuxt Agent is now in Beta on nuxt.com. We built it ourselves, plugged it into the site, and connected it to our docs, modules catalog, blog, and deployment guides.
Open the agent anywhere on nuxt.com with ⌘I (or Ctrl+I), or jump straight into the full-screen experience at /chat.
From a docs widget to a real agent
Kapa AI served us well as a docs Q&A widget for the past couple of years. It searched the docs and summarized an answer, and that was about it. But Nuxt is more than docs. There are modules, templates, deployment providers, a changelog, GitHub issues, playgrounds, and real navigation across the site.
We wanted an agent that could handle all of it, with the same design language as the rest of nuxt.com and the same content pipeline (Nuxt Content) we already run. So we built our own on top of the Nuxt MCP server we shipped last November.
Here's what the agent does today:
- Grounds answers in the official Nuxt docs and ecosystem data through MCP tools, not retrieved text chunks.
- Renders rich UI. Modules, templates, blog posts, hosting providers, and playground links come back as clickable cards instead of plain links.
- Streams everything as it runs, including tool call progress.
- Closes the loop. Feedback, voting, and issue reports flow into our internal tools so we can keep improving it.
Meet the agent
Three ways to talk to it
You can reach the agent three ways:
- A side panel pinned to the right on large screens, sliding over on smaller ones. Toggle it from the header or with ⌘I.
- An ask bar at the bottom of docs and blog pages, so you can ask a question without leaving the page you're reading.
- A full-screen chat at /chat for longer sessions.
It knows what page you're on
Ask "how do I customize this for my app?" while reading a doc and the agent automatically pulls that page in as context. A small "Agent is using this page" indicator in the footer makes it explicit, and you can dismiss it whenever you want.
Rich answers, not just text
Answers come back as more than text. Ask about a module and you get a module card with metadata pulled live from the API. Ask for starter templates and you get a row of clickable template cards. Ask about deployment and you get provider cards that link to the right guide. Need to reproduce a bug? The agent can generate a StackBlitz playground link from the conversation itself.
Try asking: "Show me official starter templates" — you'll get the full lineup as cards you can open in one click.
Feedback built in
Every assistant message has a thumbs up/down. If you want to share more (a missing piece, a wrong answer, an idea), the Report issue action opens a short form and creates a Linear ticket on our side with the conversation attached, so we have everything we need to follow up.
The agent can open that form itself, too. If you ask to "submit feedback" or "report an issue", or if the conversation starts to feel frustrated, the agent calls the report issue tool and the same form opens inline. No button hunting required.
Conversations are saved and resume across reloads, so you can step away and pick up where you left off.
What the agent can actually do
The agent's grounding comes from the Nuxt MCP server, the same one Cursor, Claude Desktop and ChatGPT connect to. That means the Nuxt Agent and your local AI assistant share the same structured data: the official docs, the modules catalog, the blog, deployment guides, and the Nuxt repositories' changelog.
On top of that grounding, the agent has a small set of native tools that render as UI in the chat: module and template cards, hosting providers, blog posts, StackBlitz playground links, and a GitHub issue search across Nuxt repositories. The agent reaches for that issue search first whenever you paste an error.
The web is available too, through Anthropic's native web search, but only as a fallback for things the model couldn't reasonably know: a brand new Vue release, a freshly published RFC, recent ecosystem news. It's not a general-purpose search engine, and the system prompt is explicit about that. We never use web search for anything that should be answered from the docs or the rest of the Nuxt content exposed through MCP.
Under the hood
The stack
A single Nitro handler drives everything. On the client, an @ai-sdk/vue Chat instance points at /api/agent. On the server, AI SDK v6 streamText calls claude-sonnet-4.6, with tools merged from our own MCP server and a few native ones. Chat state lives in Drizzle ORM, and evlog wraps the model for structured telemetry on tokens, cost, and tool calls.
UIMessage streaming with AI SDK v6
The whole pipeline runs on the AI SDK v6 UIMessage streaming model. The server side looks like this:
const stream = createUIMessageStream({
execute: async ({ writer }) => {
const result = streamText({
model: ai.wrap(MODEL),
maxOutputTokens: 4000,
stopWhen: stopWhenResponseComplete,
system: systemPrompt,
messages: await convertToModelMessages(messages),
tools: {
...mcpTools as ToolSet,
web_search: anthropic.tools.webSearch_20250305(),
search_github_issues: createSearchGitHubIssuesTool(event),
show_module: showModuleTool,
show_template: createShowTemplateTool(event),
show_blog_post: createShowBlogPostTool(event),
show_hosting: createShowHostingTool(event),
open_playground: openPlaygroundTool,
report_issue: reportIssueTool
},
experimental_telemetry: {
isEnabled: true,
integrations: [createEvlogIntegration(ai)]
}
})
writer.merge(result.toUIMessageStream({
sendSources: true,
originalMessages: messages,
onFinish: ({ messages: finalizedMessages }) => {
event.waitUntil(saveChat(finalizedMessages))
}
}))
}
})
Two details are worth pointing out. stopWhen: stopWhenResponseComplete is a custom predicate that ends the loop as soon as the model produces text without another tool call, with a hard ceiling at 10 steps. That avoids the classic "model loops forever on tools" failure mode. And event.waitUntil(saveChat(...)) pushes persistence outside the response lifecycle, so the stream finishes for the user right away while the chat row gets upserted in the background.
One MCP server, two consumers
The agent and external AI assistants talk to the same MCP server. That's the single most important architectural choice we made. The route handler opens an HTTP MCP client pointed at its own /mcp endpoint:
const httpClient = await createMCPClient({
transport: { type: 'http', url: `${getRequestURL(event).origin}${MCP_PATH}` }
})
const mcpTools = await httpClient.tools()
Those tools then get merged with the native UI tools into a single tools object passed to streamText. The payoff: any tool we add to the MCP server is immediately available to the Nuxt Agent and to every external assistant pointed at it, with no extra wiring. We wrote a separate post about how the MCP server itself works back in November.
Persistence, cost, and rate limiting
Chats live in a single agent_chats table, keyed by the x-chat-id header the client sends on every request. Drizzle's onConflictDoUpdate accumulates token usage, estimated cost, duration, and request count across the lifetime of a conversation. That gives us per-chat analytics for free.
Every request also goes through a small consumeAgentRateLimit helper before streaming starts. The current cap is 20 messages per day per IP fingerprint, which is enough for real use and low enough to prevent runaway costs if something starts looping.
A tight system prompt
A lot of agent quality comes from the prompt. A few rules carried most of the weight: reach for search_github_issues first whenever the user pastes an error, prefer show_module over get_module when the answer should render as a card, never call web_search unless the question is genuinely outside what the model could know, and never end a turn with only a tool call. Together those rules cut tool-spam and hallucinations enough that the agent stays focused on the task at hand.
What's next
The agent is launching in Beta. In the short term, we're focused on the basics: better answer quality, richer memory across turns, and cleaner source citations.
Further out, we want nuxt.com to feel more like an application than a static site. The next step there is user accounts. Each logged-in user gets their own session, their chat history saved and resumable across devices, and the Nuxt Agent becomes the first real building block of that more app-like nuxt.com.
We'd love your help shaping where it goes next. If the agent gets something wrong, or misses something you want, use the Report issue button inside the chat. It creates a ticket on our side with the full conversation attached, and we read every one.
Try the Nuxt Agent now: open it with ⌘I, use the ask bar on any docs page, or head to /chat for the full-screen experience.
The full source for nuxt.com is on GitHub, including the agent, the MCP server, and every tool covered above. The agent handler is at server/api/agent.post.ts, the native tools at server/utils/tools/, and the UI components at app/components/agent/. Take any of it as inspiration for your own apps. And if you want to build your own MCP server, the Nuxt MCP Toolkit gets you there in a few minutes.
Nuxt · v4.4.0
4.4.0/4.4.2 is the next minor release (v4.4.2 was published with no changes due to a publishing failure)
👀 Highlights
🏭 createUseFetch and createUseAsyncData
You can now create custom instances of useFetch and useAsyncData with your own default options (#32300).
// composables/api.ts
// Simple defaults
export const useClientFetch = createUseFetch({
server: false,
})
// Dynamic defaults with full control over merging
export const useApiFetch = createUseFetch((currentOptions) => {
const runtimeConfig = useRuntimeConfig()
return {
...currentOptions,
baseURL: currentOptions.baseURL ?? runtimeConfig.public.baseApiUrl,
}
})
Then use them exactly like useFetch – they're fully typed and support all the same options:
<!-- pages/dashboard.vue -->
<script setup lang="ts">
// Uses your baseURL from runtimeConfig automatically
const { data: users } = await useApiFetch('/users')
</script>
When you pass a plain object, your usage options automatically override the defaults. When you pass a function, you get full control over how options are merged – which means you can compose interceptors, headers, and other complex options however you need.
Under the hood, this is powered by a new Nuxt ad-hoc module that scans your composables directory and automatically registers your custom instances for key injection – so they work seamlessly with SSR, just like useAsyncData and useFetch.
There's also createUseAsyncData for the same pattern with useAsyncData.
🗺️ Vue Router v5
We've upgraded to vue-router v5 (#34181), which removes the dependency on unplugin-vue-router. This is the first major vue-router upgrade since Nuxt 3, and it comes with a bunch of improvements under the hood.
For most apps, this should be a transparent upgrade. If you're using unplugin-vue-router directly, you can remove it from your dependencies.
The next step will be taking typed routes out of experimental status. 👀
💪 Typed Layout Props in definePageMeta
You can now pass props to your layouts directly from definePageMeta (#34262). This means your layouts can be parameterised per-page without needing to use provide/inject or other workarounds. Check out the updated docs for the full details.
// pages/dashboard.vue
definePageMeta({
layout: {
name: 'panel',
props: {
sidebar: true,
title: 'Dashboard',
},
},
})
Even better – the props are fully typed (#34409). If your layout defines props, you'll get autocomplete and type-checking in definePageMeta.
<!-- layouts/panel.vue -->
<script setup lang="ts">
defineProps<{
sidebar?: boolean
title?: string
}>()
</script>
🗣️ useAnnouncer Composable
Accessibility got a major boost with the new useAnnouncer composable and <NuxtAnnouncer> component (#34318). While useRouteAnnouncer handles page navigation for screen readers, many apps need to announce dynamic in-page changes – form submissions, loading states, search results, and more.
<!-- app.vue -->
<template>
<NuxtAnnouncer />
<NuxtRouteAnnouncer />
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</template>
<!-- components/ContactForm.vue -->
<script setup lang="ts">
const { polite, assertive } = useAnnouncer()
async function submitForm() {
try {
await $fetch('/api/contact', { method: 'POST', body: formData })
polite('Message sent successfully')
}
catch (error) {
assertive('Error: Failed to send message')
}
}
</script>
Note: This is part of our accessibility roadmap. You don't need to use it everywhere – for many interactions, moving focus to new content or using native form validation is sufficient.
useAnnounceris most useful when content changes dynamically without a corresponding focus change.
🚀 Migrate to unrouting
We've migrated Nuxt's file-system route generation to unrouting (#34316), which uses a trie data structure for constructing routes. The cold start is roughly the same (~8ms vs ~6ms for large apps), but dev server changes are up to 28x faster when you're not adding/removing pages, and ~15% faster even when you are.
This also makes route generation more deterministic – it's no longer sensitive to page file ordering.
🍫 Smarter Payload Handling for Cached Routes
When a cached route (ISR/SWR) is rendered at runtime with payload extraction enabled, the browser immediately fetches _payload.json as a second request – which triggers a full SSR re-render of the same page. In serverless environments, this can spin up a second lambda before the first response has even finished streaming.
This release addresses this with two changes (#34410):
- A new
payloadExtraction: 'client'mode that inlines the full payload in the initial HTML response while still generating_payload.jsonfor client-side navigation - A runtime in-memory LRU payload cache so that
_payload.jsonrequests can be served without a full re-render
// nuxt.config.ts
export default defineNuxtConfig({
experimental: {
payloadExtraction: 'client',
},
})
Note:
payloadExtraction: 'client'will become the default withcompatibilityVersion: 5. The runtime cache is active for all users.
🍪 refresh Option for useCookie
If you're using cookies for session management, you've probably run into the problem of needing to extend a cookie's expiration without changing its value. The new refresh option makes this simple (#33814):
const session = useCookie('session-id', {
maxAge: 60 * 60,
refresh: true,
})
// Extends expiration each time, even with the same value
session.value = session.value
♻️ useState Reset to Default
useState and clearNuxtState now support resetting to the initial value instead of clearing to undefined (#33527). This aligns with how useAsyncData handles resets and is more intuitive for state management.
const count = useState('counter', () => 0)
count.value = 42
// Resets to 0 (the init value), not undefined
clearNuxtState('counter')
🕵️♂️ Better Import Protection
Inspired by features in TanStack Start, import protection now shows suggestions and a full trace of where a problematic import originated (#34454). This makes it much easier to debug why a server-only import ended up in your client bundle.
For example, if you accidentally import from a server route in a component:
The trace shows the import chain (the component was imported from a page), the exact line of code, and actionable suggestions for how to fix it.
We plan to continue work on improving our error messages. 🪵
🔮 View Transitions Types
You can now define view transition types in Nuxt's experimental view transitions support (#31982). This lets you use different transition styles for different navigation patterns (forwards vs. backwards, tabs vs. pages, etc.).
💡 Improved optimizeDeps Hints
When Vite discovers new dependencies at runtime and triggers page reloads, Nuxt now shows a clear, copy-pasteable nuxt.config.ts snippet to pre-bundle them (#34320). It also warns about unresolvable entries at startup.
🏷️ Normalised Page Component Names (Experimental)
A new experimental option normalises page component names to match route names (#33513), which can help with consistency in devtools and debugging.
// nuxt.config.ts
export default defineNuxtConfig({
experimental: {
normalizeComponentNames: true,
},
})
⚡ Build Profiling
Ever wondered where your build time goes? You can now get a detailed performance breakdown of your Nuxt builds (#34468, nuxt/cli#1243):
nuxt build --profile
This produces a report showing duration, RSS delta, and heap delta for every build phase, module, and bundler plugin:
It also profiles individual modules and bundler plugins, making it easy to spot bottlenecks. Three output formats are written:
- Chrome Trace (
.nuxt/perf-trace.json) – open inchrome://tracingor Perfetto for a visual timeline - JSON report (
.nuxt/perf-report.json) – machine-readable data for tracking over time - CPU profile (
nuxt-build.cpuprofile) – open in Chrome DevTools or VS Code for flame graphs
For even more detail, use --profile=verbose to print timing breakdowns to the console.
We'll be using this feature to make Nuxt even faster – and if performance is something you care about, this might be a good opportunity to contribute!
🔥 Performance Improvements
- 14,000x faster module ID parsing – replaced
new URL()+ regex chain with a singleindexOf+ slice (#34451) - Disabled NuxtLink visibility prefetching in dev – stops Vite from discovering and reloading deps unnecessarily during development (#34325)
✅ Upgrading
Our recommendation for upgrading is to run:
npx nuxt upgrade --dedupe
This will deduplicate your lockfile and help ensure you pull in updates from other dependencies that Nuxt relies on, particularly in the unjs ecosystem.
Tip: Check out our upgrade guide if upgrading from an older version.
👉 Changelog
🚀 Enhancements
- nuxt: Migrate to unrouting for nuxt file system -> route generation (#34316)
- nuxt: Allow setting layout props in
definePageMeta(#34262) - nuxt: Upgrade to vue-router v5 (#34181)
- nuxt: Add
useAnnouncercomposable and<NuxtAnnouncer>component (#34318) - nuxt: Add reset to default functionality for
useStateandclearNuxtState(#33527) - nuxt,schema: Experimentally normalise page component names to match route (#33513)
- nuxt: Add
refreshoption to useCookie (#33814) - nuxt: Export page composables from
#app/composables/pages(#33453) - vite: Improved optimizeDeps hints (#34320)
- nuxt: Add View Transitions Types support (#31982)
- nuxt: Typed props for
layoutproperty indefinePageMeta(#34409) - deps: Upgrade
hookableto v6 (#33905) - deps: Update to std-env v4 (#34457)
- nitro,nuxt: Add suggestions + trace to import protection (#34454)
- kit,nitro,nuxt,schema,vite: Add build profiling (#34468)
- nuxt,kit,schema: Add a factory function for
useFetchanduseAsyncData(#32300)
🔥 Performance
- nuxt: Disable NuxtLink visibility prefetching in dev mode (#34325)
- nuxt,vite,webpack: Use string parsing for module ids (#34451)
- nitro,schema: Inline payload in HTML for cached routes + add
payloadExtraction: 'client'(#34410)
🩹 Fixes
- schema: Do not bundle types (#34300)
- nuxt: Always inject explicit prerender routes into prerender queue (#34311)
- vite: Resolve package CSS paths in dev manifest (#34303)
- nuxt: Wait for layout transition to finish before scrolling to top (#34206)
- kit: Prevent duplicate
moduleDependenciesoptions (#34330) - nuxt: Retain promise methods after destructuring (#34319)
- nitro: Encode forward slashes in payload (#34375)
- nuxt: Do not cache
_payload.jsonin dev mode (#34365) - nuxt: Accept refs as inputs in
NuxtLink.useLink(#34380) - vite: Add nitro dev handler after vite proxy middleware (#34349)
- nuxt: Hydrate prerendered pages with initial route + replace after hydration (#34211)
- nitro: Escape strings rendered within js payload script tags (d52a4fdd7)
- vite: Recreate ViteNodeServer after config restart (#34396)
- nitro: Allow navigation from error page to external protocols (#34405)
- nitro,nuxt,schema: Don't extract payloads w/
ssr: false(#34327) - nuxt: Replace destr with JSON.parse in cookie encode/decode (#34452)
- vite: Normalise development ssr app stacktrace (#33989)
- vite: Update ssr styles plugin for rolldown compatibility (#34435)
- nuxt: Script block extract regex conflict (#34412)
- vite: Move
rollup-plugin-visualizerto optional peer dep (#34458) - nuxt: Restore island head entries from payload during hydration (#34491)
- kit: Share
asyncNuxtStorageacross kit instances (#34492) - nuxt: Close BroadcastChannel and add error handling in refreshCookie (#34508)
- nuxt: Check file freshness before truncating in cache restore (#34509)
- nuxt: Never preload manifest (#34511)
- nitro: Validate island handler context (#34510)
- nuxt: Pass deleteCount to splice in preloadRouteComponents (#34514)
- nuxt: Fix cookie expiration timeout for long-lived cookies (#34513)
- nuxt: Handle rejected promise in view transition abort (#34515)
💅 Refactors
- nuxt: Nullish coalesce instead of non-null assertions (#34331)
- nitro,vite: Set ssr export conditions + vue feature flags within nitro builder (#34379)
- nitro,nuxt: Add
/h3subpath export for forward-compat (#34383) - nuxt: Use JSON.parse instead of
destr(#34037) - vite: Use vite's
transformWithEsbuildfor analysis (#34447) - nitro,vite: Use babel for experimental decorator support (#34465)
- webpack: Remove unused
event.context.webpackcode (#34502)
📖 Documentation
- Update instructions for typedPages with public hoist pattern (#34285)
- Add alternative editor LSP setup guidance (#34322)
- Improve
<NuxtImg>fetch priority example (#34341) - Update Cloudflare dashboard path (#34372)
- Clarify --preset option in nuxt build command (#34335)
- Add shared/ directory to Nuxt 4 upgrade guide (#34391)
- Update link redirects + reduce checking flakiness (01aa49659)
- Add import for fileURLToPath in example code (#34401)
- Capitalise title (#34395)
- Update testing guide to test-utils v4 (#34408)
- Add pending back for
useFetch+useLazyFetchdocs (#34449) - Correct md heading level (#34467)
- Fix twoslash code examples (#34469)
- Remove duplicated word (5a22feaec)
- Add typed layout props docs (#34507)
🏡 Chore
- Prevent layout shift on banner image readme (#34309)
- Use npmx links 💖 (#34340)
- Use
nuxt/.githubpr template (5502ccd7b) - Update link for nuxt ossf badge (#34406)
- Remove unnecessary workspace resolutions (#34453)
- Migrate npm badges and links to npmx.dev (71eb13c21)
- Publish 4.x releases to
4xandlatesttags (1bc9bfd10) - Enforce consistent return-await usage (#34490)
- vite: Optional chaining for nitroApp.hooks (24a12c810)
- kit: Cast nitroConfig to
any(cc380ba3b) - Expand
engines.nodefollowing #34458 (#34458) - Update
installed-checkandengines.node(0c5869c2d) - Lint (31028d2e0)
✅ Tests
- Add page path gen benchmark (#34315)
- Add dev server benchmark for page route generation (#34323)
- Skip bundle tests when running in stubbed mode (#34450)
- Remove curly braces from inlined css expectations (c9ab2747f)
- Update bundle size (f8e243a57)
- Update bundle size (102f7ffe1)
- Update bundle size (dcebd1800)
🤖 CI
- Optimise ci workflows (#34274)
- Run benchmarks on pushes to
main(6abf31062) - Avoid checkout in
issue-needs-reproduction(7849b34c8) - Merge all issue labelled workflows (fdd30349a)
- Fail fast on matrices for merge groups (1008d3afd)
- More perf optimisations for merge queues (297e4e526)
- Move build step after runtime/unit tests (#34388)
- Update default branches (ba251c697)
- Bump matrix timeout (9026c16c8)
- Give
issues: writepermission to needs-reproduction workflow (ba3412b49) - Include
v5prefix in skip-changelog filter (dbc1a8666) - Don't run actions against release PRs (961589297)
- Run ci on push to 4.x/3.x (9240729e8)
- Only run provenance check on PRs (5ba227449)
❤️ Contributors
- Daniel Roe (@danielroe)
- Ori (@oritwoen)
- Yoshihiro Yamaguchi (@yamachi4416)
- Logan (@iml885203)
- Shiminori (@noriyuki-shimizu)
- Unai Mengual (@owlnai)
- Zoolpex (@Zoolpex)
- Harlan Wilton (@harlan-zw)
- Julien Huang (@huang-julien)
- 山吹色御守 (@KazariEX)
- Max (@onmax)
- Alex Korytskyi (@alex-key)
- abeer0 (@iiio2)
- Johannes Przymusinski (@cngJo)
- Adam Patterson (@adampatterson)
- Florian Heuberger (@Flo0806)
- Lorenzo Fiamingo (@lorenzofiamingo)
- Vida Xie (@9romise)
- Ihor (@riabinkovihor)
- Harm Zeinstra (@Harm-Nullix)
- Roli Bosch (@roli-lpci)
- Fabian Kirchhoff (@fabkho)
- Eduardo San Martin Morote (@posva)
- Henry (@lllomh)
- Davin`GM (@DavinGM)
- Alexander Lichter (@TheAlexLichter)
- Paul Melero (@paulmelero)
- dependabot[bot] (@dependabot[bot])
- Martin Arce (@divagueame)
- edison (@edison1105)
- Bobbie Goede (@BobbieGoede)
- Nemanja Malesija (@nemanjamalesija)
- Damian Głowala (@DamianGlowala)
- David Nahodyl (@Smef)
- Benjamin Canac (@benjamincanac)
How we built the Nuxt MCP server to enable AI assistants to access our documentation through structured data and composable tools.
4.2.1 is the next patch release.
✅ Upgrading
Our recommendation for upgrading is to run:
npx nuxt upgrade --dedupe
This will deduplicate your lockfile as well, and help ensure that you pull in updates from other dependencies that Nuxt relies on, particularly in the unjs ecosystem.
👉 Changelog
🩹 Fixes
- kit,nuxt,schema: Deprecate
ImportPresetWithDeprecation(#33596) - nuxt: Correct warning message for prefetch/noPrefetch conflict (#33617)
- nitro: Remove
<nuxt-error-overlay>iframe border (#33625) - vite: Use rolldown replace only in build (#33615)
- nitro: Use directory paths in
moduleEntryPaths(#33628) - nitro: Start error overlay minimized based on status code (#33658)
- vite: Ensure
optimizeDepsconfig is applied before other plugins (#33586) - nuxt: Respect layer priority order for scanned components (#33654)
- nuxt: Process prerender routes on
pages:resolved(#33662) - nuxt: Remove abort signal event listeners after render (#33665)
- nuxt: Cleanup event listener with cleanup signal (#33667)
- vite: Update
vite-node(#33663) - vite: Respect vite proxy in dev middleware (#33670)
💅 Refactors
- kit,nitro,nuxt,schema,vite: Explicitly import process/performance (#33650)
📖 Documentation
- Fix typo in eslint flat config description (#33569)
- Add signal support to useAsyncData examples (#33601)
- Document
pendingas alias ofstatus === 'pending'(#33221) - Note that
cookieStoreistrueby default (#33572) - Add information on types for server context (#33511)
- Mark webstorm issue resolved (#33608)
- Clarify route middleware doesn't affect API routes (#33643)
- Improve docs for
useHead/useHydration/useLazy*(#33626) - Update link to nitro source to v2 branch (08018af4f)
- Add typescript documentation for module authors (#33637)
- Typo (#33655)
🏡 Chore
- Update URLs (#33567)
- Add
verifyDepsBeforeRun: install(#33603) - Reduce redirects in docs links (1cc539325)
- Lint docs (0b5fa5dea)
🤖 CI
- Disable cache in release action (ff37598bc)
❤️ Contributors
- Daniel Roe (@danielroe)
- Anthony Fu (@antfu)
- Robin (@OrbisK)
- abeer0 (@iiio2)
- Bobbie Goede (@BobbieGoede)
- Florian Heuberger (@Flo0806)
- Matej Černý (@cernymatej)
- Peter Budai (@peterbud)
- Julien Huang (@huang-julien)
- Max (@onmax)
- 纸鹿/Zhilu (@L33Z22L11)
- Hinata Oishi (@te19oishi)
- Damian Głowala (@DamianGlowala)
- Maxime Pauvert (@maximepvrt)
- Raed Abdennadher (@RaedAbr)