Query Utils

queryCollectionNavigation

The queryCollectionNavigation composable generates the navigation tree of given collection.

Type

function queryCollectionNavigation<T extends keyof PageCollections>(
  collection: T,
  fields?: Array<keyof PageCollections[T]>
): ChainablePromise<T, ContentNavigationItem[]>

interface ChainablePromise<T extends keyof PageCollections, R> extends Promise<R> {
  where(field: keyof PageCollections[T] | string, operator: SQLOperator, value?: unknown): ChainablePromise<T, R>
  andWhere(groupFactory: QueryGroupFunction<PageCollections[T]>): ChainablePromise<T, R>
  orWhere(groupFactory: QueryGroupFunction<PageCollections[T]>): ChainablePromise<T, R>
  order(field: keyof PageCollections[T], direction: 'ASC' | 'DESC'): ChainablePromise<T, R>
}

Usage

Use the auto-imported queryCollectionNavigation to generate a navigation tree for a specific collection. This is particularly useful for creating dynamic navigation menus or sidebars based on your content structure.

The function returns a chainable promise that allows you to add additional query conditions:

pages/[...slug].vue
<script setup lang="ts">
const { data } = await useAsyncData('navigation', () => {
  return queryCollectionNavigation('docs')
    .where('published', '=', true)
    .order('date', 'DESC')
})
</script>
The queryCollectionNavigation utility is available in both Vue and Nitro. Checkout Server Usage for more details on how to use it on the server side.

You can add metadata to a directory using a .navigation.yml file.

.navigation.yml
title: Getting Started
icon: i-lucide-square-play

API

queryCollectionNavigation(collection: CollectionName, extraField: keyof Collection)

Generate a navigation tree for the specified collection.

  • Parameters:
    • collection: The key of the defined collection in content.config.ts.
    • extraFields: (Optional) An array of additional fields to include in the navigation items. (By default title and path are included in the navigation items.)
  • Returns: A chainable promise that resolves to a navigation tree structure. The promise includes methods for adding query conditions:
    • where(field, operator, value): Add a WHERE condition
    • andWhere(groupFactory): Add a grouped AND condition
    • orWhere(groupFactory): Add a grouped OR condition
    • order(field, direction): Add an ORDER BY clause

The navigation tree is generated based on the directory structure and ordering happens based on files ordering

Examples

Basic usage without additional query conditions:

pages/[...slug].vue
<script setup lang="ts">
const { data } = await useAsyncData('navigation', () => {
  return queryCollectionNavigation('docs')
})
</script>

<template>
  <nav>
    <ul v-if="data">
      <li v-for="item in data" :key="item.path">
        <NuxtLink :to="item.path">{{ item.title }}</NuxtLink>
      </li>
    </ul>
  </nav>
</template>

Example with additional query conditions and extra fields:

pages/[...slug].vue
<script setup lang="ts">
const { data } = await useAsyncData('navigation', () => {
  return queryCollectionNavigation('docs', ['description', 'badge'])
    .where('draft', '=', false)
    .where('partial', '=', false)
    .order('title', 'ASC')
})
</script>

<template>
  <nav>
    <ul v-if="data">
      <li v-for="item in data" :key="item.path">
        <NuxtLink :to="item.path">
          {{ item.title }}
          <span v-if="item.badge" class="badge">{{ item.badge }}</span>
        </NuxtLink>
        <p v-if="item.description">{{ item.description }}</p>
      </li>
    </ul>
  </nav>
</template>

Server Usage

Nuxt Content provides a similar utility to query collections on the server side. The only difference is that you need to pass event as the first argument to the queryCollectionNavigation function.

server/api/navigation.ts
export default eventHandler(async (event) => {
  const navigation = await queryCollectionNavigation(event, 'docs')
  return navigation
})
Make sure to create server/tsconfig.json file with the following content to avoid type error.
{
  "extends": "../.nuxt/tsconfig.server.json"
}