Adding Reading Time to an Article
Dec 17th, 2022
•
•
•
292 words (1 minutes)If you've ever viewed an article on Medium, you'll notice that the preview gives an estimated "read time". This feature is easily to implement using the reading-time
node pacakge and our existing contentlayer configuration. Begin by installing reading-time
.
yarn add reading-time
We will add reading time by adding a new computed field to our post model and defining the type for ReadingTime.
Define the ReadingTime Type
We previously kept our type definitions in /content/defintions
. Create a new file reading-time.ts
and then use contentlayer's defineNestedType
to create the new type.
import { defineNestedType } from "contentlayer/source-files";
export const ReadingTime = defineNestedType(() => {
name: "ReadingTime",
fields: {
minutes: {
type: "number",
required: true
},
words: {
type: "number",
required: true
}
}
})
Add the ReadingTime Computed Field
Next, open up the post definition file at /content/definitions/post.ts
and define the new computed field.
import { defineDocumentType } from "contentlayer/source-files";
import GithubSlugger from "github-slugger";
import { Tag } from "./tag";
import { Series } from "./series";
import moment from "moment";
import readingTime from "reading-time";
import { ReadingTime } from "./reading-time";
export const Post = defineDocumentType(() => ({
// .
// .
// .
computedFields: {
// .
// .
// .
readingTime: {
type: "nested",
of: ReadingTime,
resolve: (doc) => {
const time = readingTime(doc.body.raw);
return { minutes: Math.floor(time.minutes), words: time.words };
},
},
},
}));
Now, we contentlayer generates the typesafe JSON, each post will have a new field called "readingTime" -- an object with two nested components; the minutes it takes to read, and the number of words.
You can then display in a component however you like, accessing those members as follows:
<ReadingTime
minutes={post.readingTime?.minutes}
words={post.readingTime?.words}
></ReadingTime>
Next.js