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.