Table of Contents
My ideal personal site is something in between a journal and wiki. A killer feature of wikis is bi-directional links. These are also known as metioned links or backlinks. If you’re reading a page, you can see all the pages that link to it; a great way to discover related content.
Contentlayer is a library that acts as like an ORM for markdown content. It has become popular in the Next.js ecosystem as a way to manage content for static sites. It’s easy to build on top of since all content is available through a strongly-typed, generated module.
The allDocuments
array can be iterated over to find all the documents that link to a given page. Here’s a function that returns an array of backlinks for a given slug:
import { allDocuments } from "contentlayer/generated";
function getLinkedMentions(slug: string) {
return (
allDocuments
// filter out documents that don't contain a link
// to the provided document
.filter((doc) => doc.body.raw.includes("[[" + slug))
// map to title and slug for rendering
.map((doc) => ({
title: doc.title,
url: doc.url,
}))
);
}
Usage
Then, in your page component, you can call this function and render the results. The example below is in Next.js, but the approach can be used broadly.
import { getLinkedMentions } from "@/lib/linked-mentions";
export default function Page({ slug }) {
const mentions = getLinkedMentions(slug);
return (
<div>
<!-- page content -->
<h3>Mentions</h3>
<ul>
{mentions.map((link) => (
<li>
<a href={link.url}>{link.title}</a>
</li>
))}
</ul>
</div>
);
}