ajcwebdev

a first look at nuxt 3

nuxtvuenitrovite

We are excited to open source Nuxt 3 after more than a year of intense development. On top of supporting Vue 3 or Vite, Nuxt 3 contains a new server engine, unlocking new full-stack capablities to Nuxt server and beyond.

Introducing Nuxt 3 Beta

The goal of Nuxt is to make web development intuitive and performant while keeping great developer experience in mind. The original version was created by Sébastien Chopin in October 2016 to emulate the features of Next.js but with Vue instead of React. Version 3 has been over a year in the making and is composed of the following core packages:

Together these packages provide a selection of libraries for managing many common concerns for developers building on the web today such as:

In addition to curating and integrating these tools, Nuxt also provides directory structure conventions for managing pages and components.

How to Migrate a Nuxt 2 Project to Nuxt 3

If you don't have a Nuxt 2 project, skip ahead to the section, "Create a Nuxt 3 project from scratch."

At the moment, there is no Nuxt 2 to Nuxt 3 migration guide nor is it recommended due to potentially more changes coming. The team is working to provide a stable migration guide and tooling to make it as smooth as possible in the form of Nuxt Bridge. If you have an existing Nuxt 2 project, the team strongly recommends you begin by using Nuxt Bridge to experiment with new features while avoiding breaking changes. Bridge is a forward-compatibility layer that allows you to experience new Nuxt 3 features by installing and enabling a Nuxt module.

All Nuxt 2 modules should be forward compatible with Nuxt 3 as long as they migrate to bridge or if they are already following guidelines. All (upcoming) modules made with @nuxt/kit should be backward compatible with Nuxt 2 projects (even without bridge) as long as they are not depending on a Nuxt 3 / Bridge-only feature. Since Nuxt 3 natively supports TypeScript and ECMAScript Modules, it is useful to avoid CommonJS syntax such as __dirname, __filename, require(), and module.exports as much as possible.

Try online

We will be building a Nuxt application from scratch. However, you can start playing with Nuxt 3 online in your browser on either StackBlitz or CodeSandBox.

Create a Nuxt 3 project from scratch

The project will start with only three files:

We will create a directory for pages and an api later on.

mkdir ajcwebdev-nuxt3
cd ajcwebdev-nuxt3
touch package.json app.vue
echo 'node_modules\n.DS_Store\n*.log\n.nuxt\nnuxt.d.ts\n.output' > .gitignore

All the code for this article can be found on my GitHub.

App file - app.vue

The app.vue file is the main component in your Nuxt 3 applications. With Nuxt 3, the pages/ directory is optional, if not present, Nuxt won't include vue-router dependency. This is useful when working on a landing page or an application that does not need routing.

<!-- app.vue -->

<template>
<div>
<h2>ajcwebdev-nuxt3</h2>
</div>
</template>

app.vue acts as the main component of your Nuxt application. This means anything you add to it, such as JavaScript or CSS, will be global and included in every page.

package.json

In your package.json, add the following scripts (dev, build, and start) along with the latest version of nuxt3 as a development dependency.

{
"scripts": {
"dev": "nuxi dev",
"build": "nuxi build",
"start": "node .output/server/index.mjs"
},
"devDependencies": {
"nuxt3": "latest"
}
}

Nuxi is the new CLI for Nuxt 3 and has two main commands:

  1. nuxi dev - Start development server
  2. nuxi build - Make production assets

We also created a start script that uses Node to run the bundled output generated for the server by nuxi build.

Start development server

The yarn dev command starts your Nuxt app in development mode and includes hot module replacement. You can include the --open flag to automatically open the browser after starting up.

yarn dev

The CLI will display links to the running application and performance metrics.

Nuxt CLI v3.0.0-27237303.6acfdcd

  > Local:    http://localhost:3000/
  > Network:  http://192.168.1.242:3000/

ℹ Vite warmed up in 592ms
✔ Generated nuxt.d.ts
✔ Vite server built in 903ms
✔ Nitro built in 112 ms

Open localhost:3000 to see your application.

01-ajcwebdev-nuxt3-localhost-3000

Build for production

The yarn build command builds your Nuxt application for production. It creates a .output directory with your application, server, and dependencies ready to be deployed.

yarn build

Nitro produces a standalone server dist that is independent of node_modules. The output is combined with both runtime code to run your Nuxt server in any environment and serve you static files. A native storage layer is also implemented for supporting multi source, drivers and local assets.

Pages directory

The pages/ directory is optional, meaning that if you only use app.vue, vue-router won't be included, reducing your application bundle size. However, if you do include it, Nuxt will automatically integrate Vue Router and map pages/ directory into the routes of your application.

rm -rf app.vue
mkdir pages
touch pages/about.vue pages/index.vue

We deleted app.vue and will include the previous home page's content in index.vue.

<!-- pages/index.vue -->

<template>
<div>
<h2>ajcwebdev-nuxt3</h2>
</div>
</template>

We also created about.vue for an about page. Include the following code to make sure that people know stuff about your things.

<!-- pages/about.vue -->

<template>
<div>
<h2>This page tells you stuff about things!</h2>
</div>
</template>

Open localhost:3000/about.

02-about-page-localhost-3000

Server Engine

Nuxt 3 is powered by a new server engine called Nitro. Nitro is used in development and production. It includes cross-platform support for Node.js, Browsers, and service-workers and serverless support out-of-the-box. Other features include API routes, automatic code-splitting, async-loaded chunks, and hybrid static/serverless modes. Server API endpoints and Middleware that internally uses h3 are added by Nitro.

Nitro allows 'direct' calling of routes via the globally-available $fetch helper. This will make an API call to the server if run on the browser, but will simply call the relevant function if run on the server, saving an additional API call. The $fetch API uses ohmyfetch to:

Server directory for API routes

The server/ directory contains API endpoints and server middleware for your project. It is used to create any backend logic for your Nuxt application. Nuxt will automatically read in any files in the ~/server/api directory to create API endpoints. Each file should export a default function that handles API requests.

mkdir -p server/api
touch server/api/hello.js

Add the following code to hello.js.

// server/api/hello.js

export default (req, res) => '<h2>Hello from Nuxt 3</h2>'

Open localhost:3000/api/hello.

03-hello-api-route-localhost-3000

Deploy to Netlify

What's the point of a framework if you can't deploy it on a Jamstack platform?

touch netlify.toml
[build]
command = "yarn build"
publish = "dist"
functions = ".output/server"

[[redirects]]
from = "/*"
to = "/.netlify/functions/index"
status = 200

Create GitHub Repository

git init
git add .
git commit -m "the nuxt best thing"
gh repo create ajcwebdev-nuxt3
git push -u origin main

Connect your repo to your Netlify account.

04-connect-repo-to-netlify

The build command and publish directory will be included automatically from the netlify.toml file.

05-netlify-site-settings

Lastly, give yourself a custom domain.

06-add-custom-domain

Open ajcwebdev-nuxt3.netlify.app/.

07-ajcwebdev-nuxt3-netlify-deploy