Learn Nuxt Icon

The Nuxt CLI tool deep dive

Nuxt ships with a CLI tool called nuxi. So far, we have looked at how we can use it to start new projects with the init subcommand. In this article we look at all the other commands that it ships with and how it speeds up a lot of work that we would otherwise be doing manually.

The nuxi add command

When developing with Nuxt we're constantly working on 7 facets of the app:

Presentation Layer

  • Layouts
  • Pages
  • Components

Request Layer

  • Middleware
  • API Routes

Logic Layer

  • Composables
  • Plugins

There are other areas of the app too, but these require a certain amount of boiler plate. Let's look at the manual setup of each, so that we can understand what it is that nuxi does for us.

Layouts with the Nuxi command

In an upcoming section, we'll have a deeper look into .vue file structures, but essentially a layout can be seen as a reusable container for your app's pages and components. In HTML you could imagine a layout as all the stuff around your page's code, for example:

index.html


<!doctype html>
<html lang="en">
  <head>
    <title>My Awesome Site</title>
  </head>
  <body>
    <nav></nav>

    <div id="content">
      <!-- Your content here -->
    </div>

    <footer></footer>
  </body>
</html>

In this example we could look at everything around the content div as a layout. It is convenient for us to only create pages of content that will be rendered inside the content area and reuse the head, navigation, footer etc. for all pages - perhaps just tweaking the title of the page.

In nuxt that file will exist in layouts/default.vue, the naming of these files are significant and Nuxt treats the default.vue file as the layout to be used by default (without needing to tell the page what layout to use).

A layout file corresponding to the above would look something like:

layouts/default.vue


<template>
  <main>
    <nav></nav>

    <slot></slot>

    <footer></footer>
  </main>
</template>

We'll take a deeper dive into layouts a bit later in this course, but essentially the file above is using a <slot></slot> element to mark the area where Nuxt should render your page content. The navbar and the footer will render on every page that uses this layout.

As you can imagine, if your application has many different layouts. E.g. one for the auth page, one for the dashboard, one for the landing page etc. writing this boilerplate each time can become tedious. This is where nuxi steps in to make life easier - all you need to run is:

~


npx nuxi add layout dashboard

This is saying, add a new layout with the name dashboard. It will then create the layouts/dashboard.vue file for you.

Pages with the Nuxi command

Pages have the same .vue file structure as layouts, but they live in pages/<name>.vue. Pages are special in that they are automatically mapped to routes in your browser, for example:


pages/index.vue           - /
pages/home.vue            - /home
pages/dashboard/index.vue - /dashboard
pages/posts/[id].vue      - /posts/<dynamic-id>

We'll take a deeper dive into dynamic paths, but for now just know that the name you give your pages files matter in what the user visits in the browser. Here's an example of a page:

pages/index.vue


<template>
  <div class="container">
    <h1>Welcome to my site!</h1>
  </div>
</template>

This is the content that would be rendered into the <slot> section of your template. To create a new page with the nuxi command, simply do:

~


npx nuxi add page dashboard

This generates pages/dashboard.vue. To create a page with a dynamic path:

~


npx nuxi add page "users/[userId]"

This will generate pages/users/[userId].vue.

Now that you understand the core thing that nuxi replaces, here's what the files, paths and commands look like for all the other layers. Don't worry we'll have dedicated sections to go more into detail about these files and their code.

Components with the Nuxi command

what the file looks like

components/MyNavigation.vue


<template>
  <nav>
    <a>
      <img src="logo.png" />
    </a>
  </nav>
</template>

The nuxi command for adding components

~


npx nuxi add component MyNavigation

Components accept special modifiers --client or --server. This is a shortcut to generate a component that should either be rendered on the server or only rendered on the client. We'll look into why there are some components we might not want to render on the server.

Middleware with the Nuxi command

what the file looks like

middleware/auth.global.ts


export default defineNuxtRouteMiddleware((to, from) => {
  if (to.path.match(/^\/protected\/?/)) {
    return navigateTo('/');
  }
});

The nuxi command for adding middleware

~


npx nuxi add middleware --global auth

The --global modifier is used to tell nuxi to append .global.ts to the middleware name. Nuxt runs these types of middlewares on every request. We'll look at the different types of middlewares again later in this course.

API routes with the Nuxi command

what the file looks like

server/api/user.get.ts


export default defineEventHandler(async (event) => {
  return {
    id: 1,
    email: "[email protected]"
  }
});

The nuxi command for adding API routes

~


npx nuxi add api --get user

The modifiers for adding API routes are the HTTP verbs that you want to use for the endpoint. e.g. --post or --put. This will append it to your filename.

Composables with the Nuxi command

what the file looks like

composables/location.ts


export const useLocation = () => {}

The nuxi command for adding composables

~


npx nuxi add composable location

Plugins with the Nuxi command

what the file looks like

plugins/firebase.ts


export default defineNuxtPlugin(() => {
  // ...
});

The nuxi command for adding plugins

~


npx nuxi add plugin firebase

The Nuxi add command is a neat feature of the CLI to help speed up development time a little through writing less boilerplate. Go ahead and practice the command in the Nuxt project we generated earlier.

The nuxi prepare command

This is another command that we will be running intermittently when developing, but haven't started a dev or build yet.

Nuxt ships with a lot of TypeScript goodies and it uses the special .nuxt folder for all kinds of generated types. Usually you won't need to run anything because if you run build / dev then Nuxt handles this for you.

There are some cases though where you might be developing without running a build / server and need the typing in your project. Or in CI environments. This is when prepare is helpful:

~


npx nuxi prepare

Running this within your project root will generate the .nuxt directory with all the necessary files and types your app needs. If your app is in a different root folder, e.g. src, you can specify that:

~


npx nuxi prepare src

The nuxi upgrade command

Nuxt is under active development, by an amazing team with crazy velocity. This means that newer versions are still hot off the shelf. An easy way to get the latest version is to use nuxi:

~


npx nuxi upgrade

The nuxi devtools command

Nuxt has an amazing devtools project that makes debugging and inspecting an ease. To enable / disable devtools in your project:

~


npx nuxi devtools enable

~


npx nuxi devtools disable

Note, that this installs the devtools globally on your computer and also modifies your .nuxtrc.

The nuxi cleanup command

Sometimes when things get a bit complicated, you might want to make sure there aren't any old files interfering with how your code is running.

~


npx nuxi clean

This will delete:

  • .nuxt
  • .output
  • node_modules/.vite
  • node_modules/.cache

And restore your project to a fresh state, so you can be sure it is truly just your code that is buggy 😝.

The build, dev and generate command

For the purpose of this tutorial these will be the last three commands I cover. The other commands that exist I don't feel are very relevant at this stage, but you can always check them out.

Nuxi build

The build command does exactly what you think - it will build your application ready for production. We rarely run this manually as it's usually specified in your package.json scripts:

~


npx nuxi build

You can pass an optional --dotenv <filename> flag if your .env is in another file like .env.local.

Nuxi dev

This is the command we run the most when developing our application. Again, mostly via the scripts in our package.json, it prepares your application in an unoptimized state with Vite and Nitro and enables features like HMR so your app updates instantly in the browser as you make changes.

~


npx nuxi dev

This command has a bunch of useful modifiers that you can use for e.g. https local server, using different ports, controlling the output in your terminal etc.

Nuxi generate

Much like build this command also packages your application for production, the main difference is that instead of generating the server endpoints - it will generate the static output of your application which you can host on platforms like Netlify without the need for a server to handle incoming requests to generate the HTML. The HTML is essentially prerendered and on the client side the Vue engine is loaded again for interactivity.

We'll take a deep dive into different modes you can run your production app in and build a project using each:

  • Server-Side Rendered
  • Statically Generated
  • Single Page Applications

~


npx nuxi generate

Under the hood, this command basically runs npx nuxi build with a special modifier --prerender. It crawls all your pages and the <nuxt-link> elements on it to find the pages that need to be rendered into the .output/public folder. This is the folder that you'll deploy to your static hosting environment.

This limits your application in some ways with regards to API routes, server middlewares etc.

Interactive example


Conclusion

The nuxi command is a super tool for productivity and developer experience when developing Nuxt apps. Learning the commands is very helpful and you can always refer back to this page during this course to remember what the commands that we use are doing.