Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using MDXProvider with mdx-components.tsx #69613

Open
ProchaLu opened this issue Sep 3, 2024 · 2 comments
Open

Using MDXProvider with mdx-components.tsx #69613

ProchaLu opened this issue Sep 3, 2024 · 2 comments
Labels
bug Issue was opened via the bug report template. Markdown (MDX) Related to Markdown with Next.js.

Comments

@ProchaLu
Copy link
Contributor

ProchaLu commented Sep 3, 2024

Link to the code that reproduces this issue

https://github.com/ProchaLu/next-js-mdx-provider

CodeSandbox

To Reproduce

  1. Clone repro, git clone https://github.com/ProchaLu/next-js-mdx-provider
  2. install dependencies
  3. run development server

Current vs. Expected behavior

I'm trying to use both mdx-components.tsx and MDXProvider together (like the nested MDXProvider pattern). Our constraints are as follows:

  1. our app is large with multiple areas - different areas should receive different MDX components

  2. we are trying to avoid prop drilling - having to pass components={props.components} in every MDX file where we import another MDX file, eg. trying to avoid this:

    import Child from './child.mdx'
    {/* Trying to avoid this */}
    <Child components={props.components} />

Current Behavior

When using the MDXProvider in MDXComponent.tsx to provide custom components (h3 and h4), these components are not applied to the MDX content. Instead, only the global components defined in mdx-components.tsx (for h1 and h2) are applied.

mdx-components.tsx

const components = {
  h1: ({ children, ...props }: HTMLAttributes<HTMLHeadElement>) => (
    <h1 style={{ color: 'tomato' }} {...props}>
      {children}
    </h1>
  ),
  h2: ({ children, ...props }: HTMLAttributes<HTMLHeadElement>) => (
    <h2 style={{ color: 'blue' }} {...props}>
      {children}
    </h2>
  ),
} satisfies MDXComponents;

declare global {
  type MDXProvidedComponents = typeof components;
}
// eslint-disable-next-line no-undef
export function useMDXComponents(): MDXProvidedComponents {
  return components;
}

MDXComponent.tsx

'use client';

import { MDXProvider } from '@mdx-js/react';
import { MDXComponents } from 'mdx/types';
import { HTMLAttributes } from 'react';
import Content from './message.mdx';

const components = {
  h3: ({ children, ...props }: HTMLAttributes<HTMLHeadElement>) => (
    <h3 style={{ color: 'purple' }} {...props}>
      {children}
    </h3>
  ),
  h4: ({ children, ...props }: HTMLAttributes<HTMLHeadElement>) => (
    <h4 style={{ color: 'yellow' }} {...props}>
      {children}
    </h4>
  ),
} satisfies MDXComponents;

export default function MDXComponent() {
  return (
    <MDXProvider components={components}>
      <Content />
    </MDXProvider>
  );
}
Screenshot 2024-09-03 at 14 04 07

Expected Behavior

The MDXProvider in MDXComponent.tsx should apply its locally defined custom components (h3 and h4) to the MDX content.

  • h1 and h2 should get their styles from the global mdx-components.tsx.
  • h3 and h4 should get their styles from the local MDXProvider in MDXComponent.tsx.

This would allow for a more flexible and modular approach where different sections of the application can have different MDX component configurations without the need for prop drilling or defining all components globally.

However, it appears that this is not supported in the Next.js MDX integration:

Are there any suggestions for providing custom MDX components in different app areas without manually prop drilling?

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 23.5.0: Wed May  1 20:19:05 PDT 2024; root:xnu-10063.121.3~5/RELEASE_ARM64_T8112
  Available memory (MB): 16384
  Available CPU cores: 8
Binaries:
  Node: 20.16.0
  npm: 10.8.1
  Yarn: N/A
  pnpm: 9.4.0
Relevant Packages:
  next: 14.2.7 // Latest available version is detected (14.2.7).
  eslint-config-next: N/A
  react: 18.2.0
  react-dom: 18.2.0
  typescript: 5.5.2
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

Markdown (MDX)

Which stage(s) are affected? (Select all that apply)

next dev (local), next build (local), next start (local)

Additional context

No response

@ProchaLu ProchaLu added the bug Issue was opened via the bug report template. label Sep 3, 2024
@github-actions github-actions bot added the Markdown (MDX) Related to Markdown with Next.js. label Sep 3, 2024
@r-sp
Copy link

r-sp commented Nov 13, 2024

as mention on mdx provider section, You probably don’t need a provider. Passing components is typically fine. Providers often only add extra weight. we already had global and local styles. it's enough for me.


Are there any suggestions for providing custom MDX components in different app areas without manually prop drilling?

well, we can use custom element modifiers from tailwindcss-typography. or built a custom css styles for it. we don't need to override global mdx components again.

@karlhorky
Copy link
Contributor

karlhorky commented Nov 13, 2024

it's enough for me.

That's good, but I think the point of this issue is, it's not enough for everyone.

Having multiple configurable global components configurations (either via providers or via some other mechanism) would be important for medium-large apps with multiple groups of MDX files which should be authored with different global components.

Even in our relatively small codebase, we have multiple different groups of MDX files which should receive different global components.

well, we can use custom element modifiers from tailwindcss-typography. or built a custom css styles for it. we don't need to override global mdx components again.

I'm not sure if you're suggesting only a solution for custom CSS styles, but this issue is not about custom CSS styles - it's about providing different global components to different MDX files. React components are not only about styling.

If I remember correctly, Lukas was just using styling as a simple, visual illustration to show which component is which.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Issue was opened via the bug report template. Markdown (MDX) Related to Markdown with Next.js.
Projects
None yet
Development

No branches or pull requests

3 participants