Skip to content

Your First Page

Time to create your first page with Vuero.

INFO

Explore the src/components/pages folder of demo project to help you build your own pages.

Routes folder structure

As seen in the previous section, Vuero uses Unplugin Vue Router to manage routes generation from the src/pages folder. This means that you only need to create a new .vue file in the src/pages folder to create a new page in your application.

text
src/pages/
├── index.vue        # Home page
├── [...all].vue     # Catch all route (404)
├── auth.vue         # Auth layout
├── auth/
│   ├── index.vue
│   └── signup.vue
├── app.vue          # App layout
└── app/
    ├── index.vue
    └── [slug].vue   # Route with dynamic parameter

Useful links:

Pages features

Route parameters

When using dynamic routes, you can access the route parameters using the useRoute composable from Vue Router.

vue
<script setup lang="ts">
// note that you don't need to import useRoute from vue-router
const route = useRoute()
</script>

<template>
  <div>
    <h1>slug: {{ route.params.slug }}</h1>
  </div>
</template>

Useful links:

Page metadata

Page metadata are static content that will be used in vue router routes, it can be used to set information like if the page is public or private, the layout to use, the title, the meta tags, etc. Later we can use this metadata in router guards to protect routes or in the layout to render the correct content. (see Plugin Guide for more information about router guards)

vue
<script setup lang="ts">
import MyLayout from '/@src/layouts/my-layout.vue'

definePage({
  // all child pages will inherit this metadata
  meta: {
    requiresAuth: true,
  },
})
</script>

<template>
  <MyLayout>
    <slot />
  </MyLayout>
</template>
Equivalent in Nuxt quickstarter
vue
<script setup lang="ts">
definePageMeta({
  // all child pages will inherit this metadata
  layout: 'my-layout',
  requiresAuth: true,
})
</script>

<template>
  <div>
    <!-- NuxtPage is used instead of RouterView -->
    <NuxtPage />
  </div>
</template>

Useful links:

Head tags

To manage the head tags of a page, Vuero use @unhead/vue which provide composables with fully typed head tags.

vue
<script setup lang="ts">
useHead({
  titleTemplate: (title?: string) => !title ? 'My App' : `${title} - My App`,
  link: [
    {
      rel: 'icon',
      href: '/favicon.svg',
      type: 'image/svg+xml',
    },
  ],
  meta: [
    // Critical Tags
    { charset: 'utf-8' },
    {
      name: 'viewport',
      content: 'width=device-width, initial-scale=1, shrink-to-fit=no',
    },
  ],
})
</script>

<template>
  <div>
    <Suspense>
      <RouterView />
    </Suspense>
  </div>
</template>

The common place to set global head tags is in the global app component in src/VueroApp.vue if using SSR.

When using client only setup, you need to set critical head tags directly in the src/index.html because they will not be interpreted by client until the Vue app is mounted.

Useful links:

Data Loader (experimental)

Unplugin Vue Router introduce a new feature called Data Loader which allow you to load data before rendering the page. This is useful when you need to fetch data from an API or a database.

vue
<script lang="ts">
import { defineBasicLoader } from 'unplugin-vue-router/data-loaders/basic'

export const usePageData = defineBasicLoader(async (to) => {
  const slug = to.params.slug

  const page = await fetch(`https://api.example.com/pages/${slug}`)
    .then(res => res.json())

  return {
    page,
  }
}, {
  // used for SSR only
  key: 'app-slug-data',
})
</script>

<script setup lang="ts">
const route = useRoute()
const { data, isLoading } = usePageData()
</script>

<template>
  <div>
    <h1>slug: {{ route.params.slug }}</h1>

    <div v-if="isLoading">Loading...</div>
    <div v-else>{{ data.page }}</div>
  </div>
</template>

Useful links:

All Rights Reserved