1

My Problem

The nextjs documentation on mdx states that it does not support frontmatter. Instead it is suggested to create a constant and export it [1]. However I can't seem to get at data exported in such a way. For instance using the following

/* -- ./pages/example.mdx -- */
export const meta = {
    title: 'some example title'
}
/* -- ./pages/index.js -- */
import Example from './example.mdx';

export default function Index ({ ... props }) {
   return <Example />
}

It seems that what gets imported can be used as a react component, but there does not seem to be a reference to the meta property anywhere.

  • Example does not have a meta property
  • import { meta } from './example.mdx does not yield anything
  • There is no meta key on the rendered components
  • Using require ('./example.mdx') yields the same results.

What I wanted to do

I have a list of markdown files and want to create an overview page that lists all of them, using the metadata defined in every file. Something akin to the following

import fs from 'fs/promises';
import path from 'path';

export async function getStaticProps () {
    const root = path.join (process.cwd (), 'pages/items');
    const listing = await fs.readdir(root);
    const items = listing
        .filter (item => item.endsWith ('.mdx'))
        .map (item => {
            const meta = require (`./items/${item}`).meta;
            const id = item.replace (/\.md$/, '');
            return { id, ... meta }
        });

    return { props: { items } };
}

export default function Overview ({ items, ... props }) {
    /* ... use items */
}

Edit

It seems like there is a big difference between using .md and .mdx. In the examples I gave here I used .mdx, but locally I had used .md. Switching extensions makes everything work.

It is strange that the extension makes such a difference even though both of them are configured in next.config.js

const withMDX = require ('@next/mdx') ({
    extension: /\.mdx?$/
});
module.exports = withMDX ({ /* ... */ });

[1] https://nextjs.org/docs/advanced-features/using-mdx#frontmatter

vldmrrdjcc
  • 2,082
  • 5
  • 22
  • 41

2 Answers2

1

Use .mdx extension instead of a .md extension.

1

Seems like you can create a typing file to import it if you are using typescript

Step 1 - Create typing file

declare module '*.mdx' {
    export const meta: {
        title: string
    }
}

Step 2 - import the exported content

import Example, {meta} from './example.mdx';

Got the answer from here https://gist.github.com/peterblazejewicz/1ac0d99094d1886e7c9aee7e4faddef3#file-index-d-ts-L68

Chris
  • 612
  • 2
  • 9
  • 23