p5 - nuxt

```

npm create nuxt@latest nuxt-lab
cd nuxt-lab
npm install
npm run dev

```

Project structure

```

nuxt-lab/
├── layouts/
│   ├── default.vue
│   └── minimal.vue
├── pages/
│   ├── index.vue
│   ├── about.vue
│   └── items/
│       ├── index.vue
│       └── [id].vue
└── nuxt.config.ts

```

layouts/default.vue

```

<template>
  <div>
    <header>
      <h2>Book Store</h2>
      <nav>
        <NuxtLink to="/">Home</NuxtLink>
        <NuxtLink to="/about">About</NuxtLink>
        <NuxtLink to="/items">Books</NuxtLink>
      </nav>
    </header>
    <main><slot /></main>
    <footer>© 2026 Book Store</footer>
  </div>
</template>

<style scoped>
header, footer {
  background: #1e293b;
  color: white;
  padding: 20px;
  text-align: center;
}
nav { display: flex; justify-content: center; gap: 25px; }
a { color: white; text-decoration: none; }
main { min-height: 75vh; padding: 25px; }
</style>

```

layouts/minimal.vue

```

<template>
  <div><slot /></div>
</template>

```

pages/index.vue

```

<template>
  <section>
    <h1>Welcome to Book Store</h1>
    <p>Discover your next favourite book.</p>
    <NuxtLink to="/items" class="btn">Explore Books</NuxtLink>
  </section>
</template>

<style scoped>
section { text-align: center; padding: 100px 20px; }
h1 { color: #2563eb; font-size: 35px; }
p { color: #64748b; font-size: 18px; }
.btn {
  display: inline-block;
  background: #2563eb;
  color: white;
  padding: 12px 22px;
  border-radius: 7px;
  text-decoration: none;
}
</style>

```

pages/about.vue

```

<template>
  <div>
    <h1>About Us</h1>
    <p>Our bookstore provides a collection of books for readers of all interests.</p>
    <p>Explore fiction, technology, science and educational books.</p>
  </div>
</template>

```

pages/items/index.vue

```

<script setup>
const books = [
  { id: 1, name: 'Atomic Habits', author: 'James Clear' },
  { id: 2, name: 'The Alchemist', author: 'Paulo Coelho' },
  { id: 3, name: 'Rich Dad Poor Dad', author: 'Robert Kiyosaki' },
  { id: 4, name: '1984', author: 'George Orwell' },
  { id: 5, name: 'The Hobbit', author: 'J.R.R. Tolkien' }
]
</script>

<template>
  <div>
    <h1>Book Catalogue</h1>
    <div class="grid">
      <div v-for="book in books" :key="book.id" class="card">
        <h3>{{ book.name }}</h3>
        <p>{{ book.author }}</p>
        <NuxtLink :to="`/items/${book.id}`">View Details</NuxtLink>
      </div>
    </div>
  </div>
</template>

<style scoped>
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 18px;
}
.card {
  padding: 20px;
  background: #f1f5f9;
  border-radius: 10px;
}
a { color: #2563eb; }
</style>

```

pages/items/[id].vue

```

<script setup>
const route = useRoute()

const books = [
  { id: 1, name: 'Atomic Habits', author: 'James Clear', description: 'A book about building good habits.' },
  { id: 2, name: 'The Alchemist', author: 'Paulo Coelho', description: 'A journey of dreams and discovery.' },
  { id: 3, name: 'Rich Dad Poor Dad', author: 'Robert Kiyosaki', description: 'A book about financial education.' },
  { id: 4, name: '1984', author: 'George Orwell', description: 'A dystopian novel.' },
  { id: 5, name: 'The Hobbit', author: 'J.R.R. Tolkien', description: 'An adventure in Middle-earth.' }
]

const book = books.find(b => b.id === Number(route.params.id))
</script>

<template>
  <div v-if="book" class="card">
    <h1>{{ book.name }}</h1>
    <h3>Author: {{ book.author }}</h3>
    <p>{{ book.description }}</p>
    <NuxtLink to="/items">Back to Books</NuxtLink>
  </div>
  <h2 v-else>Book Not Found!</h2>
</template>

<style scoped>
.card {
  padding: 25px;
  background: #f1f5f9;
  border-radius: 10px;
}
a { color: #2563eb; }
</style>

```

Stretch Goal – Apply minimal layout to About page

Add this inside the `<script setup>` of `pages/about.vue`:

```

definePageMeta({
  layout: 'minimal'
})

```

Output URLs

```

http://localhost:3000/
http://localhost:3000/about
http://localhost:3000/items
http://localhost:3000/items/1
http://localhost:3000/items/2

```