From 24218f53e6110e5027d6b72dadc781df9c57fca7 Mon Sep 17 00:00:00 2001 From: Naomi Carrigan Date: Tue, 8 Jul 2025 18:30:51 -0700 Subject: [PATCH] feat: add reading time (#6) ### Explanation _No response_ ### Issue _No response_ ### Attestations - [x] I have read and agree to the [Code of Conduct](https://docs.nhcarrigan.com/community/coc/) - [x] I have read and agree to the [Community Guidelines](https://docs.nhcarrigan.com/community/guide/). - [x] My contribution complies with the [Contributor Covenant](https://docs.nhcarrigan.com/dev/covenant/). ### Dependencies - [x] I have pinned the dependencies to a specific patch version. ### Style - [x] I have run the linter and resolved any errors. - [x] My pull request uses an appropriate title, matching the conventional commit standards. - [x] My scope of feat/fix/chore/etc. correctly matches the nature of changes in my pull request. ### Tests - [ ] My contribution adds new code, and I have added tests to cover it. - [ ] My contribution modifies existing code, and I have updated the tests to reflect these changes. - [ ] All new and existing tests pass locally with my changes. - [ ] Code coverage remains at or above the configured threshold. ### Documentation _No response_ ### Versioning _No response_ Reviewed-on: https://git.nhcarrigan.com/nhcarrigan/blog/pulls/6 Co-authored-by: Naomi Carrigan Co-committed-by: Naomi Carrigan --- package.json | 1 + pnpm-lock.yaml | 8 ++++++++ posts/networking.md | 2 ++ src/app/page.tsx | 1 + src/app/post/[slug]/page.tsx | 2 ++ src/lib/posts.ts | 19 +++++++++++-------- 6 files changed, 25 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index d0e7fda..fb654f1 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "react": "^19.0.0", "react-dom": "^19.0.0", "react-markdown": "9.0.3", + "reading-time": "1.5.0", "rehype-raw": "7.0.0", "remark-gfm": "4.0.0" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 55efa63..a3b3e2f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,6 +23,9 @@ importers: react-markdown: specifier: 9.0.3 version: 9.0.3(@types/react@19.0.7)(react@19.0.0) + reading-time: + specifier: 1.5.0 + version: 1.5.0 rehype-raw: specifier: 7.0.0 version: 7.0.0 @@ -2352,6 +2355,9 @@ packages: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} + reading-time@1.5.0: + resolution: {integrity: sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg==} + reflect.getprototypeof@1.0.10: resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} engines: {node: '>= 0.4'} @@ -5642,6 +5648,8 @@ snapshots: dependencies: picomatch: 2.3.1 + reading-time@1.5.0: {} + reflect.getprototypeof@1.0.10: dependencies: call-bind: 1.0.8 diff --git a/posts/networking.md b/posts/networking.md index 85a28ed..04a9d19 100644 --- a/posts/networking.md +++ b/posts/networking.md @@ -58,6 +58,8 @@ The more you enjoy your work, the more you subconsciously position yourself for ## And remember... +Every conversation is a potential networking opportunity. + There is no "one true path" here. There are no guaranteed ways to land a job. There is no certainty in any of this. I share this advice because it has been my own journey to success, and I hope that it benefits some of you. But I am under no illusion that it will work for every person, every time. But hey... What's the worst that could happen? If you follow these guidelines and *don't* get a job, at the very least you should have made some new friends. And that's always a win! diff --git a/src/app/page.tsx b/src/app/page.tsx index 1b3f0be..8f2adad 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -24,6 +24,7 @@ const Home = (): JSX.Element => {

{post.data.title}

{post.data.date.toLocaleDateString("en-GB", { day: "numeric", month: "long", year: "numeric" })}

{post.data.summary}

+

{`A ${post.data.readtime} read.`}

; })} diff --git a/src/app/post/[slug]/page.tsx b/src/app/post/[slug]/page.tsx index 3ee29d2..136cc1a 100644 --- a/src/app/post/[slug]/page.tsx +++ b/src/app/post/[slug]/page.tsx @@ -31,6 +31,8 @@ const Page = async({ "en-GB", { day: "numeric", month: "long", weekday: "long", year: "numeric" }, )}`}

+

{post.data.summary}

+

{`A ${post.data.readtime} read.`}

{post.content} diff --git a/src/lib/posts.ts b/src/lib/posts.ts index 57726b3..12dde88 100644 --- a/src/lib/posts.ts +++ b/src/lib/posts.ts @@ -7,6 +7,7 @@ import { readFileSync, readdirSync } from "node:fs"; import { join } from "node:path"; import matter from "gray-matter"; +import readingTime from "reading-time"; const postsDirectory = join(process.cwd(), "posts"); @@ -16,7 +17,7 @@ const postsDirectory = join(process.cwd(), "posts"); */ const getSortedPostsData = (): Array<{ content: string; - data: { date: Date; summary: string; title: string }; + data: { date: Date; summary: string; title: string; readtime: string }; slug: string; }> => { const fileNames = readdirSync(postsDirectory); @@ -32,9 +33,10 @@ const getSortedPostsData = (): Array<{ return { content: matterResult.content, data: { - date: new Date(matterResult.data.date), - summary: matterResult.data.summary, - title: matterResult.data.title, + date: new Date(matterResult.data.date), + readtime: readingTime(matterResult.content).text, + summary: matterResult.data.summary, + title: matterResult.data.title, }, slug: slug, }; @@ -56,7 +58,7 @@ const getPostData = ( slug: string, ): { content: string; - data: { date: Date; summary: string; title: string }; + data: { date: Date; summary: string; title: string; readtime: string }; slug: string; } => { const fullPath = join(postsDirectory, `${slug}.md`); @@ -69,9 +71,10 @@ const getPostData = ( return { content: matterResult.content, data: { - date: new Date(matterResult.data.date), - summary: matterResult.data.summary, - title: matterResult.data.title, + date: new Date(matterResult.data.date), + readtime: readingTime(matterResult.content).text, + summary: matterResult.data.summary, + title: matterResult.data.title, }, slug: slug, };