Composables

queryContent()

The queryContent composable provides methods for querying and fetching your contents.

Important ⚠️

In your pages and components, wrap your query in useAsyncData composable to prevent fetching duplication on first load.

app.vue
<script setup>
const { data } = await useAsyncData('home', () => queryContent('/').findOne())
</script>

<template>
  <pre>
    {{ data }}
  </pre>
</template>

Query builder

The queryContent() composable provides methods for querying and fetching your contents.

Create a query builder to search contents.

// Create a query looking for anything in content/ directory
const contentQuery = queryContent()

// Create a query looking into content/articles directory
const contentQuery = queryContent('articles')

// Create a query looking into content/articles/nuxt3 directory
const contentQuery = queryContent('articles', 'nuxt3')

where(query)

  • query:
    • Type: Partial<QueryBuilderParams>
    • Required

Filter results by query.

Where queries are based on subset of Mongo query syntax, it handles:

OperatorDescription
$match
$eqMatch if item equals condition
$neMatch if item not equals condition
$notMatch is condition is false
$andMatch only if all of nested conditions are true
$orMatch if any of nested conditions is true
$inMatch if item is in condition array
$containsMatch if item contains every condition or match every rule in condition array
$icontainsIgnore case contains
$containsAnyMatch if item contains at least one rule from condition array
$existsCheck key existence
$typeMatch if type of item equals condition
$regexProvides regular expression capabilities for pattern matching strings
$ltCheck if item is less than condition
$lteCheck if item is less than or equal to condition
$gtCheck if item is greater than condition
$gteCheck if item is greater than or equal to condition
// Implicit (assumes $eq operator)
const articles = await queryContent('articles').where({ title: 'Home' }).findOne()

// Explicit $eq
const articles = await queryContent('articles').where({ title: { $eq: 'Home' } }).findOne()

// $gt
const articles = await queryContent('articles').where({ age: { $gt: 18 } }).find()

// $in
const articles = await queryContent('articles').where({ name: { $in: ['odin', 'thor'] } }).find()

In order to filter in objects and an array or arrays, you can use the nested properties style:

const products = await queryContent('products').where({ 'categories': { $contains: 'top' } }).find()

const products = await queryContent('products').where({ 'categories': { $contains: ['top', 'woman'] } }).find()

sort(options)

  • options
    • Type: object
    • Required

Sort results by a field or fields.

// Sort by title ascending
const articles = await queryContent('articles')
  .sort({ title: 1 })
  .find()

// Sort by title ascending first then sort by category descending
const articles = await queryContent('articles')
  .sort({ title: 1, category: -1 })
  .find()
// OR
const articles = await queryContent('articles')
  .sort({ title: 1 })
  .sort({ category: -1 })
  .find()

// Sort by nested field
const articles = await queryContent('articles')
  .sort({ 'category.title': 1 })
  .find()

sort() method does case-sensitive, alphabetical sort by default. There is some magical options you can pass to sort options to change sort behavior, like sorting case-insensitive or numerically rather than alphabetically.

  • $sensitivity: Change case sensitivity. Like using $sensitivity: 'base' for case-insensitive sort
  • $numeric: Boolean whether numeric collation should be used, such that "1" < "2" < "10".
  • $caseFirst: Whether upper case or lower case should sort first.

For example, to sort a list of people from youngest to oldest:

const people = await queryContent('people')
  .sort({ age: 1, $numeric: true })
  .find()

These options are given to Intl.Collator().

limit(count)

  • count
    • Type: number
    • Required

Limit number of results.

// fetch only 5 articles
const articles = await queryContent('articles').limit(5).find()

skip(count)

  • count
    • Type: number
    • Required

Skip results.

// fetch the next 5 articles
const articles = await queryContent('articles')
    .skip(5)
    .limit(5)
    .find()

without(keys)

  • keys
    • Type: string[] or string
    • Required

Remove a subset of fields.

const articles = await queryContent('articles').without('unused-key').find()

const articles = await queryContent('articles').without(['unused-key', 'another-unused-key']).find()

only(keys)

  • keys
    • Type: string[] or string
    • Required

Select a subset of fields.

const articles = await queryContent('articles').only('id').find()

const articles = await queryContent('articles').only(['id', 'title']).find()

find()

Fetch and return the list of matched contents based on the query.

// List of articles
const articles = await queryContent('articles').find()

findOne()

Fetch the first match of content.

const firstArticle = await queryContent('articles').findOne()

findSurround(path, options)

  • path
    • Type: string
    • Required
  • options
    • Type: { before: number, after: number }
    • Default: { before: 1, after: 1 }

Get the previous and next results around the path. The path should be the full path of the target content.

You will always obtain an array of fixed length filled with the matching document or null.

const [prev, next] = await queryContent()
  .only(['_path', 'title'])
  .sort({ date: 1})
  .where({ isArchived: false })
  .findSurround('/articles/article-2')

// Returns
[
  {
    title: 'Article 1',
    _path: '/articles/article-1'
    //...
  },
  null // no article-3 here
]

count()

Count the number of matched contents based on the query.

// Count of articles
const count = await queryContent('articles').count()

// Returns
5 // number of articles

You can also use count() with where() method.

// Count of articles
const count = await queryContent('articles')
  .where({ isArchived: false })
  .count()

// Returns
5 // number of articles