How to set up a Nuxt 3 project, install essential modules, and follow best practices for a clean and efficient development process.
17/03/25
Go Back
Nuxt 3 is a robust framework designed for building modern web applications using Vue.js. This guide will walk you through the process of setting up a Nuxt 3 project, installing essential modules, and adhering to best practices to maintain a clean and efficient development workflow. You can view the completed project on GitHub.
Before getting started, make sure you have the following installed:
To create a new Nuxt 3 project, open your terminal and run:
pnpm create nuxt <project-name>
cd <project-name>
pnpm dev -o
Your browser should automatically open http://localhost:3000, displaying your new Nuxt app.
For a fully functional Nuxt 3 setup, install the following modules using your favorite package manager (e.g., pnpm, yarn, or npm):
Add them to your nuxt.config.ts:
export default defineNuxtConfig({
devtools: { enabled: true },
modules: [
'@nuxtjs/seo',
'@nuxt/fonts',
'@nuxt/icon',
'@nuxt/image',
'@nuxt/eslint',
],
});
To maintain a clean project structure, create these folders:
Naming Conventions:
These are just recommendations, but following them will help keep your project organized and maintainable. If you have a different preference, feel free to adjust as needed. As long as you're consistent!
Create an index.vue file inside the pages folder:
<template>
<div>
<h1>Hello World!</h1>
</div>
</template>
Layouts are very powerful in Nuxt for structuring your application. Let’s create a default layout. I use this a lot for headers and footer because they stay the same on multiple pages. You can also create a mobile.vue or whatever that comes to mind.
Create default.vue in the layouts folder:
<template>
<div>
<!-- You can add a header here -->
<slot />
<!-- You can add a footer here -->
</div>
</template>
The "slot" tag is where the page content will be rendered.
Now, modify app.vue to use layouts:
<template>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</template>
To use fonts in our web-app, I recommend using @nuxt/fonts. It's more optimized including than including the url in the 'head' section and is very easy to configure.
Add the following to your nuxt.config.ts:
export default defineNuxtConfig({
modules: ['@nuxt/fonts'],
fonts: {
families: [
{ name: 'Space Grotesk', preload: true, display: 'swap' },
{ name: 'Poppins', preload: true, display: 'swap' },
],
providers: {
google: false, // Disable Google Fonts for GDPR compliance
},
},
});
@nuxt/icon is a no-brainer in each project for me. It provides a quick setup, a wide collection of icons, and is very easy to use. See the full collection at: icones.js.org. Let's add an icon to our index page.
<template>
<div>
<h1>Hello world!</h1>
<Icon name="uil:globe" style="color: black" />
</div>
</template>
@nuxt/img is a powerful image optimization module for Nuxt applications. It automatically optimizes your images for better performance and user experience while being incredibly simple to implement. Check out the docs for more information: image.nuxt.com.
Add the following to your nuxt.config.ts:
export default defineNuxtConfig({
// other configurations
image: {
quality: 80,
format: ['webp', 'avif', 'jpg'],
},
});
hello-world.jpg is an image in the public folder.
<template>
<div>
<div>
<h1>Hello world!</h1>
<Icon name="uil:globe" style="color: black" />
</div>
<NuxtImg src="/images/hello-world.png" alt="Nuxt Logo" />
</div>
</template>
I'm a big fan of Tailwind for styling. The official documentation explains it best: Tailwind Nuxt Guide. Lets use it in our index page.
<template>
<div class="flex h-screen flex-col items-center justify-center">
<div class="flex items-center justify-center p-4 text-2xl">
<Icon name="uil:globe" style="color: black" />
<h1 class="text-blue-500">Hello world!</h1>
<Icon name="uil:globe" style="color: black" />
</div>
<NuxtImg src="/images/hello-world.png" alt="Nuxt Logo" />
</div>
</template>
ESLint and Prettier help maintain a clean and consistent codebase. Trust me, you need them!
There is already an excellent guide to set this up: Adding ESLint and Prettier to Nuxt 3. However, the article didn't mention this but you need to install @nuxtjs/eslint-config-typescript as well.
There are many prettier configurations available, but I like to use the following:
// .prettierrc
{
"semi": true,
"singleQuote": true,
"useTabs": true,
"tabWidth": 2,
"trailingComma": "es5",
"printWidth": 80,
"endOfLine": "lf",
"arrowParens": "always",
"bracketSpacing": true,
"embeddedLanguageFormatting": "auto",
"plugins": [
"prettier-plugin-organize-imports",
"prettier-plugin-tailwindcss"
],
"htmlWhitespaceSensitivity": "ignore",
"vueIndentScriptAndStyle": true
}
You can change the SEO information on a per-page basis using the useHead function. I like to set default SEO metadata is set in app.vue, and specify the title per page.
Example setup in app.vue
<script setup>
const description = `Hi, welcome to our nuxt starter site! This project includes all basic needs for almost every project!`;
const ogTitle = 'Nuxt 3 - Starter project';
const twitterDescription = `Hi, welcome to our nuxt starter site!`;
const image = 'https://example.com/default-image.webp';
const mySite = 'https://example.com';
useHead({
htmlAttrs: {
lang: 'en',
},
link: [{ rel: 'canonical', href: mySite }],
meta: [
{ name: 'description', content: description },
{
name: 'keywords',
content: 'nuxt 3, starter, project',
},
{ name: 'author', content: 'John Doe' },
{ name: 'publisher', content: 'John Doe' },
{ property: 'og:site_name', content: mySite },
{ property: 'og:type', content: 'website' },
{ property: 'og:url', content: mySite },
{ property: 'og:title', content: ogTitle },
{ property: 'og:description', content: description },
{ property: 'og:image', content: image },
{ name: 'twitter:card', content: 'summary_large_image' },
{ name: 'twitter:url', content: mySite },
{ name: 'twitter:title', content: ogTitle },
{ name: 'twitter:description', content: twitterDescription },
{ name: 'twitter:image', content: image },
],
});
</script>
Example for page.vue
<script setup>
useHead({
title: 'Home',
meta: [
{
name: 'description',
content: 'Welcome to the index page of the Nuxt 3 starter project.',
},
],
});
</script>
@nuxt/seo is an essential module for any production Nuxt application. It automatically generates a sitemap and robots.txt file, making your site more discoverable by search engines.
Add the following to your nuxt.config.ts:
export default defineNuxtConfig({
// other configurations
site: { url: 'https://example.com', name: 'My Awesome Website' },
});
The module works automatically once configured. You don't need to add any additional code to your pages or components. It will:
While @nuxt/seo offers many more advanced features like structured data, canonical URL management, and social media tag optimization, the basic setup above covers the essential functionality for most projects.
Congratulations! You’ve set up a fully functional Nuxt 3 project with all the essential features. If you have any questions, feel free to reach out at: mail@lukasolivier.be