Skip to content
This repository has been archived by the owner on Nov 3, 2019. It is now read-only.

globalScope doesn't work for MDX content loaded with the webpack loader #239

Closed
ChristopherBiscardi opened this issue Jan 9, 2019 · 17 comments
Labels
bug Something isn't working

Comments

@ChristopherBiscardi
Copy link
Owner

Describe the bug

globalScope is a new feature meant to replace "shortcodes" in other platforms. Because we don't consume the MDXScopeProvider when loading MDX content in the mdx-loader, globalScope doesn't work for .mdx files in src/pages

@tujoworker
Copy link

@ChristopherBiscardi globalScope is a nice feature! So cool. But for me it seems that the global scopes are not available during the production build. Is that something You have heard about before?

@ChristopherBiscardi
Copy link
Owner Author

@tujoworker only for .mdx files in src/pages, which have the issue mentioned here.

@ChristopherBiscardi
Copy link
Owner Author

globalScope will be replaced with MDXProvider in @mdx-js/mdx@1.0, which will work everywhere and you'll be able to use like this.

<MDXProvider
  components={{ Video: () => <ReactYoutube/> }}
>

@erikdstock
Copy link

erikdstock commented Apr 14, 2019

@ChristopherBiscardi - Are you saying that the globalScope option in the gatsby-config.js no longer has any effect in 0.6.2/@mdx-js/mdx@1.0, and that we should load them via <MdxProvider ... alongside the layout components, like (for example using rebass)? If so I can try to PR a documentation update later.

Is this understanding correct?

import { Text, Button } from 'rebass'

const H1 = props => <Text as="h1" fontFamily="sans" {...props} />
// etc...

const LayoutComponents = {
  H1,
  p: Text,
  wrapper:  ({ children }) => <>{children}</>,
  // etc...
}

// Previously from gatsby-mdx plugin options.globalscope
const GlobalScopeComponents = {
  Button,
  // etc...
}

export const Boot = ({ element }) => {
  return (
    <MDXProvider
      components={{
        ...LayoutComponents,
        ...GlobalScopeComponents
      }}
    >
      <Theme>{element}</Theme>
    </MDXProvider>
  )
}

@ChristopherBiscardi
Copy link
Owner Author

Are you saying that the globalScope option in the gatsby-config.js no longer has any effect in 0.6.2/@mdx-js/mdx@1.0

The globalScope option is still there and still works. However, globalScope will be deprecated and removed since MDXProvider "Shortcodes" supersedes it. We're giving the "shortcodes" functionality a bit of time to bake in mdx-js/mdx 1.0 before documenting it as the official solution. I'm already using it on my blog though, for example, and your understanding of how it works is correct.

@erikdstock
Copy link

Ah, thanks. FWIW globalScope stopped working for me over the weekend as I was updating dependencies across my repo- just got a Button is not defined error on the gatsby page (but not in the CMS where I was making it available differently).

@ChristopherBiscardi
Copy link
Owner Author

hmm, that's not good. Since we have the alternative method in MDXProvider fixing it isn't as high a priority as other things, but I'll put it on my list to look into.

@johno
Copy link
Collaborator

johno commented Apr 16, 2019

@erikdstock have you been able to get it working using the MDXProvider approach?

@erikdstock
Copy link

@johno Yep, I was able to above. You can see it in my starter- to clarify the wrapper component described in my comment is still necessary?

@ChristopherBiscardi
Copy link
Owner Author

@erikdstock Not since 1.0.6, which shipped a different default for the wrapper

flyinggrizzly added a commit to flyinggrizzly/fgnet-mdx that referenced this issue Apr 26, 2019
see ChristopherBiscardi/gatsby-mdx#239

the `globalScope` config option is deprecated in favor of passing more
components into the provider
@thundernixon
Copy link

thundernixon commented Apr 27, 2019

Oof, this was a tricky solution to adapt to my purposes, but I got it working (at least, mostly working, though with slightly different CSS than before – possibly because I also updated versions of Gatsby and React along with these changes). So, I'm posting my approach here, which was based on code from @erikdstock & @ChristopherBiscardi, above.

Hope this isn't either too verbose or too minimal. I know it helps me to see various examples, so hopefully this helps someone else out there! If others see this and see clear flaws, please let me know.

src/components/mdx-provider.js

This is a wrapper component. It serves the purpose that was previously filled by options.globalscope – allowing global "shortcodes" to be used on my blog/portfolio .mdx posts.

import React from 'react'
import { MDXProvider } from '@mdx-js/react'

// import each component (these all live in the same 'components' folder)
import ImageRowStack from './image-rowstack.js'
import ImageFullWidth from './image-fullwidth.js'
import Caption from './image-caption.js'
import Process from './process-section.js'

// set up a dictionary of imported components
const GlobalScopeComponents = {
  ImageRowStack: ImageRowStack,
  ImageFullWidth: ImageFullWidth,
  Caption: Caption,
  Process: Process,
}

// export a MDXWrapper component, which will pass these components into the child mdx posts
export const MDXWrapper = ({ children }) => {
  return (
    <MDXProvider components={{ ...GlobalScopeComponents }}>
      {children}
    </MDXProvider>
  )
}

src/layouts/project.js

This is used as a layout for blog/portfolio project posts.

import React from 'react'
import { graphql } from 'gatsby'
import MDXRenderer from 'gatsby-mdx/mdx-renderer'
import { MDXWrapper } from '../components/mdx-provider'
// plus other imports required by other things in the project component


export default class ProjectPage extends React.Component {
    render() {
    const mdx = this.props.data.mdx
    return (
        <MDXWrapper>

            {/* other page structure */}
            
            <MDXRenderer>{mdx.code.body}</MDXRenderer>

            {/* other page structure */}

        </MDXWrapper>
    )
}

export const pageQuery = graphql`
  query ProjectQuery($id: String) {
    mdx(id: { eq: $id }) {
      id
      frontmatter {
        # metadata like project title, top description, hero image, etc
      }
      code {
        body
      }
    }
  }
`

@Ehesp
Copy link
Contributor

Ehesp commented May 1, 2019

I've just upgraded to the latest gatsby-mdx version & I'm struggling to get anything rendering using my own provided components. I'm somewhat confused - there's a few different examples going around, e.g. @thundernixon uses MDXProvider from @mdx-js/react whereas the docs use it from @mdx-js/tag.

import { MDXRenderer } from 'gatsby-mdx';
import { MDXProvider } from '@mdx-js/tag';

const components = {
  h1: props => <Heading {...props} el={'h1'} />,
  h2: props => <Heading {...props} el={'h2'} />,
  img: Image,
  a: Anchor,
  pre: AutomatedCodeBlock,
};

export const scope = {
  Icon,
};

// children = mdx.code.body
function Provider({ children }) {
  return (
    <MDXProvider component={{ ...components, ...scope }}>
        <MDXRenderer>{children}</MDXRenderer>
    </MDXProvider>
  );
}

My HTML renders correctly, but never passes through any of my custom components. Going to stick with an older version where I had this working as I'm struggling to keep up with the changes to the API until it's stable I think.

"@mdx-js/mdx": "^1.0.15",
"gatsby": "2.1.18",
"gatsby-mdx": "^0.6.3",

EDIT: Got it working somehow - using @mdx-js/react instead of @mdx-js/tag. Although code blocks are broke so checking them out 👍 (Had to upgrade mdx-utils)

@millette
Copy link

millette commented May 1, 2019

@Ehesp @mdx-js/tag is now called @mdx-js/react. The former should be considered deprecated. Don't remember the reference though, so no link to provide.

@johno
Copy link
Collaborator

johno commented May 1, 2019

Here's the link: https://mdxjs.com/migrating/v1#pragma

FWIW, @Ehesp, the last remaining change that will happen is renaming gatsby-mdx to gatsby-plugin-mdx when we release the official v1 soon. So it's safe to say things are stable now. Apologies for the churn during the MDX core v1 release.

@jennasalau
Copy link

Thanks @millette I've been banging my head on a wall for two days... @mdx-js-react over mdx tag solved everything!

@robinmetral
Copy link

Could be good to update this page and mention MDXProvider 🙂

@ChristopherBiscardi
Copy link
Owner Author

globalScope is deprecated in favor of MDXProvider

gatsby-mdx is now gatsby-plugin-mdx and published from the Gatsby repo: gatsbyjs/gatsby#14657

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

9 participants