Coder Social home page Coder Social logo

christopherbiscardi / gatsby-mdx Goto Github PK

View Code? Open in Web Editor NEW
714.0 17.0 101.0 6.93 MB

Gatsby+MDX • Transformers, CMS UI Extensions, and Ecosystem Components for ambitious projects

Home Page: https://gatsby-mdx.netlify.com/

JavaScript 98.14% HTML 1.86%

gatsby-mdx's Introduction

Join the community on Spectrum

Gatsby+MDX has been merged into the Gatsby repo. Please go there for core work and documentation now: https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-plugin-mdx This repo is now a set of ecosystem components like mdx-utils and pre-made components for syntax highlighting, etc.

What is MDX?

MDX is a JSX in Markdown loader, parser, and renderer for ambitious projects. It combines the readability of Markdown with the expressivity of JSX. The best of both worlds. 🌐

See the MDX specification

Contributing

See CONTRIBUTING.md.

gatsby-mdx's People

Contributors

alexandernanberg avatar avigoldman avatar canrau avatar christopherbiscardi avatar devdigital avatar greggb avatar itwasmattgregg avatar jamiemchale avatar jessefarebro avatar johno avatar lehnerpat avatar macklinu avatar mathieudutour avatar maxdesiatov avatar mbilokonsky avatar mmmaaatttttt avatar necmttn avatar noahsark769 avatar nokome avatar pascal-kubrick avatar philals avatar rdrey avatar redallen avatar ryaninvents avatar stefanjudis avatar swyxio avatar wesbos avatar xhmm avatar youngboy avatar ziegfried avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gatsby-mdx's Issues

Frontmatter

Desired Functionality

A user should be able to add frontmatter in either the classic way or as ES2015 style export.

Classic
---
title: My First Post
---

Welcome to my blog
ES2015 export
export const frontmatter = {
  title: "My First Post"
}

Welcome to my blog

Configuration Options

Desired Functionality

The user should be able to configure the mdx loader (#2) and add any additional extensions they want to use for MDX files.

module.exports = {
  siteMetadata: {
    title: `my great site`
  },
  plugins: [
    `gatsby-plugin-emotion`,
    `gatsby-plugin-react-helmet`,
    {
      resolve: `gatsby-mdx`,
      options: {
        extension: ['.mdx', '.md']
      }
    },
  ]
};

Error When Using Node 6.x

Describe the bug
I created a fresh install using the gatsby-starter-default making sure to use the v2 branch. I followed the instructions via the setup process to install this plugin and the necessary dependencies. I also added the plugin to the gatsby-config.js

When I run gatsby develop I get an error (see screenshot below)

To Reproduce

  1. Clone https://github.com/ryanwiemer/gatsby-mdx-test
  2. Install dependencies
  3. Run gatsby develop
  4. See error

Screenshots
error

Additional context
I tried running your kitchen-sink example locally and I see the same error. 🤷Maybe I am missing something super obvious and if so I apologize.

`wordCount` conflicts with `gatsby-transformer-remark`

Hi! When using both gatsby-mdx and gatsby-transformer-remark, I get the following error when I create a foo.mdx file outside of the src/pages directory. Oddly, the error doesn't appear if the MDX file is within src/pages.

$ gatsby develop --port 8090
success open and validate gatsby-config — 0.007 s
success load plugins — 0.183 s
success onPreInit — 0.487 s
success delete html and css files from previous builds — 0.649 s
success initialize cache — 0.012 s
success copy gatsby files — 0.035 s
success onPreBootstrap — 0.001 s
success source and transform nodes — 10.113 s
error UNHANDLED REJECTION


  Error: Schema must contain unique named types but contains multiple types named "wordCount  ".

  - Array.forEach

  - Array.forEach

  - Array.forEach

  - Array.forEach

While this isn't the fix, commenting out these lines makes the error go away:

wordCount: {
type: new GraphQLObjectType({
name: `wordCount`,
fields: {
paragraphs: {
type: GraphQLInt
},
sentences: {
type: GraphQLInt
},
words: {
type: GraphQLInt
}
}
}),
async resolve(mdxNode) {
let counts = {};
const text = await getText(mdxNode);
await retext()
.use(count)
.process(text);
return {
paragraphs: counts.ParagraphNode,
sentences: counts.SentenceNode,
words: counts.WordNode
};
function count() {
return counter;
function counter(tree) {
visit(tree, visitor);
function visitor(node) {
counts[node.type] = (counts[node.type] || 0) + 1;
}
}
}
}

The error also goes away if I turn off gatsby-transformer-remark.

Are these two libraries supposed to be able to co-exist? I'm diving into this a little more to see why it works if the MDX file is within src/pages.

Bug: Cannot find module `gatsby/graphql` on fresh install

This may be an issue with the Gatsby, but it only occurs with gatsby-mdx.

This Repo contains a fresh default template created by gatsby and then an installed gatsby-mdx plugin.

To see it crash, run:

yarn develop

To "fix" the issue, you can remove gatsby-mdx from the plugins in the gatsby-config.js.

For reference, the current versions in that repo:

    "@mdx-js/loader": "^0.15.0-0",
    "@mdx-js/mdx": "^0.15.0-0",
    "gatsby": "^1.9.277",
    "gatsby-link": "^1.6.46",
    "gatsby-mdx": "^0.0.3",

Default Layout

Thoughts on adding in a default layout option for MDX pages to avoid importing and exporting the same layout for all pages?

Creating mdx node in bootstrap sequence

Is there a way to create a mdx node from a text being imported during the bootstrap sequence from another source than the local files (from a CMS or firebase)?
To produce a md node from outside, I can do:

exports.onCreateNode = ({ node, actions}) => {
  const { createNode } = actions;
  if (node.internal.type === `Chapter`) {
    createNode({
      id: `md-${node.id}`,
      parent: node.id,
      children: [],
      internal: {
        type: `${node.internal.type}Markdown`,
        mediaType: `text/markdown`,
        content: node.name,
        contentDigest: node.internal.contentDigest
      }
    })
  }
}

This way I create an allChapterMarkdown node. Is there a similar way to create a kind of allChapterMdx?
The goal is being able to write mdx content in a file stored in a database or in a CMS markdown editor that will be processed as a mdx file in Gatsby.

Thanks

mdx plugin is not working graphql query

I am testing with remark-toc plugin,

by using this lib it is works well for direct import

   // gatsby-config.js
    const toc = require('remark-toc')
    ...
    {
      resolve: `gatsby-mdx`,
      options: {
        mdPlugins: [toc],
      }
    },
    ...

but query graphql code showing that TOC(table of content) plugin is not working correctly.

I think bug is in gatsby-node https://github.com/ChristopherBiscardi/gatsby-mdx/blob/master/packages/gatsby-mdx/gatsby-node.js#L28

here you guys forgot pass options for parsing ? but for mdx-loader it is works find.

tableOfContents fails if there is no content

tableOfContents processing will throw errors on empty mdx files. Not really important, but a bit annoying if it pops up and you had a file touch'd with no content

{
  "errors": [
    {
      "message": "Cannot read property 'type' of null",
      "locations": [
        {
          "line": 14,
          "column": 9
        }
      ],
      "path": [
        "allMdx",
        "edges",
        2,
        "node",
        "tableOfContents"
      ]
    }
  ],
  data: {...}

Adding Prettier

We should use the same prettier set up as the Gatsby mono-repo.

MDX and MDX "extensions"

IMO gatsby-mdx should be an overarching package that provides support for the entire MDX ecosystem. However it seems to make sense from a maintainability perspective, a technical perspective, and a user perspective to be able to use MDX and its extensions piecemeal.

  • gatsby-mdx
  • gatsby-plugin-mdx-deck
  • gatsby-mdx-utils?
  • babel-plugin-pluck-imports
  • babel-plugin-pluck-exports

Under this scheme nothing really changes for end-users. They still install gatsby-mdx and any other extensions they want, then configure using the gatsby-mdx. For example a "full installation" would look like this right now:

yarn add gatsby-mdx @mdx-js/tag @mdx-js/mdx gatsby-plugin-mdx-deck mdx-deck

It's a bit much to install but we do want people to be able to control their version of mdx (which means mdx and tag).

TBD on whether gatsby-plugin-mdx-deck is a plugin to gatsby-mdx or not.


mdx-deck should be treated as a new data type and not a continuation of the core mdx type as it is effectively a datatype that contains an array of mdx content.

One interesting question is: Is it worth it to be able to create an mdx-deck sourced from multiple mdx nodes? This could open up an interesting model for CMS' to do slide creation.

graphql queries in .mdx pages

To have pageQuery in .mdx files work, we need to resolve the issue of tagged template literals being parsed as inline code blocks.

mdx.sync("import {Component} from 'react'; export const pageQuery = graphql`my-graphql-query`\n\
# what\n\
 `test`");

compiles to the following, which treats my-graphql-query as inline code.

export default ({ components }) => (
  <MDXTag name="wrapper" components={components}>
    <MDXTag name="p" components={components}>
      {`import {Component} from 'react'; export const pageQuery = graphql`}
      <MDXTag
        name="inlineCode"
        components={components}
        parentName="p"
      >{`my-graphql-query`}</MDXTag>
    </MDXTag>
    <MDXTag name="h1" components={components}>{`what`}</MDXTag>
    <MDXTag name="p" components={components}>
      {` `}
      <MDXTag
        name="inlineCode"
        components={components}
        parentName="p"
      >{`test`}</MDXTag>
    </MDXTag>
  </MDXTag>
);

frontmatter treated as content when no exports

This markdown file will get treated normally:

---
title: "MDX Rocks"
date: "2017-08-10"
---

export default ({ children }) => (
  <div>
    <h1>My Layout</h1>
    <div>{children}</div>
  </div>
)

## My MDX

Some dope content.

image

If the exports are removed then this same document gets its frontmatter included in its rendered content:

---
title: "MDX Rocks"
date: "2017-08-10"
---

## My MDX

Some dope content.

image

Add editable code blocks documentation to README

What are your implementation thoughts about adding editable code blocks using gatsby-mdx? Would you use a library like react-live? Curious to hear your thoughts/suggestions on where to look, as I hope to add this feature to a design system docs site this week and would be happy to help update the README with a suggested implementation.

_frontmatter included in Layout prop on default export after mdx compilation

 ERROR  Failed to compile with 1 errors                                                                              00:07:17

 error  in ./src/pages/test/index.mdx

Syntax Error: SyntaxError: /Users/username/Sites/sitename/src/pages/test/index.mdx: Unexpected token, expected "}" (10:82)

   8 | import DefaultLayout from "/Users/username/Sites/sitename/src/components/layout.js";
   9 |
> 10 | export default ({components, ...props}) => <MDXTag name="wrapper" Layout={_default;
     |                                                                                   ^
  11 | export var _frontmatter = {};
  12 | ;} layoutProps={props} components={components}>
  13 | <MDXTag name="p" components={components}>{`(function () {

After following the docs to install gatsby-mdx, it doesn't compile.
I just updated to gatsby v2. Everything else works fine.

Component to render code snippet given git revision and line ranges

Is your feature request related to a problem? Please describe.
I'm always frustrated when I check the docs for a function (say at reactjs.org) and it doesn't have a "View source" link that immediately shows me the implementation inline.

Describe the solution you'd like
I'd like to have an object that I could use like this:

<GitSnippet
  revision={"master:./README"}
  highlightRange={"5-6, 14-17"}
  hidelineRange={"1-3"}
/>

The revision field would ideally accept as much as possible of the gitrevision syntax (example). Highlighting and "hidelining" could be delegated remark-embed-snippet.

Describe alternatives you've considered
The alternative seems to be copy/pasting source chunks into markdown, making it error-prone, impractical at scale, and hard to update.

Additional context
This issue is a continuation of a twitter thread discussing the idea.

allMdx() not appearing in graphIQL

Hi,

I have set up a minimal MDX support in a gatsby2 ("next") now, just one .mdx page under src/pages/ and it renders as intended.
But I can't query it on graphQL so I'm kind of stuck e.g. to get the TOC built. "allMdx" is simply not appearing in graphIQL on localhost:8000/___graphql .

No errors on console.

gatsby-config.js plugins section:

  ....
    `gatsby-transformer-remark`,
    {
      resolve: `gatsby-mdx`,
      options: {
        extensions: [".mdx"],
        defaultLayouts: {
          default: require.resolve("./src/components/layout.js")
        }
      }
    }
   ....

any idea where I could start finding the problem?

gatsby-mdx version is "0.0.9", gatsby is 2.0.0-beta.83

defaultLayouts and wrappers

mdx-deck uses the default export (read: default layout) as a container for each individual slide.

  • create a new pre-mdx-deck loader
  • pull default export logic out of mdx-loader into a util. Use that logic in pre-mdx-loader as well
  • introduce the concept of a wrapper? may not need this and will leave it for a second PR.

Layouts and Wrappers

Layouts are an MDX concept. They are correlate directly to the default export of an mdx file. In regular mdx files, this means they end up wrapping the entire page. In mdx-deck files, they wrap each individual slide. Which raises the question: Do we need a wrapper that is page level? Is something like having a presentation couched in the navigation, etc of a website useful? I'd think so.

Error: Cannot find module '@babel/core' while following "Initial Setup" steps

Describe the bug

I tried getting an example project running to play around with this project(to start looking into #70) but I'm seeing

Error: Cannot find module '@babel/core'

while following the initial setup steps.

To Reproduce

Steps to reproduce the behavior:

  1. Follow Gatsby's getting started steps:
  • `gatsby new gatsby-site
  • cd gatsby-site
  • gatsby develop
  • Everything works!
  1. Follow intial setup steps in this repo's readme:
  • npm install gatsby-mdx @mdx-js/mdx @mdx-js/tag or yarn add ...
  • Add gatsby-mdx to gatsby-config.js:
module.exports = {
  siteMetadata: {
    title: 'Gatsby Default Starter',
  },
  plugins: ['gatsby-plugin-react-helmet', 'gatsby-mdx'],
}
  1. Kill the old process and run gatsby develop again

Expected behavior

Gatsby to run normally.

Full output:

 → mdx-codeintellify $ gatsby develop
success delete html and css files from previous builds — 0.018 s
success open and validate gatsby-config — 0.004 s
info One or more of your plugins have changed since the last time you ran Gatsby. As
a precaution, we're deleting your site's cache to ensure there's not any stale
data
success copy gatsby files — 0.014 s
error UNHANDLED EXCEPTION


  Error: Cannot find module '@babel/core'

  - loader.js:581 Function.Module._resolveFilename
    internal/modules/cjs/loader.js:581:15

  - loader.js:507 Function.Module._load
    internal/modules/cjs/loader.js:507:25

  - loader.js:637 Module.require
    internal/modules/cjs/loader.js:637:17

  - v8-compile-cache.js:159 require
    [mdx-codeintellify]/[v8-compile-cache]/v8-compile-cache.js:159:20

  - extract-exports.js:1 Object.<anonymous>
    [mdx-codeintellify]/[gatsby-mdx]/utils/extract-exports.js:1:77

  - v8-compile-cache.js:178 Module._compile
    [mdx-codeintellify]/[v8-compile-cache]/v8-compile-cache.js:178:30

  - loader.js:700 Object.Module._extensions..js
    internal/modules/cjs/loader.js:700:10

  - loader.js:599 Module.load
    internal/modules/cjs/loader.js:599:32

  - loader.js:538 tryModuleLoad
    internal/modules/cjs/loader.js:538:12

  - loader.js:530 Function.Module._load
    internal/modules/cjs/loader.js:530:3

  - loader.js:637 Module.require
    internal/modules/cjs/loader.js:637:17

  - v8-compile-cache.js:159 require
    [mdx-codeintellify]/[v8-compile-cache]/v8-compile-cache.js:159:20

  - on-create-node.js:5 Object.<anonymous>
    [mdx-codeintellify]/[gatsby-mdx]/on-create-node.js:5:24

  - v8-compile-cache.js:178 Module._compile
    [mdx-codeintellify]/[v8-compile-cache]/v8-compile-cache.js:178:30

  - loader.js:700 Object.Module._extensions..js
    internal/modules/cjs/loader.js:700:10

  - loader.js:599 Module.load
    internal/modules/cjs/loader.js:599:32

  - loader.js:538 tryModuleLoad
    internal/modules/cjs/loader.js:538:12

  - loader.js:530 Function.Module._load
    internal/modules/cjs/loader.js:530:3

  - loader.js:637 Module.require
    internal/modules/cjs/loader.js:637:17

  - v8-compile-cache.js:159 require
    [mdx-codeintellify]/[v8-compile-cache]/v8-compile-cache.js:159:20

  - gatsby-node.js:9 Object.<anonymous>
    [mdx-codeintellify]/[gatsby-mdx]/gatsby-node.js:9:24

  - v8-compile-cache.js:178 Module._compile
    [mdx-codeintellify]/[v8-compile-cache]/v8-compile-cache.js:178:30

Introduce Jest

Time to get some snapshot testing in here now that we're supporting quite a few different ways of combining frontmatter, non-frontmatter, default layouts, mdx-decks, etc.

Focusing on the webpack loader input/output first.

Upgrading from 0.0.6 to 0.0.7 breaks the plugin

I tried upgrading from 0.0.6 to 0.0.7 (and 0.0.8) and got this error when running gatsby develop:

error Plugin gatsby-mdx returned an error


  TypeError: Cannot read property 'map' of undefined

  - gatsby-node.js:34 Object.exports.onCreateWebpackConfig
    [seeds-v2]/[gatsby-mdx]/gatsby-node.js:34:31

  - api-runner-node.js:137 runAPI
    [seeds-v2]/[gatsby]/dist/utils/api-runner-node.js:137:37

  - api-runner-node.js:247 Promise.mapSeries.plugin
    [seeds-v2]/[gatsby]/dist/utils/api-runner-node.js:247:32

  - util.js:16 tryCatcher
    [seeds-v2]/[bluebird]/js/release/util.js:16:23

  - reduce.js:155 Object.gotValue
    [seeds-v2]/[bluebird]/js/release/reduce.js:155:18

  - reduce.js:144 Object.gotAccum
    [seeds-v2]/[bluebird]/js/release/reduce.js:144:25

  - util.js:16 Object.tryCatcher
    [seeds-v2]/[bluebird]/js/release/util.js:16:23

  - promise.js:512 Promise._settlePromiseFromHandler
    [seeds-v2]/[bluebird]/js/release/promise.js:512:31

  - promise.js:569 Promise._settlePromise
    [seeds-v2]/[bluebird]/js/release/promise.js:569:18

  - promise.js:614 Promise._settlePromise0
    [seeds-v2]/[bluebird]/js/release/promise.js:614:10

  - promise.js:693 Promise._settlePromises
    [seeds-v2]/[bluebird]/js/release/promise.js:693:18

  - async.js:133 Async._drainQueue
    [seeds-v2]/[bluebird]/js/release/async.js:133:16

  - async.js:143 Async._drainQueues
    [seeds-v2]/[bluebird]/js/release/async.js:143:10

  - async.js:17 Immediate.Async.drainQueues
    [seeds-v2]/[bluebird]/js/release/async.js:17:14


error Cannot read property 'filter' of undefined


  TypeError: Cannot read property 'filter' of undefined

  - api-runner-node.js:274 Promise.mapSeries.catch.then.results
    [seeds-v2]/[gatsby]/dist/utils/api-runner-node.js:274:42

  - util.js:16 tryCatcher
    [seeds-v2]/[bluebird]/js/release/util.js:16:23

  - promise.js:512 Promise._settlePromiseFromHandler
    [seeds-v2]/[bluebird]/js/release/promise.js:512:31

  - promise.js:569 Promise._settlePromise
    [seeds-v2]/[bluebird]/js/release/promise.js:569:18

  - promise.js:614 Promise._settlePromise0
    [seeds-v2]/[bluebird]/js/release/promise.js:614:10

  - promise.js:693 Promise._settlePromises
    [seeds-v2]/[bluebird]/js/release/promise.js:693:18

  - async.js:133 Async._drainQueue
    [seeds-v2]/[bluebird]/js/release/async.js:133:16

  - async.js:143 Async._drainQueues
    [seeds-v2]/[bluebird]/js/release/async.js:143:10

  - async.js:17 Immediate.Async.drainQueues
    [seeds-v2]/[bluebird]/js/release/async.js:17:14


error UNHANDLED REJECTION


  TypeError: Cannot read property 'filter' of undefined

  - api-runner-node.js:274 Promise.mapSeries.catch.then.results
    [seeds-v2]/[gatsby]/dist/utils/api-runner-node.js:274:42

  - util.js:16 tryCatcher
    [seeds-v2]/[bluebird]/js/release/util.js:16:23

  - promise.js:512 Promise._settlePromiseFromHandler
    [seeds-v2]/[bluebird]/js/release/promise.js:512:31

  - promise.js:569 Promise._settlePromise
    [seeds-v2]/[bluebird]/js/release/promise.js:569:18

  - promise.js:614 Promise._settlePromise0
    [seeds-v2]/[bluebird]/js/release/promise.js:614:10

  - promise.js:693 Promise._settlePromises
    [seeds-v2]/[bluebird]/js/release/promise.js:693:18

  - async.js:133 Async._drainQueue
    [seeds-v2]/[bluebird]/js/release/async.js:133:16

  - async.js:143 Async._drainQueues
    [seeds-v2]/[bluebird]/js/release/async.js:143:10

  - async.js:17 Immediate.Async.drainQueues
    [seeds-v2]/[bluebird]/js/release/async.js:17:14


error Command failed with exit code 1.

gatsby-remark-* plugin support

It'd be awesome if it could support gatsby-remark-* plugins so it instantly has image support, etc. Not 100% sure if possible so if not, reimplement a similar API.

All exports as GraphQL

It'd be great to have exports queryable in GraphQL. There are some limitations on what types of values we can push into GraphQL and how we can follow them along in the JavaScript AST.

I think the goal should should be having all named exports with primitive types as fields on the Mdx node.

Write your MDX post.

export const seo = {
  description: "my description",
  keywords: ["hello", "world"]
}
export const author = "Avi"

export const computed = 1 + 2 // I don't get pushed into graphQL

Markdown here

Then query it out.

query MdxQuery {
  allMdx {
    edges {
      node {
        exports {
           author
           seo {
              description
           }
        }
      }
    }
  }
}

There should be a "special" case for frontmatter, where it gets merged with the classic frontmatter. This would let users set frontmatter in the two ways outlined in #6.

mdx-decks integration

I just found one nice project https://github.com/jxnblk/mdx-deck which render mdx file as presentations.

to work with gatsby-mdx, I have to use two webpack loaders together, mdx-deck loader to load slides, gatsby-mdx loader to load page that import and render slides...

Just asking if it is possible to make this process easier and integrate it in here ? and they are using the same webpack loader extension .mdx, is there a better way to prevent conflicts ?

decks needs a default value

I forgot to add a default value for options.decks and you'll see an error that looks like:

  TypeError: Cannot read property 'map' of undefined

Until next release you can add an empty array to decks to bypass the error

{
  resolve: "gatsby-mdx",
  options: {
    decks: []
  }
}

Frontmatter as PageContext

What do you think of adding the frontmatter automatically as pageContext? That way you could use those values in the GraphQL queries or just render them out in the Layout.

In pages/index.mdx

---
title: "My post title"
---

Welcome to my blog.


export default ({ pageContext, children }) => (
  <div>
    <h1>{pageContext.frontmatter.title}</h1>
    {children}
  </div>
)

Testing

We need to test this somehow, or at least snapshot. It seems that the official plugins really only do snapshotting, but we should have an example project that deploys to netlify and uses all of the relevant functionality so we can check PRs and such.

Native Pages Functionality

Desired Behavior

A user enables gatsby-mdx in their gatsby-config.js. They can then use .mdx files in src/pages/* immediately to create new pages on their site.

// gatsby-config.js
module.exports = {
  siteMetadata: {
    title: `my great site`
  },
  plugins: [
    `gatsby-plugin-emotion`,
    `gatsby-plugin-react-helmet`,
    { resolve: require.resolve(`gatsby-mdx`), options: {} },
  ]
};
import Box from 'superbox/emotion';
import { graphql } from 'gatsby';

export default ({ children, ...props }) => <Box>{children}</Box>

export const pageQuery = graphql`
  allAuthors { edges { node { name } } }
`

# Title

some content

MDXRenderer needs to be an MDX context consumer

Describe the bug
The new GraphQL query capabilities in #55 seem to isolate React from its context. This means that we don't have access to the context when rendering an MDXTag and we need to make MDXRenderer a MDX context consumer.

To Reproduce
Steps to reproduce the behavior:

  1. Use an MDXprovider with a components prop higher in the React tree
  2. render something using MDXRenderer from gatsby-mdx
  3. See no components used

Expected behavior

MDXRenderer should allow sub-components to access the React context.

Additional context

Temporary workaround && POC:

const Renderer = withMDXComponents(
  ({ __mdxScope, codeBody, components }) => (
      <MDXRenderer components={components} scope={__mdxScope}>
        {codeBody}
      </MDXRenderer>
    )
);

Better errors for generated wrapper issues

Is your feature request related to a problem? Please describe.

When a generated wrapper has an error, the error points to the generated wrapper rather than the user's wrapper. This makes it super weird when debugging a pageQuery that got hoisted into the wrapper.

GraphQL Error Unknown field `markdownRemark` on type `Query`

  file: /Users/chris/github/christopherbiscardi/gatsby-starter-blog-mdx/.cache/gatsby-mdx/mdx-wrappers-dir/948d44de256b74ce08daa27cfc231ecc--scope-hash-3010b3badc54a9dfa4a4c80e419a41b2.js

   1 |
   2 |   query BlogPostBySlug($slug: String!) {
   3 |     site {
   4 |       siteMetadata {
   5 |         title
   6 |         author
   7 |       }
   8 |     }
>  9 |     markdownRemark(fields: { slug: { eq: $slug } }) {
     |     ^
  10 |       id
  11 |       excerpt
  12 |       html
  13 |       frontmatter {
  14 |         title
  15 |         date(formatString: "MMMM DD, YYYY")
  16 |       }
  17 |     }
  18 |   }
  19 |

Describe the solution you'd like
We need to put some debug information into the generated wrapper to point someone to the user's page component if there's an error.

Describe alternatives you've considered
Is there a way to do this automatically?

options.defaultLayout not used?

I'm working on a design system documentation site and am trying to use gatsby-mdx and options.defaultLayout to use the same layout file across all .mdx pages in my project. However, the default layout doesn't appear to be rendering.

Here are the steps I took and a repo that reproduces the issue.

  • Create a new gatsby v2 site: npx -p gatsby-cli gatsby new site https://github.com/gatsbyjs/gatsby-starter-default\#v2
  • Install gatsby-mdx from the newly created gatsby site directory: yarn add gatsby-mdx @mdx-js/mdx @mdx-js/tag
  • Add the gatsby-mdx plugin to the gatsby config:
module.exports = {
  plugins: [
    {
      resolve: 'gatsby-mdx',
      options: {
        defaultLayout: require.resolve('./src/components/layout.js'),
      },
    },
  ],
}
  • Replace src/pages/index.js with src/pages/index.mdx and add any MDX content
  • Run yarn develop to run the gatsby dev server

Expected: Visiting http://localhost:8000 wraps the src/pages/index.mdx content in options.defaultLayout (src/components/layout.js)
Actual: Visiting http://localhost:8000 results in the MDX content rendered without any wrapping element

Is my simplified pseudocode understanding of defaultLayout correct?

function gatsbyMdxPlugin(source, options) {
  let code = mdx(source)
  if (options.defaultLayout) {
    let Layout = require(options.defaultLayout)
    render(<Layout>{code}</Layout>)
  } else {
    render(code)
  }
}

how to access html output?

I'm attempting to switch my gatsby site from remark over to gatsby-mdx. I'm calling createPage() in my gatsby-node file. With remark I would access the parsed markdown via the html property. What is the equivalent method via gatsby-mdx?

// gatsby-node.js
createPage({
    path: node.fields.slug,
    component: path.resolve(`./src/templates/blog-post.js`),
    context: { absPath: node.absolutePath, slug: node.fields.slug },
})
// blog-post.js
// here's what I was doing with remark

export default ({ data }) => {
  const post = data.markdownRemark
  return <div dangerouslySetInnerHTML={{ __html: post.html }} />
}

GraphQL Support

Desired Functionality

A user should be able to query MDX components in any directory that's sourced by gatsby-source-filesystem plugin.

{
  allMdx {
    edges {
      node {
        frontmatter {
          title
        }
      }
    }
  }
}

Documentation

We should start to improve the gatsby-mdx documentation. We have a gatsby-mdx.netlify.com – the docs should live there.

Content

Some initial thoughts on topics we should cover.

  • Getting Started
    • Installing and Configuring MDX
    • Importing and using an MDX component
    • Creating an MDX page
  • Creating MDX pages from GraphQL
    • Sourcing MDX from the filesystem
    • Sourcing MDX from remote sources
    • Creating MDX pages from GraphQL
  • Using a Design System
  • Contributing
    • Local setup
    • Where MDX lives in the Gatsby Lifecycle
    • Extending MDX

Website

We should look at using rebass, which is what the MDX website uses.

Maybe we can through some Gatsby purple into it 😉

Starter

We should have a Gatsby MDX starter ready to go with MDX pages created from GraphQL queries.

Unable to set wrapper component

Describe the bug
I think it should be possible to set the wrapper component by specifying a wrapper component in <MDXProvider />.

I tried this in x0, and it worked, but it does not seem to work with gatsby-mdx.

To Reproduce
Specify a wrapper in <MDXProvider />. The output is always wrapped in a <div />, regardless of the component specified.

<MDXProvider
  components={{
    wrapper: 'article'
  }}
>
  {children}
</MDXProvider>

Expected behavior
The output should be wrapped in an <article />.


Sorry, I did have a look into the code, but couldn't figure this out. Thanks for any help 😊.

Layout props

Currently, the MDX loader only passes the components prop to the layout component. This is pretty limiting.

There is currently a PR open to fix this (#189). If there are any major delays around it, we should look at working around this with a HoC or render prop component that catches the page props and uses a React Context to hand it down to the layout component.

race condition?

Frequently I'll save a markdown file, Gatsby will pick up the changes and trigger HMR, then the browser throws this error:

image

To get rid of it I have to restart Gatsby, and change the markdown file so it doesn't cache, and the error often goes away. But then it happens again sometimes.

It sounds like a race condition in the GraphQL to me, but I'm not sure what could be causing it.

My markdown file query looks like this:

export const query = graphql`
  query($slug: String!) {
    mdx(fields: { slug: { eq: $slug } }) {
      frontmatter {
        title
      }
    }
  }
`

and my Theme looks like this:

export default props => {
  const post = props.data.mdx.frontmatter

  return (
    <MDXProvider
      components={{
        pre: Code,
      }}
    >
      <Layout post={post}>
        <div className="post">
          <h1>{post.title}</h1>
          {props.children}
        </div>
      </Layout>
    </MDXProvider>
  )
}

Any ideas what could make props.data.mdx null sometimes?

Split mdx-deck support out into separate package

Is your feature request related to a problem? Please describe.
npm installing gatsby-mdx warns about missing a peer dependency of mdx-deck.

Describe the solution you'd like
Blog projects won't need mdx-deck. Adding it to your package.json adds 30+ seconds to your npm install (it downloads Chromium).

Describe alternatives you've considered
gatsby-mdx could make the code that uses mdx-deck conditional upon that package being available.

componentWithMDXScope fails if there is no scope

Describe the bug
componentWithMDXScope fails with an error if there isn't anything imported into an MDX file.

To Reproduce
Use componentWithMDXScope to create a page with a queried scope, but don't import anything into the MDX file.

You should see an error like this:

TypeError: Cannot read property 'map' of null

  - component-with-mdx-scope.js:29 componentWithMD    XScope
    [v6]/[gatsby-mdx]/component-with-mdx-scope.js:    29:41

importMDX Helper

Proposal

Right now there are 3 clear ways to use MDX.

  1. Import the component directly (The "natural" way)
  2. Add in an MDX file in the pages/ directory
  3. Query the MDX files via GraphQL and use the createPage action to create the pages

We could add a 4th way – an importMDX helper that would let people get MDX components from GraphQL queries in their page components.

import React from 'react'
import { graphql } from 'gatsby'
import { importMDX } from 'gatsby-mdx'

const MyPage = ({ data: { mdx: { component } } }) => {
  const MyMarkdown = importMDX(component)

  return (
    <div>
      <MyMarkdown />
    </div>
  )
}

export default MyPage


export const pageQuery = graphql`
  query MyPageQuery {
    mdx {
      component
    }
  }
`

Thoughts on adding in a importMDX helper for loading MDX components from GraphQL queries?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.