1.0.22 • Published 4 months ago

contentlayer-datapad v1.0.22

Weekly downloads
-
License
ISC
Repository
github
Last release
4 months ago

datapad

Awesome Contentlayer configuration with GFM, LQIP, TOC and more.

It includes the following plugins:

Installation

yarn add contentlayer-datapad

Setup

import { defineDocumentType, makeSource } from 'contentlayer/source-files';
import {
  computeFields,
  remarkPlugins,
  rehypePlugins,
} from 'contentlayer-datapad';

export const Blog = defineDocumentType(() => ({
  name: 'Blog',
  filePathPattern: `blog/**/*.mdx`,
  contentType: 'mdx',
  fields: {
    title: {
      type: 'string',
      required: true,
    },
    description: {
      type: 'string',
      required: true,
    },
    date: {
      type: 'date',
      required: true,
    },
    image: {
      type: 'string',
      required: false,
    },
  },
  computedFields: computeFields<'Blog'>({}),
}));

const source = makeSource({
  contentDirPath: './content',
  documentTypes: [Blog],
  mdx: {
    remarkPlugins: remarkPlugins(),
    rehypePlugins: rehypePlugins({}),
  },
});

export default source;

Also, update your Tailwind config to include the following:

import type { Config } from 'tailwindcss';

const config: Config = {
  content: ['./node_modules/contentlayer-datapad/**/*.js'],
  // ...
};

export default config;

Configuration

computeFields

computeFields accepts a configuration object with the following properties:

PropertyTypeDescriptionDefault
openGraphEndpointstringThe endpoint of the Open Graph image generator (i.e. @vercel/og)'/api/og'
imagesFolderstringThe folder where your images are stored, prepended to the document image path'./public'

The computed fields are:

Field NameTypeDescriptionExample Output
slugstringThe slug of the document, used in the URL'/blog/my-post'
slugAsParamsstringThe slug as a path segment'my-post'
readingTimestringThe estimated time to read the document, in minutes'5 min read'
tocjsonThe table of contents of the document[{ value: 'Heading 1', depth: 1, url: '#heading-1' }]
imageBlurstringThe LQIP image data of the document'UklGRkgAAABXRUJQVlA4IDwAAADQAQCdASoQAAkABUB8JYwC7ADbW2wxAAD+5fWSusCgEGgrbEnESec12AakPGs5RtCwUs8GJTOZH7EgIAA='

remarkPlugins

remarkPlugins does not accept any configuration.

rehypePlugins

rehypePlugins accepts a configuration object with the following properties:

PropertyTypeDescriptionDefault
shikiThemeThemeThe theme to use for syntax highlighting'one-dark-pro'

Usage

Here's how to use the custom fields in your Next.js app:

import { allBlogs } from 'contentlayer/generated';
import Image from 'next/image';
import type { Toc } from 'contentlayer-datapad';

return allBlogs.sort(sortBlogPostByDate).map((post) => (
  <div key={post.name}>
    <Image
      src={src}
      width={1920}
      height={1080}
      alt=""
      blurDataURL={`data:image/jpg;base64,${post.imageBlur}`}
      placeholder="blur"
    />

    <p>{post.readingTime}</p>

    <ul>
      {(post.toc as Toc).map((item) => (
        <li
          key={item.url}
          style={{
            paddingLeft: `${item.depth - 2}rem`,
          }}
        >
          <a href={item.url}>{item.value}</a>
        </li>
      ))}
    </ul>
  </div>
));