Generated Data
The Contentlayer build process transforms content from your source(s) into data objects that can be consumed by your application.
This reference explains the location, shape, and structure of the generated data objects.
Generated Data Objects
Data objects are built into a three-tier system that works like this:
- JSON documents represent each individual transformed document.
- Document collections manifest for exporting collections of documents.
- All collections manifest for exporting every document collection, as well as a combined collection of all documents.
See below for details about each individual piece.
JSON Documents
Generated JSON documents contain the data that was transformed from the content source.
File Location
They are placed in a type-specific directory within Contentlayer's data directory, following this pattern:
.contentlayer/generated/[DOCTYPE]/[ID].json
For example, if the document type was called Page
and the ID of one object was index.md
, then the path to that file would be:
.contentlayer/generated/Page/index.md.json
Data Structure
The data structure is essentially a list of key-value pairs, minus a few generated and reserved properties (see below). Using the page example from above, if the index.md
file had title
and description
fields, along with markdown content below the file's frontmatter, it might look like this:
{
"title": "...",
"description": "...",
"body": {
"raw": "...",
"html": "..."
},
"_id": "index.mdx",
"_raw": {
"sourceFilePath": "index.mdx",
"sourceFileName": "index.mdx",
"sourceFileDir": ".",
"contentType": "markdown",
"flattenedPath": ""
},
"type": "Doc"
}
Field Shapes
The shape of data for each field is dependent on both the data source and field type. See individual source references for more information.
Generated Properties
There may be generated properties depending on your content source. For example, the local file source generates a property for the document type and for the body content.
These properties can be configured so that you control what become reserved words, meaning you can't have another field using these names. For example, using the default configuration for the local file source, you wouldn't be able to set fields named body
or type
.
Reserved Properties
The following properties are non-configurable and reserved for generated documents. They may not be used as field names.
_id
: The ID value for the individual document._raw
: a series of meta attributes about the document.
Document Collection Manifest
The document type manifest is responsible for importing and exporting document collections — an array of individual documents of the same type.
Here's an example of a Page
document type with two documents in the collection:
import indexMdx from './Page/index.mdx.json'
import aboutMdx from './Page/about.mdx.json'
export const allPages = [indexMdx, aboutMdx]
Manifest Exports
The manifest exports a single object that is an array of all imported JSON documents.
The naming convention is to prepend the pluralized document type with "all". If Page
is the document type name, then the exported object will be called allPages
.
File Location
The file is located in the main Contentlayer data directory and named according to its main export. In the example above where the document type name is Page
, the file will live at .contentlayer/generated/allPages.mjs
.
All Documents Manifest
The main manifest file is responsible for exporting every document collection, as well as an allDocuments
collection that is an array of every document across all document types.
It it colocated with the collection manifest in the .contentlayer/generated
directory as index.mjs
.
Continuing the Page
example, a simple version of the file may look like this:
export { isType } from 'contentlayer/client'
export * from './allPages.mjs'
import { allPages } from './allPages.mjs'
export const allDocuments = [...allPages]
isType
Utility
This file also exports an isType
utility that could be conveniently imported from this file or directly from contentlayer/client
.
This is most frequently used to determine if a particular document is of a particular type, taking into account your specific configuration.
Rather than using a filter like this (where you need to know the type
field name):
allDocuments.filter((doc) => ['Page', 'Post'].includes(doc.type))
You can do this instead:
import { isType, allDocuments } from 'contentlayer/generated'
allDocuments.filter(isType(['Page', 'Post']))
Nested Objects
Nested objects are not written to individual documents, nor are they exported by any of the manifests.
Instead, nested objects are nested directly in the documents that are using them.
Was this article helpful to you?
Provide feedback
Last edited on March 31, 2023.
Edit this page