shuding / nextra

Simple, powerful and flexible site generation framework with everything you love from Next.js.
https://nextra.site
MIT License
11.32k stars 1.24k forks source link

[v3] Broken MDX import #2951

Open andrii-bodnar opened 2 months ago

andrii-bodnar commented 2 months ago

I have some common parts in my documentation that I would like to import as separate files. It's possible according to this.

But when I import the mdx file into another mdx, the imported content doesn't show up, just headings get mixed up with the original page heading.

For example, I have the following test.mdx:

## Common content

common content

### Subsection 1

subsection 1 content

And I import it into the Introduction page:

import test from './test.mdx'

# Introduction

**Nextra** is a framework on top of Next.js, that lets you build content focused
websites. It has all the great features from Next.js, plus extra power to create
Markdown-based content with ease.

<test />

test

## Quick Start

import { Cards } from 'nextra/components'

To start using Nextra, you need to select a theme first:

...

Result:

Screenshot 2024-06-27 at 17 18 11

87xie commented 3 days ago

I referred to the MDX's using MDX guidelines:

‡ The rules for whether a name in JSX (so x in ) is a literal tag name (like h1) or not (like Component) are as follows:

  • If there’s a dot, it’s a member expression (<a.b> → h(a.b)), which means a reference to the key b taken from object a.
  • Otherwise, if the name is not a valid JS identifier, it’s a literal ( → h('a-b')).
  • Otherwise, if it starts with a lowercase, it’s a literal ( → h('a')).
  • Otherwise, it’s a reference ( → h(A)).

My guess is as follows:

  • In the above example, <test> starts with a lowercase letter, so MDX treats it as an HTML tag and compiles it to _jsx('test') instead of _jsx(test).
  • The headings in the TOC are parsed by Nextra's remark-headings plugin, which determines the headings based on the ESM exports.

I think a simple solution would be to rename test to UpperCamelCase so that MDX can correctly parse it as a component:

import Test from './test.mdx'

<Test />