Linked mentions with Contentlayer

@sirajchokshi

Table of Contents

  1. Usage

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:

linked-mentions.ts
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.

pages/[slug].tsx
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>
  );
}