Nicole Orchard
Nicole Orchard

Reputation: 11

Custom components not rendering from mdx-components.js in Next.js

I'm trying to pass custom components to my .mdx posts via the mdx-components.js file, but the custom components are not rendering.

This is my mdx-components.js file which I made based on the NextJS docs:

// my-blog/mdx-components.js

import UnderlineHoverLink from "./app/_components/Links/UnderlineHoverLink";

export function useMDXComponents(components) {
  return {
    a: ({ href, children }) => (
      <UnderlineHoverLink href={href}>{children}</UnderlineHoverLink>
    ),
    ...components,
  };
}

And this is the page where I am rendering the.mdx files:

// my-blog/app/(routes)/posts/[slug]/page.js:

import { getPostBySlug } from "@/app/_lib/mdx";

const getPageContent = async (slug) => {
  const { meta, content } = await getPostBySlug(slug);
  return { meta, content };
};

export async function generateMetadata({ params }) {
  const { meta } = await getPageContent(params.slug);
  return { title: meta.title };
}

const Page = async ({ params }) => {
  console.log(params);
  const { content } = await getPageContent(params.slug);
  return content;
};

export default Page;

and this is where I am getting the content from my filesystem where the .mdx files are:

// my-blog/app/_lib/mdx/index.js

import fs from "fs";
import path from "path";
import { compileMDX } from "next-mdx-remote/rsc";

const rootDirectory = path.join(process.cwd(), "content/posts");

export const getPostBySlug = async (slug) => {
  const realSlug = slug.replace(/\.mdx$/, "");
  const filePath = path.join(rootDirectory, `${realSlug}.mdx`);

  const fileContent = fs.readFileSync(filePath, { encoding: "utf8" });

  const { frontmatter, content } = await compileMDX({
    source: fileContent,
    options: { parseFrontmatter: true },
  });

  return { meta: { ...frontmatter, slug: realSlug }, content };
};

According to the NextJS documentation:

Adding styles and components in mdx-components.tsx will affect all MDX files in your application.

I've been following the documentation pretty closely, but I can't seem to get my custom link to render. Can anyone help me troubleshoot?

I inspected the output html in the browser to see if the custom link was rendering but other styling was overriding it. But it looks like the custom link is not rendering. I tried removing the mdx-components.js file to see if it wasn't being loaded at all, but NextJS threw an error, so I know the file is being loaded.

Upvotes: 0

Views: 576

Answers (1)

Nicole Orchard
Nicole Orchard

Reputation: 11

I ended up finding a solution to this. When using the compileMDX function to compile your mdx markdown, you can pass components as an argument. So now my file looks like this:

// my-blog/app/_lib/mdx/index.js

import fs from "fs";
import path from "path";
import { compileMDX } from "next-mdx-remote/rsc";
import { useMDXComponents } from "@/mdx-components";

const rootDirectory = path.join(process.cwd(), "content/posts");

export const getPostBySlug = async (slug) => {
  const realSlug = slug.replace(/\.mdx$/, "");
  const filePath = path.join(rootDirectory, `${realSlug}.mdx`);

  const fileContent = fs.readFileSync(filePath, { encoding: "utf8" });

  const { frontmatter, content } = await compileMDX({
    source: fileContent,
    components: useMDXComponents(),
    options: { parseFrontmatter: true },
  });

  return { meta: { ...frontmatter, slug: realSlug }, content };
};

Upvotes: 1

Related Questions