In this post, we are going to learn about Nuxt, one of if not “the” most popular Vue.js frameworks.
To be specific, we are going to learn about Nuxt 3 - its latest release codenamed "Mount Hope".
As stated above, Nuxt is an open-source Vue.js framework for making websites, or to put it as its makers term it - "The intuitive Vue framework".
What is the difference between Vue.js and Nuxt?
Since Nuxt is a Vue framework, it means that we get several opinionated functionalities out of the box that we would otherwise not get inside a vanilla Vue.js app.
These preconfigured functionalities range from but are not limited to routing, app-level context, SSR(server-side rendering) & SSG(static site generation), inbuilt S.E.O (search engine optimization), data fetching, and several app-level configurations. We can build vanilla Vue.js apps with such features, but that would involve setting everything up by ourselves either by using our own code or plug-in together some node modules.
So, in the name of not reinventing the wheel, let's learn about Nuxt and see what it offers.
N.B., before installing Nuxt just with Vue.js, you need to have node.js and npm installed in your system. A basic understanding of Vue.js will also be helpful since we’ll expansively be dealing with the Vue.js syntax.
Creating a new Nuxt project
Before creating a Nuxt project, you need to have the latest LTS version of Node.js installed on your system. The Visual Studio Code editor coupled with the Volar extension is a good setup for working on Nuxt.js projects.
To create a new Nuxt app named - getting-started-with-nuxt
, run the following script on your terminal.
npx nuxi init getting-started-with-nuxt
Next, switch to the project's directory and run the npm install
command on your terminal to install the project's dependencies.
# Switch into the project's directory
cd getting-started-with-nuxt
# install dependencies
npm install
Anatomy of a Nuxt application
After having created the new Nuxt app, when observing the project's file and directory layout, you should see the following:
getting-started-with-nuxt
├── README.md
├── app.vue
├── node_modules
├── nuxt.config.ts
├── package.json
├── pnpm-lock.yaml
└── tsconfig.json
Let’s try to understand the files and directories that we see above.
app.vue
: This is the main component of a Nuxt.js application created when you initiate a new project withnpx nuxi init
. This component is sufficient for an app that does not need routing.node_modules
: This is the file where the project’s dependencies are placed. We neither modify this directory’s contents nor stage its contents for versioning.nuxt.config.js
: This is the file that stores a Nuxt project's configuration.package.json
: Just as we will see in other JavaScript projects we'll be working on, thepackage.json
file is the ID card of a project, carrying project details such as it's name, description, scripts, dependencies and so on. Visit the npm docs for more information about this file.package-lock.json
: This file persists the versions of the dependencies our project uses for consistency whenever our project happens to be run. We normally don’t modify this file as it is managed by the package manager. When usingpnpm
as your package manager, you will see apnpm-lock.yaml
instead.
To see what our project would look like when served, run npm run dev
on your terminal.
Figure 1-1 is the presentation of what we should see if every step was correctly followed.
Nuxt pages and components
To add new pages to our Nuxt.js app we need to first create a /pages
directory, then place all page files inside it. The /pages
directory is optional in Nuxt 3. When it is present, Nuxt enables the support for its file-based routing, the opposite is true otherwise, unless we set pages: true
inside the configuration file - nuxt.config.js
or when a app/router.options.ts
file is present.
Let's add the /pages
directory to the Nuxt app we just created, transfer the app.vue
file inside this directory and rename it to index.vue
.
Visiting localhost:3000 after making the suggested change, we end up at the same point as we did in illustration 1-1.
Let's try visiting a new route - localhost:3000/new-page. In doing so, we end up at the page illustrated below.
When we try to visit non-existent pages, Nuxt handles that by automatically directing us to a default 404 status page. We can customize the error page by adding an error.vue
component on the root of our project directory. We'll learn more about error handling on Nuxt in a later post.
Try renaming the index.vue
component currently present inside the pages
directory. When we try to visit localhost:3000, we end up at the error page displayed above once again. This is because each page that is created using a directory needs to have an index.vue
component inside it that acts as the default view of that page, in our case, we are dealing with the website's homepage which is the root index.vue component found under the /pages
top level directory.
Let’s add one more page to our Nuxt project.
Create a new about.vue
component under the /pages
directory adding the following template code inside.
<template>
<div>
<h1>This is the about page</h1>
</div>
</template>
On your browser, visit the link - localhost:3000/about. You should see the resulting page with the /about
route as a page containing the title “This is the about page”.
Let’s see how we can use components in our Nuxt project.
In Nuxt, components are placed within the /components
directory. We can then use them inside other components or pages.
Let's add a new component. Inside the /components
directory, add a new file, naming it - HighlightedText.vue
. Add the following code inside the newly created component.
<template>
<h2 style="font-weight: 800">
"{{ text }}"
</h2>
</template>
<script>
export default {
props: {
text: {
type: String,
default: "Some Message"
}
}
}
</script>
Next, import this component inside our about page currently at /pages/about.vue
. We'll end up with the following after updating our about page.
<template>
<div>
<h1>This is the about page</h1>
<HighlightedText></HighlightedText>
</div>
</template>
<script>
import HighlightedText from '../components/HighlightedText.vue';
export default {
components: {HighlightedText}
}
</script>
On visiting the about page route again, we'll see the "some Message" text rendered as expected.
Try deleting the component-importing code from the about.vue
file, remaining with the following code.
<template>
<div>
<h1>This is the about page</h1>
<HighlightedText></HighlightedText>
</div>
</template>
When you visit localhost:3000/about again, nothing would have changed, you'll still see the "Some Message" text present, meaning that our component is still rendered despite removing the component importation code.
So, what happened?
The explanation for this behaviour is simple. Nuxt scans the /component
directory by default and makes all found components globally available for consumption within other components and pages, abstaining us from the need to import them every time we need to use them. This helps us write less code.
This completes the introductory part of Nuxt 3. The source code for the project we created in this post is available on this GitHub repository.
Summary
We have so far learnt how to create a new Nuxt 3 project, what a Nuxt project’s various files and directories represent, see how we can create new pages, and use components inside Nuxt pages.
This post has been a mere introduction to Nuxt 3, we'll see more of what we can do with pages