Document Type Fields with Contentlayer
Introduction
In this post we will discuss how to use contentlayer to define document type fields.
Core features
- Contentlayer
documentType
forArticle
- Contentlayer
documentType
forProject
- Contentlayer
nestedType
forSeries
- Contentlayer common
computedFields
computedFields
computedFields.ts
import { type ComputedFields } from 'contentlayer2/source-files'; export const computedFields: ComputedFields = { readingTime: { type: 'json', resolve: (doc) => readingTime(doc.body.raw), }, slug: { type: 'string', resolve: (doc) => doc._raw.flattenedPath.replace(/^.+?(\/)/, ''), }, path: { type: 'string', resolve: (doc) => doc._raw.flattenedPath, }, filePath: { type: 'string', resolve: (doc) => doc._raw.sourceFilePath, }, toc: { type: 'json', resolve: (doc) => extractTocHeadings(doc.body.raw) }, };
defineNestedType
for series
Series.ts
import { defineDocumentType, defineNestedType, } from 'contentlayer2/source-files'; const Series = defineNestedType(() => ({ name: 'Series', fields: { title: { type: 'string', required: true, }, order: { type: 'number', required: true, }, }, }));
defineDocumentType
for article
Blog.ts
export const Blog = defineDocumentType(() => ({ name: 'Blog', filePathPattern: 'article/**/*.mdx', contentType: 'mdx', fields: { title: { type: 'string', required: true }, series: { type: 'nested', of: Series }, date: { type: 'date', required: true }, tags: { type: 'list', of: { type: 'string' }, default: [] }, lastmod: { type: 'date' }, featured: { type: 'boolean' }, draft: { type: 'boolean' }, summary: { type: 'string' }, images: { type: 'list', of: { type: 'string' }, default: [] }, authors: { type: 'list', of: { type: 'string' }, required: true }, layout: { type: 'string' }, bibliography: { type: 'string' }, canonicalUrl: { type: 'string' }, language: { type: 'string', required: true }, }, computedFields: { ...computedFields, structuredData: { type: 'json', resolve: (doc) => ({ '@context': 'https://schema.org', '@type': 'BlogPosting', headline: doc.title, datePublished: doc.date, dateModified: doc.lastmod || doc.date, description: doc.summary, image: doc.images ? doc.images[0] : '', }), }, }, }));
defineDocumentType
for authors
Authors.ts
export const Authors = defineDocumentType(() => ({ name: 'Authors', filePathPattern: 'authors/**/*.mdx', contentType: 'mdx', fields: { name: { type: 'string', required: true }, default: { type: 'boolean' }, avatar: { type: 'string' }, occupation: { type: 'string' }, company: { type: 'string' }, email: { type: 'string' }, twitter: { type: 'string' }, linkedin: { type: 'string' }, github: { type: 'string' }, layout: { type: 'string' }, portfolio: { type: 'string' }, language: { type: 'string', required: true }, }, computedFields, }));
Community
We're excited to see the community adopt Hyperse-io, raise issues, and provide feedback. Whether it's a feature request, bug report, or a project to showcase, please get involved!