Skip to content

Instantly share code, notes, and snippets.

@ashx3s
Last active January 24, 2024 12:25
Show Gist options
  • Save ashx3s/59068feba277c73cc2a4be7a15ec6f59 to your computer and use it in GitHub Desktop.
Save ashx3s/59068feba277c73cc2a4be7a15ec6f59 to your computer and use it in GitHub Desktop.
Nuxt 3 Abbreviated Guide

Components in Nuxt

  • All vue components will work in nuxt
  • Unlike regular vue, you do not need to import child components into other components that is handled by the config
  • Use props and slots to render content in a component

Props

  • Documentation
  • Props are used to pass information from a parent to a child component
  • Set up props in the script tag like this:
  • if a value is required, set a required: true
<script setup>
const props = defineProps({
  stringProp: {
    type: String,
    default: 'default values',
    required: true
  },
  objectProp: {
    type: Object,
    default() {
      return {
        imagePath: require(`../assets/images/image1.jpg),
        altText: 'description'
      }
    }
  }
})
</script>
  • Use them in a template like this:
<template>
<article>
  <h1>{{ props.stringProp.key1 }}</h1>
  <img :url="props.Objectprop.imagePath" :alt="altText">
</article>
</template>

slots

  • Documentation

  • Slots are used to create spaces where you can add content within the component

  • They can be named and created dynamically to allow for multiple slots to be used

  • See this simple slot example:

    • component: BaseHeader.vue:
    <template>
    <!-- style your header here -->
      <header>
        <slot></slot>
      </header>
    </template>
    
    • page: index.vue
    <template>
    <div id="app">
      <base-header>
        <h1>Page Title</h1>
      </base-header>
    </div>
    </template>
    
  • However you can get more complex with them by using named slots:

    • component: BaseArticle.vue
      <template>
      <article>
        <header>
         <slot name="header"></slot>
        </header>
        <section>
          <slot name="content"></slot>
        </section>
      </article>
      </template>
      
    • then use the component on a page like so
    <template>
    <base-article>
      <template v-slot:header>
        <!-- write html -->
      </template>
      <template v-slot:content>
        <!-- write html -->
      </template>
    </base-article>
    </template>
    

Nuxt 3 Configuration

Project Configuration

  • Start a nuxt 3 project with npx nuxi init projectName
  • Set up a git repo if you want
  • Nuxt 3 does not preset very much in your config file, nor does it auto create many folders
    • you will likely need to add these:
      • components/ for all your components, declare folders in the config file
      • pages/ see the naming conventions section of this gist
      • assets/ for css, fonts, images etc
    • and you may also need to add these:
      • layouts/ for different top level layouts
      • plugins/ for custom plugins and non nuxt modules
      • public/ for files that keep their names and never change like favicon.ico
      • server/ to create backend logic

Configuration

Just like Nuxt 2, this file is where you configure most of your modules and settings. However unlike nuxt 2, it doesn't give you very much boiler plate code.

Metadata

  • There is global and page level metadata (like page title etc). This is focused on the global level. See below for using the config file vs the app.vue file
  • For more information about metadata, see this doc on metadata

nuxt.config.ts approach

  • This is just like with nuxt 2.
export default defineNuxtConfig({
  head: {
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { hid: 'description', name: 'description', content: 'write a description here'},
      { name: 'title', content: 'Site Title' }
    ],
    links: [
      { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
      { rel: 'stylesheet', href: 'https://fonts.googleapis.com/css2?family=Ubuntu'}
    ]
  }
})

app.vue approach

  • This codeblock is copied for the Nuxt 3 documentation
  • Note that you can bind dynamic content to it (see on the documentation for examples)
  • You can add visual content around and below this (see on documentation)
<template>
  <Html lang="en-US">
    <Head>
      <Title>{{ dynamic }} title</Title>
      <Meta name="description" content="Page Description" />
      <Link rel="preload" href="/test.txt" as="script" />
      <Style type="text/css" href="~/assets/css/main.css" />
    </Head>
  </Html>
</template>

definePageMeta approach

  • add metadata to specific pages by adding this to the script
<script setup>
definePageMeta({
  title: 'About Page',
  layout: 'custom'
})
</script>

Adding Fonts and Icons

Fonts

You can add fonts to Nuxt 3 in 3 different ways (until the google fonts module is ready, then you'll have 4 ways)

  1. Download the fonts and add it locally to an assets/fonts/ folder
  2. Import the fonts into a css stylesheet with @import syntax (link would be found on google fonts)
  3. Add the fonts to the nuxt.config.ts file or to the app.vue file as noted in the metadata section of this file

Icons

Nuxt Naming Conventions

Components

  • Documentation
  • use PascalCase
    • ie: BasePage.vue
  • You can use the folders as part of the naming convention
    • ie:
    /components
       base/
        Button.vue
    
    • can be called as
    <BaseButton />
    

Pages

  • Documentation

  • all of your web pages go into a pages/ folder at the root directory

  • use lowercase naming

    • ie: index.vue
  • dynamic routes use [id].vue syntax

  • Add page level metadata or define the page layout with definePageMeta({}) syntax

  • Meta Data Documentation

App.vue

  • When first set up, there is an app.vue file
  • This acts as the entry point to the site, and as a default layout
  • once you create a pages/ folder, you need to make an index.vue file inside it
    • this becomes the new home page
    • inject it into app.vue by adding <NuxtPage /> to the app.vue template
    • you can also delete the app.vue file to set your site to use layouts/default.vue layout and render index.vue content without adding <NuxtPage /> to it

Layouts

  • Documentation
  • use lowercase
    • ie: default.vue or contactpage.vue
  • then add to a page either in the script tag or around your content
  • You can cancel the default layout from being applied to a page by adding layout: false to the definePageMeta({})

Add via script tag

<script setup>
definePageMeta({
  layout: "gallery"
})
</script>

Add in template

<template>
  <NuxtLayout name="gallery">
  <!-- add your content in here -->
  </NuxtLayout>
</template>

Options API vs Composition API

These are two different ways of writing syntax in vue. They can work together, but need to be structured separately.

The Difference

Options API

<script>
export default {
  data() {
    strVariable: 'This is a string variable'
  },
  prop: {
    title: {
      type: String,
      default: 'Title'
    }
  },
  computed: {
    helloFunction(): {
      return {
        str: 'Hello Function'
      }
    }
  }
}
</script>

Composition API

<script setup>

const props = defineProps({
  title: {
    type: String,
    default: 'Title'
  }
})

const strVariable = "This is a string variable"

function helloFunction = computed() {
  return {
    str: 'Hello Function'
  }
}
</script>

Can you use both?

  • Yes! you can, there are 2 ways to do that
  1. Use 2 separate script tags
<script>
export default({
// options api content
})
</script>
<script setup>
// composition api content
</script>
  1. use setup inside the script tag (this is a way to use setup in nuxt 2 and vue 2 as well)
<script>
  export default {
    // non composition api stuff here
    setup() {
      // composition api stuff here
    }
  }
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment