Telerik blogs

Wondering how Nuxt 3 differs from Nuxt 2? Or afraid you’re missing something new in Nuxt 3? Here’s 100 tips and updates worth noting, in handy categories for easy skimming.

I have spent the last few days reading the entire Nuxt 3 documentation thanks to Raindrop. I took notes about the things I found interesting, but there were so many of them. Ultimately, I got tens of pages of valuable content but didn’t know how to structure it. Then, I got an idea. 🤩

What if I wrote a blog post about the 100 things you should know about Nuxt 3? I could share my notes with you, organized by categories, with little tips that are easy to digest. 🙌

It’s a win-win situation because even if you are familiar with Nuxt 3, you will learn something new. On the other hand, if you are coming from Nuxt 2, this article will help you to get up to speed with the new version and feel confident you are getting everything. 🚀

Are you ready? Let’s dive in! 🏄‍♀️

The Nuxt 3 Basics & Internal Changes vs. Nuxt 2

1/ Vue 3 is what is used behind the background. FYI, Vue 2 and Nuxt 2 will be deprecated in December 2023. 😅

2/ The composition API is now the new standard, but you can still use the options API. The composition API is easier to test and provides a better TypeScript experience. So declare your components using the <script setup lang= "ts">.

3/ If you prefer to use the options API, you must use the defineNuxtComponent helper. It is similar to the defineComponent helper but also provides the asyncData, fetch, and head methods. You can learn more about it here.

4/ The framework has been rewritten with TypeScript, drastically improving developer experience by writing type-safe code. Nuxt 3 comes with zero-config TypeScript support and auto-generate types. TypeScript is one of the main reasons why it is recommended to use the composition API to better benefit from it.

5/ A focus has been put on bundle size reduction. Vue’s functionality, including template directives or built-in components, is tree-shakable. Your production bundle will not ship them if you don’t use them. 👍

6/ They also moved from a runtime Nuxt dependency to a minimal, standalone server compiled with nitropack.

7/ The virtual dom has also been rewritten to be faster and smaller to get faster server-side rendering and less memory usage.

8/ Nuxt 2 uses webpack 4 and Babel, but Nuxt 3 switched to Vite (or webpack 5) and esbuild.

9/ Vite is the default choice. It supports hot module replacement (HMR) in development and can bundle your code in production. You can still use webpack 5, but Vite is fast and getting increasingly popular (especially for those who had to configure webpack once in their life 😅).

10/ A new server engine fuels Nuxt 3, Nitro, offering cross-platform support for Node.js, browsers, service workers and more, while also providing serverless support, API routes, automatic code-splitting, async-loaded chunks, a hybrid mode for static and serverless sites, and a development server with hot module reloading.

11/ Nitro allows you to build an API. It creates routes by reading files in server/api/ and server middleware from server/middleware/. You can generate one light, minified, and optimized .output/ directory to release in production on any system supporting JavaScript (Node, serverless, workers, edge-side rendering, etc.).

12/ A key feature of Nuxt 3 is its support for layers and extensions, enabling you to expand a default Nuxt application to reuse components, utilities, and configurations. The layers structure closely resembles a standard Nuxt application, making creating and maintaining straightforwardly.

13/ In Nuxt 2, the server is not standalone and relies on the part of the Nuxt core when running nuxt start (with the nuxt-start or nuxt distributions) or through custom programmatic usage. This approach is fragile and unsuitable for serverless and service-worker environments. In contrast, Nuxt 3 generates a standalone dist when running nuxt build into the .output directory. This output includes runtime code to run your Nuxt server in any environment (even experimental browser service workers!) and serve your static files, positioning it as a proper hybrid framework for the Jamstack. Furthermore, Nuxt introduces a native storage layer that supports multi-source drivers and local assets.

14/ Nuxt also offers a Virtual File System (VFS) that enables modules to add templates to this directory without writing them to disk. You can explore the generated files by accessing http://localhost:3000/_vfs.

15/ Nuxt offers a powerful hooking system to expand almost every aspect of the application using hooks. This feature is powered by unjs/hookable, allowing you to add custom hooks to modify the behavior of various application parts. You can use built-in hooks provided by Nuxt or create your hooks to add new functionality to your application. This provides much flexibility and makes it easier to customize and extend Nuxt to fit your needs. 😃

State Management

16/ Previously, Nuxt depended on the Vuex library for global state management. Nuxt 3 doesn’t prescribe a specific state management method so that you can choose the best solution. There are multiple integrations with well-known state management libraries, including Pinia (the official Vue recommendation), Harlem (immutable global state management) or XState (state machine approach with tools for visualizing and testing your state logic).

17/ Nuxt offers the useState composable for creating a reactive, SSR-compatible shared state across components. useState is an SSR-friendly alternative to ref. Its value is preserved after server-side rendering (during client-side hydration) and is shared among all components using a unique key. 🤩

Nuxt 2 Migrations

18/ There is a layer called Nuxt Bridge that you can use to ease the migration from Nuxt 2 to Nuxt 3. You can take a look, but I’ve heard many people from the community and the core team saying that it is better to start from scratch, especially if you have to rewrite your components with the composition API and TypeScript.

19/ Considering migration? Allocate a few days to write comprehensive tests using Cypress before proceeding with the code migration. It will help you catch regressions and be more confident about the migration. This is precisely the first thing I would do. 🤓

After converting your codebase to TypeScript and becoming comfortable with it, you can enable stricter checks for increased safety (read more). To help strict type checking, update nuxt.config as follows:

export default defineNuxtConfig({
  typescript: {
    strict: true

Developer Experience (DX) & TypeScript

20/ They recently released an official Nuxt devtools to improve your developer experience. You can see all your application pages, components, imports, modules, hooks and much more. 😄

21/ You have to use the Volar extension for VS Code (instead of Vetur) to get the best experience with the takeover Mode.

22/ You have starter templates and themes to quickly bootstrap a Nuxt application, a module, a content-driven website or a Nuxt layer. Everything is accessible at

23/ A new command line interface is called Nuxi. It is like the Vue CLI but for Nuxt. A CLI allows you to add modules, plugins, components, pages, etc., to your project. It is also possible to use it to create a new project. 😎

24/ Do you know all the Nuxi commands? Here is the list. 💁‍♀️

# Nuxi commands

npx nuxi add [--cwd] [--force] <TEMPLATE> <NAME>          # generates a component, composable, layout, plugin, page, middleware or api function.
npx nuxi analyze [--log-level] [rootDir]                  # builds Nuxt and analyzes the production bundle (experimental).
npx nuxi build-module [--stub] [rootDir]                  # runs @nuxt/module-builder to generate dist directory within your rootDir that contains the full build for your nuxt-module.
npx nuxi build [--prerender] [--dotenv] [--log-level] [rootDir] # creates a .output directory with all your application, server and dependencies ready for production.
npx nuxi clean|cleanup [rootDir]                          # removes common generated Nuxt files and caches
npx nuxi dev [rootDir] [--dotenv] [--log-level] [--clipboard] [--open, -o] [--no-clear] [--port, -p] [--host, -h] [--https] [--ssl-cert] [--ssl-key]                                  # starts a development server with hot module replacement
npx nuxi devtools enable|disable [rootDir]                # will install the Nuxt DevTools globally, and also enable it within the particular project you are using
npx nuxi info [rootDir]                                   # logs information about the current or specified Nuxt project.
npx nuxi init|create [--verbose|-v] [--template,-t] [dir] # initializes a fresh Nuxt project using unjs/giget.
npx nuxi prepare [--log-level] [rootDir]                  # creates a .nuxt directory in your application and generates types.
npx nuxi preview [rootDir] [--dotenv]                     # starts a server to preview your Nuxt application after running the build command.
npx nuxi typecheck [--log-level] [rootDir]                # runs vue-tsc to check types throughout your app.
npx nuxi upgrade [--force|-f]                             # upgrades Nuxt 3 to the latest version.

25/ By default, Nuxt omits type-checking during nuxi dev or nuxi build execution for performance optimization. However, you can activate type-checking during build or development by installing @types/node, vue-tsc, and typescript as devDependencies. You can either enable the typescript.typeCheck option in your nuxt.config file or manually check your types with nuxi by running yarn nuxi typecheck.

26/ Nuxt automatically generates a .nuxt/tsconfig.json file containing resolved aliases used in your Nuxt project, along with other practical defaults. Create a tsconfig.json file in your project’s root directory with the following content to use this feature. This configuration will ensure that your project benefits from the automatically generated settings and simplifies TypeScript usage in your Nuxt application.

  "extends": "./.nuxt/tsconfig.json"

27/ The .nuxt/nuxt.d.ts file contains the types of any modules used, along with the primary types that Nuxt 3 requires, enabling automatic recognition of these types in your IDE.

28/ Nitro automatically generates types for API routes, and Nuxt generates types for globally available components and auto-imports them from your composables, along with other core functionalities.

Application Structure

29/ Like in Nuxt 2, you can use layouts defined in the layouts/ directory. Just keep in mind that if you only have a single layout in your application, it is recommended to use app.vue with the <NuxtPage /> component instead and forget about the layouts/ directory.

30/ They have detailed the entire directory structure in the guide. It might be helpful to browse the navigation to understand at least better.

31/ Nuxt seamlessly imports components located in the components/ directory and any components registered by modules you might be utilizing.

32/ Out of the box, only the ~/components directory undergoes scanning. To include additional directories or modify the component scanning process within a subfolder of this directory, you can update the configuration to encompass these changes.

33/ Nuxt 3 leverages the utils/ directory to enable the automatic import of helper functions and other utilities in your app via auto-imports. This directory serves as a semantic separation between your Vue composables and other auto-imported utility functions. 🙂

34/ Remember that these utils are only available within the Vue part of your app. Instead, they auto import exported functions and variables from ~/server/utils within the server directory.

35/ In Nuxt 3, the pages/ directory is optional, which means that if it is not present, Nuxt will not include the vue-router dependency. This is especially useful when working on a landing page or an application that does not require routing.

36/ Route middleware runs within the Vue part of your Nuxt app. Despite the similar name, they are entirely different from server middleware, which runs in your app’s Nitro server part.

37/ The .nuxtignore file allows Nuxt to disregard layouts, pages, components, composables, and middleware files within your project’s root directory (rootDir) during the build process. The .nuxtignore file follows the exact specification as .gitignore and .eslintignore files, with each line representing a glob pattern that specifies which files should be excluded from the build. 🤓

38/ Nuxt 3 still uses two directories to handle assets like stylesheets, fonts or images. The public/ directory content is served at the server root as-is. The assets/ directory contains, by convention, every asset you want the build tool (Vite or webpack) to process.

Pages & Components

39/ Nuxt enables route validation through the validate property in definePageMeta for each page you want to validate. The validate property takes the route as an argument, and you can return a boolean value to decide if the route should be rendered with this page. Returning false will trigger a 404 error if no other match is found. Alternatively, you can return an object containing statusCode/statusMessage to respond with an error immediately (bypassing further match checks). For more complex use cases, consider using anonymous route middleware.

<script setup>
  validate: async (route) => {
    // Check if the id is made up of digits
    return /^\d+$/.test(

40/ Nuxt offers <Title>, <Base>, <NoScript>, <Style>, <Meta>, <Link>, <Body>, <Html> and <Head> components, allowing you to interact directly with your metadata within your component’s template.

41/ The useHead composable function, powered by Unhead, enables you to manage head tags programmatically and reactively.

42/ In most cases, meta tags don’t need to be reactive since robots typically scan only the initial load. Therefore, we recommend using useServerSeoMeta as a performance-centric utility that won’t perform any action or return a head object on the client side.

43/ You can find a list of all Nuxt.js lifecycle hooks in the official documentation at the following link.

44/ Nuxt offers a <NuxtErrorBoundary> component to manage client-side errors within your app without replacing your entire site with an error page. This component handles errors occurring within its default slot, and on the client side, it prevents the error from propagating to the top level, rendering the #error slot instead. The #error slot receives the error as a prop. Setting the error to null triggers the default slot’s re-rendering; however, ensure the error is resolved first to avoid rendering the error slot again. What’s great is that navigating to a different route automatically clears the error. 😃

45/ If you want to auto-import components based only on their name rather than their path, you can set the pathPrefix option to false in the extended form of the configuration object in your nuxt.config.js file. This example will import components based on their name, not prefix them with the directory name.

export default defineNuxtConfig({
  components: [
      path: '~/components',
      pathPrefix: false,

46/ To automatically prefix or change the prefix of your components, use the following code in your nuxt.config.js file. This example adds the prefix “Special” to components in the ~/components/special-components directory and imports components from the default ~/components directory without a prefix.

export default defineNuxtConfig({
  components: [
      path: '~/components/special-components',
      prefix: 'Special'

47/ To dynamically import a component (lazy-loading a component), add the Lazy prefix to the component’s name in your template. This approach is handy if the component is only sometimes needed. Using the Lazy prefix, you can delay loading the component code until the appropriate moment, which can help optimize your JavaScript bundle size.

    <TheHeader />
    <slot />
    <LazyTheFooter />

48/ If you want to use the Vue <component :is= "someComputedComponent"> syntax, then you will need to use the resolveComponent helper provided by Vue.

49/ You can also explicitly import components from #components if you want or need to bypass Nuxt’s auto-importing functionality. 🤓

50/ If a component is intended to be rendered only on the client side, add the .client suffix to the component file name. .client components are rendered only after being mounted. To access the rendered template using the onMounted() hook, you can add await nextTick() in the callback of the onMounted() hook:

import { onMounted, nextTick } from 'vue';

export default {
  setup() {
    onMounted(async () => {
      await nextTick();
      // Access rendered .client component here

51/ .server components can either be used on their own, where they will always be rendered on the server, or paired with a .client component. When the props of a standalone server component update, it will result in a network request to update the rendered HTML. Note that Server components are currently experimental. To use them, you need to enable the “component islands” feature in your nuxt.config by setting componentIslands: true under the experimental key.

export default defineNuxtConfig({ 
  experimental: { 
    componentIslands: true 

52/ <NuxtPage> is a wrapper component for Vue Router’s <RouterView> component. It accepts the same name and route props, enabling seamless integration and functionality within the Nuxt.js framework.

53/ The <NuxtLayout />component renders incoming content through the <slot /> element. This content is subsequently enclosed within Vue’s <Transition /> component to enable layout transitions. To ensure optimal performance, it is advised that <NuxtLayout /> should not be the root element of the page component.

54/ To customize <NuxtLink> defaults, create your link component using the defineNuxtLink function, allowing for tailored functionality and appearance while maintaining the core features of the original component.

55/ Nuxt offers a <DevOnly> component that allows you to render a component exclusively during development. This component will not be included in production builds and is tree-shaken, ensuring that it won’t add any extra overhead to your app.

    <Sidebar />
      <!-- this component will only be rendered during development -->
      <LazyDebugBar />

56/ Nuxt offers the <NuxtClientFallback> component to display its content on the client side in case any of its children cause an error during SSR, and you can define a fallback tag to be rendered if it fails to render on the server.

    <Sidebar />
    <!-- this component will be rendered on client-side -->
    <NuxtClientFallback fallback-tag="span">
      <Comments />
      <BrokeInSSR />

57/ The <Teleport> component teleports a component to a different location in the DOM.

<Teleport to="body">
  <div v-if="open" class="modal">
    <p>Hello from the modal!</p>
    <button @click="open = false">

58/ The <NuxtLoadingIndicator> displays a progress bar on page navigation. 🤩

59/ Nuxt 3 still leverages Vue’s <Transition> component to apply transitions between pages and layouts. You can read more about Vue Transition here.

Data Fetching

60/ In certain situations, you should make direct API calls. Nuxt 3 offers a globally accessible $fetch method which shares the same API as the Fetch API. Utilizing $fetch comes with several advantages, such as intelligently making direct API calls when running on the server or making client-side calls to your API when running on the client (as well as handling third-party API calls). Furthermore, it includes convenient features like automatically parsing responses and stringifying data. More information about Fetch API is available here.

61/ $fetch is the preferred way to make HTTP calls in Nuxt instead of @nuxt/http and @nuxtjs/axios made for Nuxt 2. 😅

62/ You may be wondering about the distinction between useFetch and useAsyncData. Concisely, useFetch takes a URL and retrieves the data, while useAsyncData may involve more complex logic. Essentially, useFetch(url) is comparable to useAsyncData(url, () => $fetch(url)), serving as a convenient shortcut for the most frequent use cases.

63/ Nuxt utilizes ofetch to make the $fetch helper available globally, enabling you to perform HTTP requests within your Vue app or API routes.

64/ The $fetch API implemented by Nuxt is powered by ofetch ( Key features of ofetch include: Automatic parsing of JSON responses, with the option to access the raw response if needed. Request body and parameters are automatically handled, with appropriate Content-Type headers set automatically. This ensures that data is transmitted correctly and optimally, simplifying the process of interacting with external APIs or services in your application.

65/ When planning to use specific keys (like only title and description) in your component, you can select the keys by chaining the result of $fetch or using the pick option:

<script setup>
const { data: movies } = await useFetch('/api/netflix/romance', { pick: ['title', 'description'] })

66/ When invoking $fetch within the browser, user-specific headers such as cookies are automatically transmitted to the API. However, during server-side rendering, the $fetch request occurs internally on the server and therefore does not incorporate the user’s browser cookies or relay cookies received from the fetch response.

67/ When using $fetch in components without wrapping it with useAsyncData, the data will be fetched twice. Initially, the data will be fetched on the server, and during hydration, it will be fetched again on the client side since $fetch does not transfer state from the server to the client. As a result, the data will be fetched twice, once on the server and once on the client, leading to poor performance and inefficiencies. To avoid double data fetching, it’s recommended to use useFetch or useAsyncData in conjunction with $fetch when fetching component data. These approaches provide optimal performance by ensuring that data is fetched only once on the server or client side, depending on the context.

68/ Server API endpoints and middleware are added by Nitro that internally uses h3.

69/ In Nitro, it’s possible to directly call routes using the globally available $fetch helper. This will trigger an API call to the server when executed in the browser. However, when executed on the server, it will directly call the relevant function, which can save an additional API call and enhance performance. This feature streamlines the process of calling routes and simplifies server-side logic. 🤓

70/ You can refresh specific data. This example below refreshes only data where the key matches to count.

    {{ pending ? 'Loading': count }}
  <button @click="refresh">Refresh</button>

<script setup>
  const { pending, data: count } = useLazyAsyncData('count', () => $fetch('/api/count'))
  const refresh = () => refreshNuxtData('count')

Application Performance & Testing

71/ As a <NuxtLink> comes into view on the client side, Nuxt proactively fetches components and payload (created pages) for the linked pages, leading to a swifter browsing experience.

72/ The process of transforming a static page into an interactive one within the browser is referred to as “Hydration.”

73/ The preloadRouteComponents function enables manual preloading of individual pages within your Nuxt app, allowing you to optimize performance by loading components of a given route that the user may potentially navigate to in the future. As a result, these components are readily available and less likely to obstruct navigation. It’s worth noting that Nuxt automatically preloads the required routes when using the NuxtLink component, streamlining the process and enhancing performance by default.

74/ Throughout a component’s lifecycle, Vue monitors the temporary instance of the current component, while Nuxt similarly tracks a temporary instance of nuxtApp, using a global variable. This variable is then unset within the same tick. This mechanism ensures proper isolation and prevents potential data leaks during server-side rendering. This process is crucial for server rendering to prevent cross-request state pollution, which could result in a shared reference leak between two users or unintended information sharing between different components.

75/ The Nuxt 3 core team have rewritten @nuxt/test-utils. It supports Vitest and Jest as test runners. This is the recommended way to test your components.

Application Configuration

76/ If you need to figure out all the configuration options you can use in nuxt.config.ts, they have made a page that explains the complete list of options. 😉

77/ You will find out that there are two types of configuration to expose variables to your application: runtimeConfig and app.config. But what’s the difference between one or the other? runtimeConfig is for private or public tokens that need to be specified after build using environment variables. app.config is for public tokens that are determined at build time, website configuration such as theme variant, title and any project config that are not sensitive.

78/ Nuxt offers a runtime configuration API that allows you to reveal and manage settings within your application and server routes. This API enables runtime updates to the configuration by setting environment variables, providing greater flexibility and adaptability for your application. 🤓

79/ Variables accessible exclusively on the server should be placed directly within runtimeConfig. For variables that need to be accessible on both the client and server sides, they should be defined under runtimeConfig.public, ensuring broad availability across the application environment.

80/ You can update runtime config values by utilizing corresponding environment variable names with the ‘NUXT_’ prefix, providing an easy method for adjusting configurations.

81/ Nuxt 3 introduces the app.config configuration file, which enables you to expose reactive configurations within your application. This feature allows you to update the configuration at runtime during lifecycle events or by editing a Nuxt plugin with HMR (hot-module-replacement). You can supply runtime app configuration effortlessly by creating an app.config.ts file. This file can have .ts, .js or .mjs extensions, depending on your preference. Avoid including sensitive information in the app.config file, as it is exposed to the user client bundle and can pose security risks.

Composables & Utils

82/ The useRouter composable includes afterEach, beforeEach and beforeResolve helper methods that function as navigation guards. Nevertheless, Nuxt introduces the concept of route middleware, which streamlines the implementation of navigation guards and enhances the overall developer experience.

83/ The useRequestHeaders function enables us to access and proxy the authorization header from the initial request to any subsequent internal requests during server-side rendering (SSR), ensuring a seamless flow of authentication information.

84/ Nuxt comes with a lot of composables. Do you know all of them? I have summarized them all below. 😇

// Composables
useAppConfig()       // Access the reactive app config defined in the project.
useAsyncData()       // Within your pages, components, and plugins you can use useAsyncData to get access to data that resolve asynchronously.
useCookie()          // Within your pages, components, and plugins, you can use useCookie, an SSR-friendly composable to rewrite cookies.
useError()           // Returns the global Nuxt error that is being handled, and it is available on both the client and server.
useFetch()           // Provides a convenient wrapper around useAsyncData and $fetch. It automatically generates a key on URL and fetch options, provides type hints for request url based on server routes, and infers API response type.
useHeadSafe()        // A wrapper around the useHead composable that restricts the input only to allow safe values.
useHead()            // Allows you to manage your head tags in a programmatic and reactive way
useHydration()       // Allows full control of the hydration cycle to set and receive data from the server.
useLazyAsyncData()   // Provides a wrapper around useAsyncData that triggers navigation before the handler is resolved
useLazyFetch()       // Provides a wrapper around useFetch that triggers navigation before the handler is resolved.
useNuxtApp()         // Provides a way to access shared runtime context of Nuxt, which is available on both client and server side.
useNuxtData()        // Gives you access to the current cached value of useAsyncData, useLazyAsyncData, useFetch, and lazyFetch with explicitly provided key.
useRequestEvent()    // Within your pages, components, and plugins, you can use useRequestEvent to access the ng request. In the browser, useRequestEvent will return undefined.
useRequestHeaders()  // Access the incoming request headers within your pages, components, and plugins. In the browser, uestHeaders will return an empty object.
useRouter()          // Returns the router instance and must be called in a setup function, plugin, or route middleware.
useRuntimeConfig()   // Expose config variables within your app.
useState()           // An SSR-friendly ref replacement. Its value will be preserved after server-side rendering and shaross all components using a unique key.
useRoute()           // Returns the current route and must be called in a setup function, plugin, or route middleware.

85/ Nuxt also comes with many utils you can use in your application—wondering if you know all of them? I have summarized them all below. 😇

// Nuxt utils
$fetch()                     // helper for making HTTP requests within your Vue app or API routes.
abortNavigation()            // prevents navigation from taking place and throws an error if one is set as a parameter.
addRouteMiddleware()         // dynamically add route middleware in your Nuxt application.
clearError()                 // clear all errors and redirect the user if redirection defined
clearNuxtData()              // delete cached data, error status and pending promises of useAsyncData and useFetch.
createError()                // create an error object with additional metadata. It is usable in both the Vue and Nitro portions of your app, and is meant to be thrown.
defineNuxtComponent()        // helper function for defining type safe Vue components using options API similar to defineComponent().
defineNuxtRouteMiddleware()  // create named route middleware
definePageMeta()             // a compiler macro that you can use to set metadata for your page components
navigateTo()                 // a router helper function that allows programmatically navigating users through your Nuxt application.
onBeforeRouteLeave()         // adds a navigation guard that triggers whenever the component for the current location is about to be left.
onBeforeRouteUpdate()        // adds a navigation guard that triggers whenever the component for the current location is about to be updated.
onNuxtReady()                // allows running a callback after your app has finished initializing. It is ideal for running code that should not block the initial rendering of your app.
prefetchComponents()         // manually prefetch individual components that have been registered globally in your Nuxt app. (By default Nuxt registers these as async components.) You must use the Pascal-cased version of the component name.
preloadComponents()          // manually preload individual components that have been registered globally in your Nuxt app. (By default Nuxt registers these as async components.)
preloadRouteComponents()     // manually preload individual pages in your Nuxt app.
refreshNuxtData()            // re-fetches all data from the server and updates the page as well as invalidates the cache of useAsyncData, useLazyAsyncData, useFetch and useLazyFetch.
reloadNuxtApp()              // perform a hard reload of your app, re-requesting a page and its dependencies from the server.
setPageLayout()              // allows you to dynamically change the layout of a page.
setReponseStatus()           // sets the statusCode (and optionally the statusMessage) of the response.
showError()                  // provides a quick and simple way to show a full-screen error page if needed.
updateAppConfig()            // updates app config using deep assignment.

86/ When you throw an error created using createError on the server-side, it will prompt a full-screen error page, which can be cleared using clearError. On the client side, it will generate a non-fatal error you can manage. If you wish to trigger a full-screen error page on the client side, you can achieve this by setting the property fatal: true.

87/ The onNuxtReady composable enables the execution of a callback once your app has completed its initialization. This is useful for running code to help the app’s initial rendering process. Keep in mind that onNuxtReady operates exclusively on the client side.

Plugins, Modules & Nuxt Kit

88/ When you must find a well-maintained Nuxt module that is compatible with Nuxt 3 (instead of reinventing the wheel), head over the Nuxt 3 module search. The list is getting longer as time flies, and I didn’t know that there was one module for ChatGPT, MeiliSearch and MagicRegexp.

89/ There is now a development kit called @nuxt/kit to create nuxt modules. It provides composable utilities to make interacting with Nuxt Hooks and Nuxt Builder Core easier.

90/ Nuxt Kit utilities are designed explicitly for modules and should not be imported during runtime. They are not intended for use in components, Vue composables, pages, plugins or server routes, as they cater exclusively to module-related functionality.🙂

91/ Nuxt modules have transitioned to being exclusively for build-time, and the buildModules property from Nuxt 2 has been deprecated in preference for the modules property. 🤓

92/ Helpers can be made accessible across all composables and throughout your application, typically through a Nuxt plugin. You can inject helpers by returning an object containing a provide key. In Nuxt 2 plugins, this approach was known as the inject function. For more information, refer to the plugins documentation.

const nuxtApp = useNuxtApp()
nuxtApp.provide('hello', (name) => `Hello ${name}!`)
console.log(nuxtApp.$hello('name')) // Prints "Hello name!"

93/ If you want to create a module for Nuxt, refer to the Module Author Guide for detailed information and guidance. This comprehensive resource will help you understand the process and best practices for developing your own Nuxt module.

94/ You can also see the list of all Nuxt Kit utilities on this page.


95/ A Nuxt application offers versatile deployment options, including hosting on a Node.js server, pre-rendering for static hosting, or deployment to serverless or edge (CDN) environments. 💁‍♀️

96/ If you’re a Deno enthusiast, you’ll be thrilled to know that Nuxt 3 is fully compatible. 🤩

97/ You can now deploy to CDN edge workers. Historically, server-side and universal rendering could only be achieved using Node.js. Nuxt 3 elevates this capability by rendering code directly within CDN edge workers, decreasing latency and costs. More information is available here.

98/ For a compilation of cloud providers compatible with Nuxt 3, please refer to the following list.

99/ Nitro generates a self-contained server distribution that operates independently from node_modules. The output includes an .output/server/index.mjs file, instructing Node.js to treat this file as a native ES module. 🤓

100/ Chunk loading errors may arise from network connectivity issues or new deployments that render previous, hashed JS chunk URLs obsolete. Nuxt includes native support for addressing these errors by executing a hard reload when a chunk fails to load during route navigation. To modify this default behavior, set experimental.emitRouteChunkError to false for complete disablement or to manual if you prefer to manage these errors independently.


Well done! You’ve reached the end of this article. I hope you enjoyed it and learned something new. If you have any questions, please leave them in the comments section below. I’ll be happy to answer them.

You can reach me on Twitter @RifkiNada. And in case you are curious about my work or other articles, you can look at them here 😉

Do you have any other key points to share about Nuxt 3? Let me know in the comments below. 👇

Thank you for reading! 🙏

About the Author

Nada Rifki

Nada is a JavaScript developer who likes to play with UI components to create interfaces with great UX. She specializes in Vue/Nuxt, and loves sharing anything and everything that could help her fellow frontend web developers. Nada also dabbles in digital marketing, dance and Chinese. You can reach her on Twitter @RifkiNadaor come on her website,

Related Posts


Comments are disabled in preview mode.