Trouble displaying personalized components from mdx-components.js in Next.js

I've been attempting to integrate custom components into my .mdx posts using the mdx-components.js file, however, the custom components are not being displayed.

Here's the code from my mdx-components.js file, which I created following the guidelines from the NextJS documentation:

// 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,
  };
}

Below is the code that renders the .mdx files on my page:

// 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 here's the code snippet responsible for fetching the content from the filesystem where the .mdx files are located:

// 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 };
};

As mentioned in the NextJS documentation:

By defining styles and components in mdx-components.tsx, changes will be reflected across all MDX files within your application.

Despite following the documentation closely, I'm unable to successfully render my custom link. If anyone could offer assistance with troubleshooting, it would be greatly appreciated.

I've examined the HTML output in the browser to check if the custom link is being displayed but possibly being overridden by other styles. However, it appears that the custom link is not rendering at all. I even attempted removing the mdx-components.js file to test if it was being loaded, and NextJS raised an error, confirming that the file is being loaded.

Answer №1

After much exploration, I finally discovered a workaround for this issue. By utilizing the compileMDX function to compile mdx markdown, components can be passed as an argument. As a result, my current file structure is as follows:

// 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 };
};

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Transferring a JavaScript Value to a PHP Variable (Under Certain Constraints)

Although I have reviewed existing questions and answers related to this issue, I found that the solutions provided do not suit my specific situation. Discussing the differences between client-side JavaScript and server-side PHP, two common solutions are: ...

What is the best way to interpret a JSON with nested structure?

I can't seem to find any errors in the code below, but I keep receiving an error message stating "item._highlightResult.map is not a function". {items.map((item, index) => ( <li key={index}><a href={item.story_url} target="_blank& ...

Is there a way to transfer a JSON array from a text/javascript block to a runat=server block within the context of ExactTarget/Salesforce Marketing Cloud?

I have a page containing two <script> elements: one is running locally and the other one is running on the ExactTarget server: <script type="text/javascript"> var results = localStorage.getItem('results'); var results = JSON.parse(re ...

How can JQuery be utilized to extract the information stored in the "value" parameter of a chosen option?

I have a dropdown menu that dynamically populates its options with numbers. Here is the code for that: <select name="TheServices" id="services-selector"> <option value="" disabled selected hidden>Static Select ...

Accordion content in motion

After creating an accordion, I wanted to enhance the user experience by adding a transition effect whenever they click on the accordion header. Even though I included height: auto and transition in the accordion container, it did not seem to have any impa ...

Managing browser back button functionality

I've been struggling to find a solution for handling the browser back button event. I would like to prompt the user with a "confirm box" if they click on the browser back button. If they choose 'ok', I need to allow the back button action, ...

Tips for choosing and deselecting data using jQuery

Is there a way to toggle the selection of data in my code? Currently, when I click on the data it gets selected and a tick image appears. However, I want it so that when I click again on the same data, the tick will disappear. How can I achieve this func ...

In Reactjs, Axios and fetch are both commonly used for sending ongoing network requests to localhost

In order to establish a successful connection between the express backend and MongoDB database, I initially used fetch("/") from the frontend, which returned the index.html code. However, when I switched to fetch("http://localhost:9000"), I encountered a C ...

Warning: Shadcn-UI Form Alert - An element is converting an uncontrolled input to controlled mode

Throughout the course of this project, I found myself repeatedly using const [fileNames, setFileNames] = useState<string[]>([]); and logging the state with console.log(fileNames). However, every time I clicked on the parent element, an empty Array e ...

Discovering which page the form was submitted from using xsl template

Incorporating code like <input type="hidden" value="contact-form-1" name="getpage"> into my form is something I'm interested in, as it allows me to retrieve the URL of the page from which the form was submitted. The challenge arises because the ...

Deleting multiple data records in PHP/SQL by using a Select Option

Currently, I have developed a system that allows for the deletion of multiple data using a select option. However, I am facing some issues with this functionality. When only one data is selected and the delete button is pressed, it successfully deletes the ...

What is the best way to refresh jCarousel following the loading of AJAX content?

After purchasing a custom jCarousel JavaScript (available at http://pastebin.com/BwsVpNjr), I encountered an issue when trying to load content with AJAX. The carousel breaks because it is unable to detect the width or height. Is there a way to have jCarous ...

Tips for incorporating external JavaScript code into React components

I have been tasked with integrating a graphical widget into a React component for a project I am working on. The widget_api code provided by RIPE Stat is required to accomplish this. Previously, in HTML5, the integration was successful using the following ...

How to Retrieve a Remote File in Angular using $http.get() with OAuth Authentication

I have a unique situation where my users possess private files that require downloads by authenticated users. The server I am using initially downloads a file from S3 utilizing its own set of S3 app_id and secret_token credentials. Once the file has been d ...

Node's original file name

Is there a way to retrieve the original filename from a file that has an absolute path in node.js? In node.js, I can use path.basename to get the name and base URL, and fs.stats for more detailed information like: Stats { dev: 2114, ino: 48064969, ...

Discover the position within a two-dimensional array

Suppose I have an array that contains objects, and each object has its own id property. In this case, I can find the index by writing: data.findIndex(x=>x.id === newData.id); Now, if data is an array of arrays of objects, how can I efficiently get two ...

How to capture the "chip close" event in Vuetify

Exploring the vuetify realm as a newcomer, I find myself grappling with event handling while working on my first web app project. Specifically, I am currently developing a "UserPicker" component using VAutocomplete. This component functions by sending an ...

Having trouble displaying an image in the Image tag when using Next.js and Material UI

I'm encountering an issue while attempting to showcase images in my Next.js project with Material UI. Here is the code snippet I am using: <Box display="flex" alignItems="center"> <Image s ...

Leveraging spread syntax and styling for array string interpolation in JavaScript

Imagine I have an array such as [1,2,3] and my goal is to insert its values into a string format like: the values are (?, ?, ?) Can anyone suggest a simple solution for this? I am aware of the spread operator ...[1,2,3], and it's feasible to conver ...

The for loop encountered an uncaught type error when trying to access the .length property

Currently, I am working on a school project where the task is to create a basic social network posting application using Django and JavaScript. The purpose of using JavaScript is to dynamically load posts onto the webpage and update HTML components. I have ...