You are reading Nuxt Content V1 documentation. Read the latest version
Configuration
You can configure @nuxt/content
with the content
property in your nuxt.config.js
.
export default {
content: {
// My custom configuration
}
}
Before diving into the individual attributes, please have a look at the default settings of the module.
Merging defaults
You can define every option either as function or as static value (primitives, objects, arrays, ...). If you use a function, the default value will be provided as the first argument.
If you don't use a function to define you properties, the module will try to
merge them with the default values. This can be handy for markdown.remarkPlugins
, markdown.rehypePlugins
and so on because
the defaults are quite sensible. If you don't want to have the defaults included, just use a function.
Properties
apiPrefix
- Type:
string
- Default:
'/_content'
Route that will be used for client-side API calls and SSE.
content: {
// $content api will be served on localhost:3000/content-api
apiPrefix: 'content-api'
}
dir
- Type:
string
- Default:
'content'
Directory used for writing content. You can give an absolute path, if relative, it will be resolved with Nuxt srcDir.
content: {
dir: 'my-content' // read content from my-content/
}
fullTextSearchFields
- Type:
Array
- Default:
['title', 'description', 'slug', 'text']
Fields that needs to be indexed to be searchable, learn more about search here.
text
is a special key that contains your Markdown before being parsed to AST.
content: {
// Only search in title and description
fullTextSearchFields: ['title', 'description']
}
nestedProperties
- Type
Array
- Default:
[]
- Version: >= v1.3.0
Register nested properties to handle dot-notation and deep filtering.
content: {
nestedProperties: ['categories.slug']
}
liveEdit
- Type
boolean
- Default:
true
- Version: >= v1.5.0
Disable live edit mode in development:
content: {
liveEdit: false
}
markdown
This module uses remark and rehype under the hood to compile markdown files into JSON AST that will be stored into the body
variable.
remarkPlugins
and rehypePlugins
To configure how the module will parse Markdown, you can:
- Add a new plugin to the defaults:
export default {
content: {
markdown: {
remarkPlugins: ['remark-emoji']
}
}
}
- Override the default plugins:
export default {
content: {
markdown: {
remarkPlugins: () => ['remark-emoji']
}
}
}
- Use local plugins
export default {
content: {
markdown: {
remarkPlugins: [
'~/plugins/my-custom-remark-plugin.js'
]
}
}
}
- Provide options directly in the definition
export default {
content: {
markdown: {
remarkPlugins: [
['remark-emoji', { emoticon: true }]
]
}
}
}
- Provide options using the name of the plugin in
camelCase
export default {
content: {
markdown: {
// https://github.com/remarkjs/remark-external-links#options
remarkExternalLinks: {
target: '_self',
rel: 'nofollow'
}
}
}
}
yarn add remark-emoji
export default {
content: {
markdown: {
remarkPlugins: ['remark-emoji']
}
}
}
markdown.tocDepth
- Type:
number
- Default:
3
- Version: >= v1.11.0
You can change maximum heading depth to include in the table of contents.
markdown.remarkPlugins
- Type:
Array
- Default:
['remark-squeeze-paragraphs', 'remark-slug', 'remark-autolink-headings', 'remark-external-links', 'remark-footnotes']
- Version: >= v1.4.0
You can take a look at the list of remark plugins.
markdown.rehypePlugins
- Type:
Array
- Default:
['rehype-minify-whitespace', 'rehype-sort-attribute-values', 'rehype-sort-attributes', 'rehype-raw']
- Version: >= v1.4.0
You can take a look at the list of rehype plugins.
markdown.basePlugins
markdown.remarkPlugins
as a function instead.markdown.plugins
markdown.remarkPlugins
as an array instead.markdown.prism.theme
- Type:
string
- Default:
'prismjs/themes/prism.css'
This module handles code highlighting in markdown content using PrismJS.
It automatically pushes the desired PrismJS theme in your Nuxt.js config, so if you want to use a different theme than the default one, for example prism-themes:
yarn add prism-themes
content: {
markdown: {
prism: {
theme: 'prism-themes/themes/prism-material-oceanic.css'
}
}
}
To disable the inclusion of the theme, set prism to false
:
content: {
markdown: {
prism: {
theme: false
}
}
}
markdown.highlighter
- Type:
Highlighter
|PromisedHighlighter
- Version: >=1.9.0
You can change the default code highlighter in markdown content by using this option. As an example, we use highlight.js.
import highlightjs from 'highlight.js'
export default {
content: {
markdown: {
highlighter(rawCode, lang) {
const highlightedCode = highlightjs.highlight(rawCode, { language: lang }).value
// We need to create a wrapper, because
// the returned code from highlight.js
// is only the highlighted code.
return `<pre><code class="hljs ${lang}">${highlightedCode}</code></pre>`
}
}
}
}
When markdown.highlighter
is defined, it will automatically disable the inclusion of the Prism theme.
Don't forget to add the corresponding style manually if you define markdown.highlighter
.
It returns a string
or HAST (Hypertext Abstract Syntax Tree). You can build HAST by passing the 4th argument. It consits of h
, node
and u
.
import highlightjs from 'highlight.js'
export default {
content: {
markdown: {
highlighter(rawCode, lang, _, { h, node, u }) {
const highlightedCode = highlightjs.highlight(rawCode, { language: lang }).value
// We can use ast helper to create the wrapper
const childs = []
childs.push(
h(node, 'pre', [
h(node, 'code', { className: ['hljs', lang] }, [
u('raw', highlightedCode)
])
])
)
return h(
node,
'div',
{ className: 'highlighted-with-highlightjs' },
childs
)
}
}
}
}
After rendering with the nuxt-content
component, it will look like this:
<div class="highlighted-with-highlightjs">
<pre class="language-<lang>">
<code>
...
</code>
</pre>
</div>
You can also get the line highlight and file name value from the 3rd argument. Combining them with the HAST, you can pass it to the client.
import highlightjs from 'highlight.js'
export default {
content: {
markdown: {
highlighter(rawCode, lang, { lineHighlights, fileName }, { h, node, u }) {
const highlightedCode = highlightjs.highlight(rawCode, { language: lang }).value
const childs = []
const props = {
className: `language-${lang}`,
dataLine: lineHighlights,
dataFileName: fileName
}
childs.push(
h(node, 'pre', [
h(node, 'code', props, [
u('raw', highlightedCode)
])
])
)
return h(
node,
'div',
{ className: 'highlighted-with-highlightjs' },
childs
)
}
}
}
}
Then the returned code will look like this:
<div class="highlighted-with-highlightjs">
<pre class="language-<lang>" data-line="<line>" data-file-name="<file-name>">
<code>
...
</code>
</pre>
</div>
You can learn more about
h
,node
andu
from mdast-util-to-hast, Universal Syntax Tree and unist-builder
If you need to get the highlighter from promised-returned-package/function, you can do it this way:
import { getHighlighter } from 'example-highlighter'
export default {
content: {
markdown: {
async highlighter() {
const highlighter = await getHighlighter()
return (rawCode, lang) => {
return highlighter.highlight(rawCode, { language: lang })
}
}
}
}
}
You can head over to Snippets - Custom Highlighter section to see more example.
yaml
- Type:
object
- Default:
{}
This module uses js-yaml
to parse .yaml
, .yml
files. You can check here for options.
Note that we force json: true
option.
xml
- Type:
object
- Default:
{}
This module uses xml2js
to parse .xml
files. You can check here for options.
csv
- Type:
object
- Default:
{}
This module uses node-csvtojson
to parse csv files. You can check here for options.
extendParser
- Type:
object
- Default
{}
With this option you can define your own parsers for other file types. Also you can overwrite the default parser!
To add your custom parser write a function that gets as an argument the content of the file and returns the extracted data.
Example
const parseTxt = file => file.split('\n').map(line => line.trim())
// in Config:
{
extendParser: {
'.txt': parseTxt
}
}
editor
You can provide a custom editor for editing your markdown files in development. Set the editor
option to a path to your editor component. The code of the default editor you can find here.
content: {
editor: '~/path/to/editor/component.vue'
}
Your component should implement the following:
v-model
for getting the markdown code.- prop
isEditing
is a boolean with the information if the editing is started and the component is shown. (this is optional) - when finished editing your component has to emit
endEdit
You should be aware that you get the full markdown file content so this includes the front-matter. You can use gray-matter
to split and join the markdown and the front-matter.
useCache
- Type:
boolean
- Default:
false
When true
, the production server (nuxt start
) will use cached version of the content (generated after running nuxt build
) instead of parsing files. This improves app startup time, but makes app unaware of any content changes.
Defaults
export default {
content: {
editor: '~/.nuxt/content/editor.vue',
apiPrefix: '_content',
dir: 'content',
fullTextSearchFields: ['title', 'description', 'slug', 'text'],
nestedProperties: [],
liveEdit: true,
useCache: false,
markdown: {
remarkPlugins: [
'remark-squeeze-paragraphs',
'remark-slug',
'remark-autolink-headings',
'remark-external-links',
'remark-footnotes'
],
rehypePlugins: [
'rehype-minify-whitespace',
'rehype-sort-attribute-values',
'rehype-sort-attributes',
'rehype-raw'
],
prism: {
theme: 'prismjs/themes/prism.css'
}
},
yaml: {},
csv: {},
xml: {},
extendParser: {}
}
}