Advanced

Nuxt Content is highly customizable, giving you freedom and control over how the data is transformed.

Hooks

The module adds some hooks you can use:

content:file:* hooks are available in nitro runtime, in order to use them you need to create a custom nitro plugin.

Create a plugin in the server/plugins/ directory

server/plugins/content.ts
export default defineNitroPlugin((nitroApp) => {  // ...})

content:file:beforeParse

Allows you to modify the contents of a file before it is handled by the parsers.

Arguments:

  • file
    • Type: Object
    • Properties:
      • _id: String
      • body: String

Example

Changing all occurrences of React to Vue in all Markdown files:

server/plugins/content.ts
export default defineNitroPlugin((nitroApp) => {  nitroApp.hooks.hook('content:file:beforeParse', (file) => {    if (file._id.endsWith('.md')) {      file.body = file.body.replace(/react/g, 'vue')    }  })})

content:file:afterParse

Allows you to modify a document after being parsed by parsers.

Example

Using content's first picture as cover image.

server/plugins/content.ts
import { visit } from 'unist-util-visit'export default defineNitroPlugin((nitroApp) => {  nitroApp.hooks.hook('content:file:afterParse', (file) => {    if (file._id.endsWith('.md')) {      visit(file.body, (n:any) => n.tag === 'img', (node) => {        file.coverImage = node.props.src      })    }  })})

Transformers

Transformers are responsible for parsing and manipulating contents in the content module. Internally, the module has specific transformers for each content type to parse the raw content and prepare it for querying and rendering.

You can create custom transformers to support new content types or improve functionalities of supported content types.

  1. Create your transformer. A transformer consists of 4 parts:
  • name: Transformer name.
  • extensions: List of valid file extensions.
  • parse: If provided, this function will be used to parse the raw content.
  • transform: Receives that parsed content and manipulates it.
my-transformer.ts
// filename: my-transformer.tsimport { defineTransformer } from '@nuxt/content/transformers'export default defineTransformer({  name: 'my-transformer',  extensions: ['.names'],  parse (_id, rawContent) {    return {      _id,      body: rawContent.trim().split('\n').map(line => line.trim()).sort()    }  }})
  1. Define simple module to register transformer
my-module.mjs
// filename: my-module.mjsimport { resolve } from 'path'import { defineNuxtModule } from '@nuxt/kit'export default defineNuxtModule({  setup (_options, nuxt) {    nuxt.options.nitro.externals = nuxt.options.nitro.externals || {}    nuxt.options.nitro.externals.inline = nuxt.options.nitro.externals.inline || []    nuxt.options.nitro.externals.inline.push(resolve('./my-module'))    // @ts-ignore    nuxt.hook('content:context', (contentContext) => {      contentContext.transformers.push(resolve('./my-module/my-transformer.ts'))    })  }})
  1. Register your module
nuxt.config.ts
// filename: my-module.mjsimport { resolve } from 'path'import { defineNuxtConfig } from '@nuxt/kit'import MyModule from './my-module'export default defineNuxtConfig({  modules: [    MyModule,    '@nuxt/content'  ]})

That's it. You can create .names files in content directory. Checkout transformer example.