---
title: "Nuxt 3.17"
description: "Nuxt 3.17 is out - bringing a major reworking of the async data layer, a new built-in component, better warnings, and performance improvements!"
canonical_url: https://nuxt.com/blog/v3-17
last_updated: 2026-04-15
---

# Nuxt 3.17

> Nuxt 3.17 is out - bringing a major reworking of the async data layer, a new built-in component, better warnings, and performance improvements!

## 📊 Data Fetching Improvements

A major reorganization of Nuxt's data fetching layer brings significant improvements to `useAsyncData` and `useFetch`.

Although we have aimed to maintain backward compatibility and put breaking changes behind the `experimental.granularCachedData` flag (disabled by default), we recommend testing your application thoroughly after upgrading. You can also disable `experimental.purgeCachedData` to revert to the previous behavior if you are relying on cached data being available indefinitely after components using `useAsyncData` are unmounted.

<read-more target="_blank" to="https://github.com/nuxt/nuxt/pull/31373">

Read the original PR for full details.

</read-more>

### Consistent Data Across Components

All calls to `useAsyncData` or `useFetch` with the same key now share the underlying refs, ensuring consistency across your application:

```vue
<!-- ComponentA.vue -->
<script setup>
const { data: users, pending } = useAsyncData('users', fetchUsers)
</script>

<!-- ComponentB.vue -->
<script setup>
// This will reference the same data state as ComponentA
const { data: users, status } = useAsyncData('users', fetchUsers)
// When either component refreshes the data, both will update consistently
</script>
```

This solves various issues where components could have inconsistent data states.

### Reactive Keys

You can now use computed refs, plain refs, or getter functions as keys:

```ts
const userId = ref('123')
const { data: user } = useAsyncData(
  computed(() => `user-${userId.value}`),
  () => fetchUser(userId.value)
)

// Changing the userId will automatically trigger a new data fetch
// and clean up the old data if no other components are using it
userId.value = '456'
```

### Optimized Data Refetching

Multiple components watching the same data source will now trigger only a single data fetch when dependencies change:

```ts
// In multiple components:
const { data } = useAsyncData(
  'users', 
  () => $fetch(`/api/users?page=${route.query.page}`),
  { watch: [() => route.query.page] }
)

// When route.query.page changes, only one fetch operation will occur
// All components using this key will update simultaneously
```

## 🎭 Built-In Nuxt Components

### `<NuxtTime>` - A new component for safe time display

We've added a new `<NuxtTime>` component for SSR-safe time display, which resolves hydration mismatches when working with dates ([#31876](https://github.com/nuxt/nuxt/pull/31876)):

```vue
<template>
  <NuxtTime :datetime="Date.now()" />
</template>
```

The component accepts multiple time formats and gracefully handles both client and server rendering.

### Enhanced `<NuxtErrorBoundary>`

The `<NuxtErrorBoundary>` component has been converted to a Single File Component and now exposes `error` and `clearError` from the component - as well as in the error slot types, giving you greater ability to handle errors in your templates and via `useTemplateRef` ([#31847](https://github.com/nuxt/nuxt/pull/31847)):

```vue
<NuxtErrorBoundary @error="handleError">
  <template #error="{ error, clearError }">
    <div>
      <p>{{ error.message }}</p>
      <button @click="clearError">Try again</button>
    </div>
  </template>
  
  <!-- Content that might error -->
  <MyComponent />
</NuxtErrorBoundary>
```

## 🔗 Router Improvements

`<NuxtLink>` now accepts a `trailingSlash` prop, giving you more control over URL formatting ([#31820](https://github.com/nuxt/nuxt/pull/31820)):

```vue
<NuxtLink to="/about" trailing-slash>About</NuxtLink>
<!-- Will render <a href="/about/"> -->
```

## 🔄 Loading Indicator Customization

You can now customize the loading indicator with new props directly on the component ([#31532](https://github.com/nuxt/nuxt/pull/31532)):

- `hideDelay`: Controls how long to wait before hiding the loading bar
- `resetDelay`: Controls how long to wait before resetting loading indicator state

```vue
<template>
  <NuxtLoadingIndicator :hide-delay="500" :reset-delay="300" />
</template>
```

## 📚 Documentation as a Package

The Nuxt documentation is now available as an npm package! You can install `@nuxt/docs` to access the raw markdown and YAML content used to build the documentation website ([#31353](https://github.com/nuxt/nuxt/pull/31353)).

## 💻 Developer Experience Improvements

We've added several warnings to help catch common mistakes:

- Warning when server components don't have a root element [#31365](https://github.com/nuxt/nuxt/pull/31365)
- Warning when using the reserved `runtimeConfig.app` namespace [#31774](https://github.com/nuxt/nuxt/pull/31774)
- Warning when core auto-import presets are overridden [#29971](https://github.com/nuxt/nuxt/pull/29971)
- Error when `definePageMeta` is used more than once in a file [#31634](https://github.com/nuxt/nuxt/pull/31634)

## 🔌 Enhanced Module Development

Module authors will be happy to know:

- A new `experimental.enforceModuleCompatibility` allows Nuxt to throw an error when a module is loaded that isn't compatible with it ([#31657](https://github.com/nuxt/nuxt/pull/31657)). It will be enabled by default in Nuxt v4.
- You can now automatically register every component exported via named exports from a file with `addComponentExports` [#27155](https://github.com/nuxt/nuxt/pull/27155)

## 🔥 Performance Improvements

Several performance improvements have been made:

- Switched to `tinyglobby` for faster file globbing [#31668](https://github.com/nuxt/nuxt/pull/31668)
- Excluded `.data` directory from type-checking for faster builds [#31738](https://github.com/nuxt/nuxt/pull/31738)
- Improved tree-shaking by hoisting the `purgeCachedData` check [#31785](https://github.com/nuxt/nuxt/pull/31785)

## ✅ Upgrading

Our recommendation for upgrading is to run:

```sh
npx nuxi@latest upgrade --dedupe
```

This refreshes your lockfile and pulls in all the latest dependencies that Nuxt relies on, especially from the unjs ecosystem.

## Full release notes

<read-more target="_blank" to="https://github.com/nuxt/nuxt/releases/tag/v3.17.0" icon="i-simple-icons-github">

Read the full release notes of Nuxt `v3.17.0`.

</read-more>

A huge thank you to everyone who's been a part of this release. ❤️
