The Intuitive Vue Framework.
3.9.1 is a regularly scheduled patch release.
As usual, our recommendation for upgrading is to run:
nuxi upgrade --force
This will refresh your lockfile as well, and ensures that you pull in updates from other dependencies that Nuxt relies on, particularly in the vue and unjs ecosystems.
useRequestHeaders
(#24853)startsWith
to array access (#24744)NuxtErrorBoundary
with ssr: false
(#24896)any
in inferred injections (#25010)<ClientOnly>
(#25009)currentRoute
in Ref
(#25026)nuxt-config-schema
(#25067)features
/future
docs (f5676fba5)vue-router
docs link (#24948)readValidatedBody
and getValidatedQuery
(#24990)getValidatedRouterParams
(#25057)3.9.0 is the next minor release.
A very merry Christmas to you and yours from all Nuxters involved in this release! 🎁🎄
We have lots of features packed into v3.9.0 and can't wait for you to try them out.
This release comes with Vite 5 and Rollup 4 support. Module authors may need to check to ensure that any vite plugins you're creating are compatible with these latest releases.
This comes with a whole host of great improvements and bug fixes - check out the Vite changelog for more info.
This release is tested with the latest Vue 3.4 release candidate, and has the necessary configuration to take advantage of new features in Vue 3.4, including debugging hydration errors in production (just set debug: true
) in your Nuxt config.
👉 To take advantage, just update your vue
version once v3.4 is released, or try out the release candidate today:
{
"dependencies": {
"nuxt": "3.9.0",
"vue": "3.4.0-rc.1",
"vue-router": "latest"
}
}
This is a highly-experimental update, but it's now possible to play around with interactive components within Nuxt server components. You'll need to enable this new feature additionally to component islands:
export default defineNuxtConfig({
experimental: {
componentIslands: {
selectiveClient: true
}
}
})
Now, within a server component, you can specify components to hydrate by using the nuxt-client
directive:
<NuxtLink :to="/" nuxt-client />
We're pretty excited about this one - so do let us know how you're using it! 🙏
We now use Vite's new AST-aware 'define' to perform more accurate replacements on server-side code, meaning code like this will no longer throw an error:
<script setup lang="ts">
if (document) {
console.log(document.querySelector('div'))
}
</script>
This hasn't been possible until now because we haven't wanted to run the risk of accidentally replacing normal words like document
within non-JS parts of your apps. But Vite's new define
functionality is powered by esbuild
and is syntax-aware, so we feel confident in enabling this functionality. Nevertheless, you can opt out if you need to:
export default defineNuxtConfig({
hooks: {
'vite:extendConfig' (config) {
delete config.define!.document
}
}
})
We now have a new hook-based system for <NuxtLoadingIndicator>
, including a useLoadingIndicator
composable that lets you control/stop/start the loading state. You can also hook into page:loading:start
and page:loading:end
if you prefer.
You can read more in the docs and in the original PR (#24010).
callOnce
Sometimes you only want to run code once, no matter how many times you load a page - and you don't want to run it again on the client if it ran on the server.
For this, we have a new utility: callOnce
(#24787).
<script setup>
const websiteConfig = useState('config')
await callOnce(async () => {
console.log('This will only be logged once')
websiteConfig.value = await $fetch('https://my-cms.com/api/website-config')
})
</script>
Note that this utility is context-aware so it must be called in component setup function or Nuxt plugin, as with other Nuxt composables.
For a while now, errors returned by useAsyncData
and useFetch
have been typed pretty generically as Error
. We've significantly improved the type possibilities for them to make them more accurate in terms of what you'll actually receive. (We normalise errors with the h3
createError
utility under the hood, so they can be serialised from server to client, for example.)
We've tried to implement the type change in a backwards compatible way, but you might notice that you need to update the generic if you're manually configuring the generics for these composables. See (#24396) for more information, and do let us know if you experience any issues.
We've taken some time in this release to make some minor performance improvements, so you should notice some things are a bit faster. This is an ongoing project and we have ideas for improving initial load time of the Nuxt dev server.
As usual, our recommendation for upgrading is to run:
nuxi upgrade --force
This will refresh your lockfile as well, and ensures that you pull in updates from other dependencies that Nuxt relies on, particularly in the unjs ecosystem.
<NuxtLayout>
(#24116)addComponentsDir
(#24309)useCookie
(#24503)error.data
when throwing 404 errors (#24674)/module
or /nuxt
module subpath if it exists (#24707)refresh
on islands and server components (#24261)dedupe
option for data fetching composables (#24564)undefined
on server (#24711)addServerScanDir
composable (#24001)setup
within defineComponent
options (#24515)useRequestHeader
utility (#24781)callOnce
util to allow running code only once (#24787)NuxtIsland
(#22649)bundler
module resolution (#22821)toArray
util (#24857)resolve
operation (#24736)join
operation (#24717)get
operations (#24734)useRuntimeConfig
call (#24843)JSON.stringify
operation (#24848)import.d.ts
(#24413)reactivityTransform
(vue 3.4) (#24477)<DevOnly>
(#24511)isBuiltin
polyfill for greater node support (#24512)<NuxtLayout>
usage in islands (#24529)error
in useAsyncData
has correct type (#24396)appManifest
middleware after modules run (#24786)setup
within defineComponent
(#24784)__VUE_PROD_HYDRATION_MISMATCH_DETAILS__
(#24836)mode
from filePath
for addComponent
(#24835)bundler
module resolution due to lack of support (22ce98d61)~/modules
dirs to modulesDir
(#24457)defineComponent
to infer prop types for router-link stub (dc0e8347b)jiti.import
for schema (#24526)process.*
usage in nuxt vue app (#24749)future
and features
namespace (#24880)typedPages
(#24436)defineNuxtConfig
to deployment example (#24451)~
to @
alias in examples (#24574)-o
option to --open
(#24644)<NuxtPage>
(#24675)getCachedData
option (#24697)addServerScanDir
example (7cd02e290)loadNuxt
options (#24201)nuxi module
(#24790)useFetch
and useAsyncData
#24407 (#24775, #24407)addComponentsDir
example to modules author guide (#24876)dev:prepare
instead of build:stub
(802b3e28c)nuxt/bridge
when composables change (#24752)3.8.2 is a patch release focusing on bug fixes
3.8.2 is a patch release and we've deferred some exciting features in our next release (3.9.0, expected in December) but it does bring a significant Nitro minor release: v2.8.0. It's well worth checking out the release notes.
👉 Note that as Nitro has updated to rollup v4, but as Nuxt's vite dependency is still on rollup v3 until v3.9, you may experience type mismatches in modules or your projects if you are dependent on particular rollup plugins or plugin types.
As usual, our recommendation for upgrading is to run:
nuxi upgrade --force
This will refresh your lockfile as well, and ensures that you pull in updates from other dependencies that Nuxt relies on, particularly in the unjs ecosystem.
transformAssetUrls
(#24173)createError
(#24093)plugins.d.ts
if they will be written (#23943)typeof
optimisations (#23903)KeepAlive
cache (#24024)runtimeConfig
type hints (#23696)useFetch
key (#24307)useFetch
key from headers (#23462, #24333)ignoreOptions
(#24337)useFetch
(#24364)useCookie
timeout (#24253)app:error
(#24376)import.meta
(#24186).nuxtrc
in nuxt/starter
(56147b4a8)defineNuxtPlugin
syntax in bridge migration (#23036)nuxt3-vuex-module
in migration guide (#24260).gitignore
in directory structure (#24338)app.config
placement with custom srcDir
(#24252)<ContentDoc>
in example (#24244)@nuxt/kit-nightly
in example (bdedc3207)nuxi-edge
to nuxi-nightly
(#24347)@nuxt/test-utils
to separate repo (#24146)repository
fields in package.json
(54529c17d)package.json
s (#24189)@nuxt/eslint-config
(#24209)3.8.1 is a patch release focused on bug fixes and performance improvements.
pages
on nuxt app and deduplicate calls (#24032)extends
(#23795)target: blank
links with base (#23751)std-env
to detect whether app is being tested (#23830).json
extension for server components (#23802)@unhead/vue
in template code (#23858)baseURL
(#23884)cloneDeep
again (#23888)$fetch
at entry start (#23906)postcss-url
and duplicate postcss-import
(#23861)useCookie
value when it expires (#23549)h3
cors handler for vite routes only (#23995)addServerImportsDir
implementation (#24000)isChangingPage
util in scrollBehavior (#24091)useCookie
(#24043)ClientFallback
(#24086)typeCheck
plugin (#24114)useRequestEvent()
internally (#23916)useFetch
key generation logic (#24082)addPrerenderRoutes
name (#24102)NuxtIsland
(#23801)webpack
has it in core (#23703)We have a lot of exciting features in v3.8, and can't wait for you to try it out.
Just to remind you, we're now using the new Nuxt CLI which is now versioned separately. There are some exciting improvements there to follow, so do check out the latest releases. (For example, we now share the same port with the Vite websocket, meaning better support for docker containers in development.)
Nuxt DevTools v1.0.0 is out and we now think it's ready to be shipped as a direct dependency of Nuxt.
👉 You can check out the release notes for more information - and stay tuned for an article detailing our roadmap for the future.
We've now made <NuxtImg>
and <NuxtPicture>
first-class built-in components, documenting them and auto-installing @nuxt/image
the first time that they are used (#23717).
https://github.com/nuxt/nuxt/assets/28706372/597c9307-5741-4d9c-8eab-aad5bfef2ef2
We would definitely advise using @nuxt/image
if you're using images in your site; it can apply optimisations to make your site more performant.
🚨 This is a behaviour change so do take care with this one: 🚨
We now support scanning layouts within subfolders in ~/layouts
in the same way as we do with ~/components
.
File | Layout name |
---|---|
~/layouts/desktop/default.vue | 'desktop-default' |
~/layouts/desktop-base/base.vue | 'desktop-base' |
~/layouts/desktop/index.vue | 'desktop' |
See #20190 for more information
We now support a built-in app manifest (see #21641), which generates a manifest at /_nuxt/builds/meta/<buildId>.json
.
Initially this enables loading payloads only for prerendered routes, if a site is static (preventing 404s). It also enables client-side route rules. To begin with, only redirect
route rules will have an effect; they will now redirect when performing client-side navigation. (More coming soon...!)
The app manifest also enables future enhancements including detection of outdated deployments by checking /_nuxt/builds/latest.json
.
You can switch off this behaviour if you need to (but do let us know if you have any issues):
export default defineNuxtConfig({
experimental: {
appManifest: false
}
})
We now define a 'scope' for Nuxt composables executed in plugins (#23667), which allows running synchronous cleanup before navigating away from your site, using the Vue onScopeDispose
lifecycle method. This should fix an edge case with cookies (#23697) and also improves memory management, for example in Pinia stores (#23650). You can read more about Vue effect scopes.
We also now support native async context for the Vue composition API (#23526). In case you're unaware, we support native async context on Node and Bun, enabled with experimental.asyncContext
. This can help address issues with missing a Nuxt instance. But it didn't previously affect missing Vue instances.
If you experience issues with 'Nuxt instance unavailable', enabling this option may solve your issues, and once we have cross-runtime support we are likely to enable it by default.
export default defineNuxtConfig({
experimental: {
asyncContext: true
}
})
We've supported defining your own NuxtLink
components with the defineNuxtLink
utility. We now support customising the options for the built-in <NuxtLink>
, directly in your nuxt.config
file (#23724). This can enable you to enforce trailing slash behaviour across your entire site, for example.
export default defineNuxtConfig({
experimental: {
defaults: {
nuxtLink: {
activeClass: 'nuxt-link-active',
trailingSlash: 'append'
}
}
}
})
We have two very significant new features for useAsyncData
and useFetch
:
deep: false
to prevent deep reactivity on the data
object returned from these composables (#23600). It should be a performance improvement if you are returning large arrays or objects. The object will still update when refetched; it just won't trigger reactive effects if you change a property deep within the data
.getCachedData
option to handle custom caching for these composables (#20747)const nuxtApp = useNuxtApp()
const { data } = await useAsyncData(() => { /* fetcher */ }, {
// this will not refetch if the key exists in the payload
getCachedData: key => nuxtApp.payload.static[key] ?? nuxtApp.payload.data[key]
})
We also support configuring some default values for these composables in an app-wide way (#23725):
export default defineNuxtConfig({
experimental: {
defaults: {
useAsyncData: {
deep: false
},
useFetch: {
retry: false,
retryDelay: 100,
retryStatusCodes: [500],
timeout: 100
}
}
}
})
We now more carefully load layer plugins (#22889 and #23148) and middleware (#22925 and #23552) in the order of the layers, always loading your own plugins and middleware last. This should mean you can rely on utilities that layers may inject.
We've also added a test suite to cover these layer resolution changes.
And probably one of the most significant changes - if you are using remote layers we now clone these within your node_modules/
folder (#109) so layers can use dependencies with your project. See c12
release notes for full details.
Every commit to the main
branch of Nuxt is automatically deployed to a new release, for easier testing before releases. We've renamed this from the 'edge release channel' to the 'nightly release channel' to avoid confusion with edge deployments. And probably also with Microsoft Edge (though I haven't heard that anyone was confused with that one!)
➡️ nuxt3
is now nuxt-nightly
➡️ nuxi-edge
is now nuxi-nightly
➡️ @nuxt/kit-edge
is now @nuxt/kit-nightly
... and so on.
You can read more about how it works.
Nitro v2.7 has been released with lots of improvements and bug fixes - do check out the full changelog.
🔥 One of the most significant is that we now save ~40% of bundle size in production by using native fetch
(which is supported in Node 18+) (#1724). So if possible, we'd recommend you update your Node version to at least 18.
🚨 This is likely to need code changes in your project 🚨
Vue requires that type imports be explicit (so that the Vue compiler can correctly optimise and resolve type imports for props and so on). See core Vue tsconfig.json
.
We've therefore taken the decision to turn on verbatimModuleSyntax
by default in Nuxt projects, which will throw a type error if types are imported without an explicit type
import. To resolve it you will need to update your imports:
- import { someFunction, SomeOptions } from 'some-library'
+ import { someFunction } from 'some-library'
+ import type { SomeOptions } from 'some-library'
You may also encounter modules in the Nuxt ecosystem that need to be updated; please open an issue for those modules. I'm also very happy to help if you're encountering any problems with this, if you're a module author. Just tag me and I'll take a look.
If for whatever reason you need to undo this change in your project you can set the following configuration:
export default defineNuxtConfig({
typescript: {
tsConfig: {
compilerOptions: {
verbatimModuleSyntax: false
}
}
}
})
However, we'd recommend only doing that temporarily, as Vue does need this option to be set for best results.
As usual, our recommendation for upgrading is to run:
nuxi upgrade
addServerImports
and addServerImportsDir
(#23288)prerenderRoutes
ssr composable (#22863)appManifest
by default (#23448)withAsyncContext
(#23526)-nightly
extension (#23508)@nuxt/devtools
as dependency and enable (#23576)deep: false
for data composables (#23600)@nuxt/image
when it is used (#23717)<NuxtLink>
options (#23724)asyncData
errors with null
(#23428)vue-router
(#23440)config.autoImport
in addServerImports
(#23472)clearNuxtState
called w/o keys (#23483)addPrerenderRoutes
name (#23509)test
/dev
as manifest buildId when appropriate (#23512)<DevOnly>
(#23466)useFetch
(#23693)lodash-es
+ simplify postcss resolution (#23692)useAsyncData
(#23351)prerenderedAt
to override app manifest (#23781)prerenderedAt
behaviour pending next patch (108b1bdf7)listhen
options on nuxi dev page (#23415)handler
for useAsyncData
(#23389)nitro
to use runtimeConfig
(#23454)bridge.typescript
option must be set. (#23503)nuxt kit
section (#22375)/edge-channel
page to /nightly-release-channel
(#23648)routeRules
example (818dc626c)<NuxtImg>
and <NuxtPicture>
(#23741)3.7.4 is a regularly scheduled patch release.
As usual, our recommendation for upgrading is to run:
nuxi upgrade
nuxt/*
exports (#23357)consola
and improve test dx (#23302)nuxt2
command (#23211)code-block
in migration guide (#23224)callHook
method (#23231)srcDir
JSDoc (#23250)nuxtApp.runWithContext
(#23258)devtools.nuxt.com
(#23350)await
to clarify sendRedirect
is async (#23345)tryUseNuxt
to kit context utils list (#23373)linkChecker
job to link-checker
(#23319)3.7.3 is a hotfix release to address a regression introduced in 3.7.2.
#components
(#23188)3.7.2 is a regularly scheduled patch release.
As usual, our recommendation for upgrading is to run:
nuxi upgrade
joinURL
with remote sources on NuxtIsland (#23093)data-v
attrs from server component props (#23095)useFetch
auto key (#23086)cssCodeSplit
(#23049)spaLoadingTemplate
if file exists (#23048)tsconfig.json
defaults (#23121)0
(#23127)name
param to PageMeta
interface description (#23107)experimental.componentIslands
(#23138)nuxi init
command (#23155)3.7.1 is a regularly scheduled patch release.
As usual, our recommendation for upgrading is to run:
nuxi upgrade --force
This will refresh your lockfile as well, and ensures that you pull in updates from other dependencies that Nuxt relies on, particularly in the unjs ecosystem.
ssr: false
(#22869)priority
when registering components dirs (#22882)addLayout
(#22902)true
(#22905)write: false
for type templates (#22972)shouldExternalize
(#22991)destr
in more places over JSON.parse
(#22997)<NuxtPage>
(#22912)pageKey
(#22920)env
object for nuxt plugins (#22963)NuxtLayout
(#22989)GITHUB_REF_NAME
to get branch for release (d49ea58de)