Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing common prop to all components in MDX file, without adding the prop to each component

I've got mdx files with components that need to be locale aware.

Lots of components. And they all need to be locale-aware.

In the .mdx files, I can change them from this:

<FirstDayOfMonth/>

to that:

<FirstDayOfMonth lang="fr"/>

But then I'd need to do it for every component in every .mdx file.

Is there a way to make a prop available to all components used in mdx?


I thought of passing it to the MDXRenderer, something like this:

<MDXProvider>
  <MDXRenderer lang={currentLang}>{body}</MDXRenderer>
</MDXProvider>

Or accessing the frontmatter from the components.

But both approaches are not documented and didn't give any results.

Better ideas?


per request, list of relevant dependencies:

  "dependencies": {
    "@mdx-js/mdx": "^1.6.22",
    "@mdx-js/react": "^1.6.22",
    "gatsby": "^3.6.2",
    "gatsby-plugin-copy-files-enhanced": "^1.1.1",
    "gatsby-plugin-mdx": "^2.11.0",
    "preact": "^10.5.13",
    "preact-render-to-string": "^5.1.19",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
}
like image 324
Félix Paradis Avatar asked Sep 10 '25 01:09

Félix Paradis


1 Answers

You could add those props when passing the shortcodes to the MDXProvider by iterating through the map and returning new components with the default props injected.

import FirstDayOfMonth from 'path/to/FirstDayOfMonth';

const addProps = (components, defaultProps) => {
  const withProps = {};

  for (const [key, Component] of Object.entries(components)) {
    withProps[key] = (props) => <Component {...defaultProps} {...props} />
  }

  return withProps;
}

const shortcodes = { FirstDayOfMonth, SomeOtherComponent };

const Layout = ({ children }) => {
  const someDefaultProps = {
    lang: "fr",
    something: "else",
  };

  const shortcodesWithProps = useMemo(
    () => addProps(shortcodes, someDefaultProps),
    someDefaultProps
  );

  return (
        ...
        <>
          <MDXProvider components={shortcodesWithProps}>
            {children}
          </MDXProvider>
        </>
       ...
  );
};
like image 139
diedu Avatar answered Sep 12 '25 14:09

diedu