You are reading Nuxt Content V1 documentation. Read the latest version
Advanced
Programmatic Usage
$content
is accessible from @nuxt/content.
Beware that you can access it only after the module has been loaded by Nuxt. require('@nuxt/content')
should happen in hooks or internal Nuxt methods.
export default {
modules: [
'@nuxt/content'
],
generate: {
async ready () {
const { $content } = require('@nuxt/content')
const files = await $content().only(['slug']).fetch()
console.log(files)
}
}
}
Static Site Generation
Since Nuxt 2.14+, nuxt generate
has a crawler feature integrated which will crawl all your links and generate your routes based on those links. Therefore you do not need to do anything in order for your dynamic routes to be crawled.
Also, nuxt generate
will automagically skip webpack build step when no code has been changed and use the previous build using cache. The content module integrates with this feature to ignore changes inside the content/
folder. In other terms, when changing the content of your site and deploying, the build will be skipped.
Learn more in this article.
When using Nuxt <= 2.12, you might need to specify the dynamic routes with generate.routes
Example
export default {
modules: [
'@nuxt/content'
],
generate: {
async routes () {
const { $content } = require('@nuxt/content')
const files = await $content({ deep: true }).only(['path']).fetch()
return files.map(file => file.path === '/index' ? '/' : file.path)
}
}
}
Recommended to use Nuxt 2.14+ with nuxt generate
because it's awesome!
Hooks
The module adds some hooks you can use:
content:file:beforeParse
Allows you to modify the contents of a file before it is handled by the parsers.
Arguments:
file
- Type:
object
- Properties:
- path:
string
- extension:
string
(ex:.md
) - data:
string
- path:
Example
Changing all appearances of react
to vue
in all Markdown files:
hooks: {
'content:file:beforeParse': (file) => {
if (file.extension !== '.md') return
file.data = file.data.replace(/react/g, 'vue')
}
}
content:file:beforeInsert
Allows you to add data to a document before it is stored.
Arguments:
document
- Type:
object
- Properties:
- See writing content
- Type:
database
- Type:
object
- Properties:
- See type definition
- Type:
Example
When building a blog, you can use file:beforeInsert
to add readingTime
to a document using reading-time.
text
is the body content of a markdown file before it is transformed to JSON AST. You can use at this point, but it is not returned by the API.
export default {
modules: [,
'@nuxt/content'
],
hooks: {
'content:file:beforeInsert': (document) => {
if (document.extension === '.md') {
const { time } = require('reading-time')(document.text)
document.readingTime = time
}
}
}
}
Example
You might want to parse markdown inside a .json
file. You can access the parsers from the database
object:
export default {
modules: [,
'@nuxt/content'
],
hooks: {
'content:file:beforeInsert': async (document, database) => {
if (document.extension === '.json' && document.body) {
const data = await database.markdown.toJSON(document.body)
Object.assign(document, data)
}
}
}
}
content:options
Extend the content options, useful for modules that wants to read content options when normalized and apply updated to it.
Arguments:
options
- Type:
object
- Properties:
- See configuration
- Type:
Example
export default {
modules: [,
'@nuxt/content'
],
hooks: {
'content:options': (options) => {
console.log('Content options:', options)
}
}
}
Handling Hot Reload
When you are in development mode, the module will automatically call nuxtServerInit
store action (if defined) and $nuxt.refresh()
to refresh the current page.
In case you want to listen to the event to do something more, you can listen on content:update
event on client-side using $nuxt.$on('content:update')
:
export default function ({ store }) {
// Only in development
if (process.dev) {
window.onNuxtReady(($nuxt) => {
$nuxt.$on('content:update', ({ event, path }) => {
// Refresh the store categories
store.dispatch('fetchCategories')
})
})
}
}
And then add your plugin in your nuxt.config.js
:
export default {
plugins: [
'@/plugins/update.client.js'
]
}
Now everytime you will update a file in your content/
directory, it will also dispatch the fetchCategories
method.
This documentation uses it actually. You can learn more by looking at plugins/init.js.
API Endpoint
This module exposes an API endpoint in development so you can easily see the JSON of each directory or file, it is available on http://localhost:3000/_content/. The prefix is _content
by default and can be configured with the apiPrefix property.
Example
-| content/
---| articles/
------| hello-world.md
---| index.md
---| settings.json
Will expose on localhost:3000
:
/_content/articles
: list the files incontent/articles/
/_content/articles/hello-world
: gethello-world.md
as JSON/_content/index
: getindex.md
as JSON/_content/settings
: getsettings.json
as JSON/_content
: listindex
andsettings
The endpoint is accessible on GET
and POST
request, so you can use query params: http://localhost:3000/_content/articles?only=title&only=description&limit=10.
Since v1.4.0, this endpoint also supports where
in query params:
- All the keys that don't belong to any of the default ones will be applied to
where
http://localhost:3000/_content/articles?author=...
- You can use
$operators
with_
:
http://localhost:3000/_content/articles?author_regex=...
This module uses LokiJS under the hood. You can check here for query examples.
- You can use nested properties:
http://localhost:3000/_content/products?categories.slug_contains=top
You can learn more about that endpoint in lib/middleware.js.