diff --git a/e2e-tests/mdx-less-babel/.gitignore b/e2e-tests/mdx-less-babel/.gitignore
index 615f726febf63..a6c24c20b52b1 100644
--- a/e2e-tests/mdx-less-babel/.gitignore
+++ b/e2e-tests/mdx-less-babel/.gitignore
@@ -9,3 +9,4 @@ yarn-error.log
# Cypress output
cypress/videos/
+cypress/screenshots/
diff --git a/e2e-tests/mdx-less-babel/cypress/fixtures/file-to-attempt-rce-on.txt b/e2e-tests/mdx-less-babel/cypress/fixtures/file-to-attempt-rce-on.txt
new file mode 100644
index 0000000000000..036fdbe69718b
--- /dev/null
+++ b/e2e-tests/mdx-less-babel/cypress/fixtures/file-to-attempt-rce-on.txt
@@ -0,0 +1 @@
+Nothing here, do not remove
\ No newline at end of file
diff --git a/e2e-tests/mdx-less-babel/cypress/integration/js-frontmatter.js b/e2e-tests/mdx-less-babel/cypress/integration/js-frontmatter.js
new file mode 100644
index 0000000000000..ac26fcb0aba45
--- /dev/null
+++ b/e2e-tests/mdx-less-babel/cypress/integration/js-frontmatter.js
@@ -0,0 +1,29 @@
+describe(`webpack loader`, () => {
+ it(`---js frontmatter should not parse by default`, () => {
+ cy.visit(`/js-frontmatter`).waitForRouteChange()
+
+ // Check frontmatter not parsed in page context
+ cy.get(`[data-cy="js-frontmatter"]`).invoke(`text`).should(`eq`, `disabled`)
+ })
+
+ it(`---javascript frontmatter should not parse by default`, () => {
+ cy.visit(`/javascript-frontmatter`).waitForRouteChange()
+
+ // Check frontmatter not parsed in page context
+ cy.get(`[data-cy="js-frontmatter"]`).invoke(`text`).should(`eq`, `disabled`)
+ })
+})
+
+describe(`data layer`, () => {
+ it(`---js or ---javascript frontmatter should not parse by default`, () => {
+ cy.visit(`/mdx-query-js-frontmatter/`).waitForRouteChange()
+ cy.contains(`I should not be parsed`).should("not.exist")
+ })
+})
+
+it(`---js and ---javascript frontmatter should not allow remote code execution`, () => {
+ cy.readFile(`cypress/fixtures/file-to-attempt-rce-on.txt`).should(
+ `eq`,
+ `Nothing here, do not remove`
+ )
+})
diff --git a/e2e-tests/mdx-less-babel/gatsby-node.js b/e2e-tests/mdx-less-babel/gatsby-node.js
new file mode 100644
index 0000000000000..5e4c76ccc2535
--- /dev/null
+++ b/e2e-tests/mdx-less-babel/gatsby-node.js
@@ -0,0 +1,12 @@
+exports.createSchemaCustomization = ({ actions }) => {
+ const { createTypes } = actions
+
+ createTypes(`
+ type Mdx implements Node {
+ frontmatter: Frontmatter
+ }
+ type Frontmatter {
+ title: String
+ }
+ `)
+}
diff --git a/e2e-tests/mdx-less-babel/package.json b/e2e-tests/mdx-less-babel/package.json
index 55d44e90d8370..7b316d2bf418e 100644
--- a/e2e-tests/mdx-less-babel/package.json
+++ b/e2e-tests/mdx-less-babel/package.json
@@ -6,9 +6,9 @@
"@mdx-js/mdx": "^1.6.6",
"@mdx-js/react": "^1.6.6",
"cypress": "^3.1.0",
- "gatsby": "^2.0.118",
- "gatsby-plugin-mdx": "^1.2.19",
- "gatsby-source-filesystem": "^2.3.14",
+ "gatsby": "next",
+ "gatsby-plugin-mdx": "next",
+ "gatsby-source-filesystem": "next",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"theme-ui": "^0.3.1"
@@ -18,10 +18,11 @@
],
"license": "MIT",
"scripts": {
- "build": "gatsby build",
- "develop": "gatsby develop",
+ "clean": "gatsby clean",
+ "build": "cross-env CYPRESS_SUPPORT=y gatsby build",
+ "develop": "cross-env CYPRESS_SUPPORT=y gatsby develop",
"format": "prettier --write '**/*.js'",
- "test": "cross-env CYPRESS_SUPPORT=y npm run build && npm run start-server-and-test",
+ "test": "npm run build && npm run start-server-and-test",
"start-server-and-test": "start-server-and-test serve http://localhost:9000 cy:run",
"serve": "gatsby serve",
"cy:open": "cypress open",
@@ -34,4 +35,4 @@
"prettier": "2.0.4",
"start-server-and-test": "^1.7.1"
}
-}
\ No newline at end of file
+}
diff --git a/e2e-tests/mdx-less-babel/src/pages/javascript-frontmatter.mdx b/e2e-tests/mdx-less-babel/src/pages/javascript-frontmatter.mdx
new file mode 100644
index 0000000000000..5210c21d086d4
--- /dev/null
+++ b/e2e-tests/mdx-less-babel/src/pages/javascript-frontmatter.mdx
@@ -0,0 +1,16 @@
+---javascript
+(() => {
+require(`fs`).writeFileSync(`${process.cwd()}/cypress/fixtures/file-to-attempt-rce-on.txt`, (new Error('Helpful stack trace if this does execute. It should not execute.')).stack)
+console.trace()
+return {
+title: `I should not be parsed`
+}
+})()
+
+---
+
+
JS frontmatter engine is disabled by default
+
+
+ {props.pageContext.frontmatter?.title || `disabled`}
+
diff --git a/e2e-tests/mdx-less-babel/src/pages/js-frontmatter.mdx b/e2e-tests/mdx-less-babel/src/pages/js-frontmatter.mdx
new file mode 100644
index 0000000000000..fcb411cdccfda
--- /dev/null
+++ b/e2e-tests/mdx-less-babel/src/pages/js-frontmatter.mdx
@@ -0,0 +1,16 @@
+---js
+(() => {
+require(`fs`).writeFileSync(`${process.cwd()}/cypress/fixtures/file-to-attempt-rce-on.txt`, (new Error('Helpful stack trace if this does execute. It should not execute.')).stack)
+console.trace()
+return {
+title: `I should not be parsed`
+}
+})()
+
+---
+
+JS frontmatter engine is disabled by default
+
+
+ {props.pageContext.frontmatter?.title || `disabled`}
+
diff --git a/e2e-tests/mdx-less-babel/src/pages/mdx-query-js-frontmatter.js b/e2e-tests/mdx-less-babel/src/pages/mdx-query-js-frontmatter.js
new file mode 100644
index 0000000000000..c94d169a7699e
--- /dev/null
+++ b/e2e-tests/mdx-less-babel/src/pages/mdx-query-js-frontmatter.js
@@ -0,0 +1,30 @@
+import React from "react"
+import { graphql } from "gatsby"
+
+export default function PageRunningGraphqlResolversOnJSFrontmatterTestInputs({
+ data,
+}) {
+ return {JSON.stringify(data.allMdx.nodes, null, 2)}
+}
+
+export const query = graphql`
+ {
+ allMdx(filter: { slug: { glob: "frontmatter-engine/*" } }) {
+ nodes {
+ frontmatter {
+ title
+ }
+ body
+ excerpt
+ tableOfContents
+ timeToRead
+ wordCount {
+ paragraphs
+ sentences
+ words
+ }
+ mdxAST
+ }
+ }
+ }
+`
diff --git a/e2e-tests/mdx-less-babel/src/posts/frontmatter-engine/javascript-frontmatter.mdx b/e2e-tests/mdx-less-babel/src/posts/frontmatter-engine/javascript-frontmatter.mdx
new file mode 100644
index 0000000000000..76f5bd494d3a4
--- /dev/null
+++ b/e2e-tests/mdx-less-babel/src/posts/frontmatter-engine/javascript-frontmatter.mdx
@@ -0,0 +1,16 @@
+---javascript
+(() => {
+require(`fs`).writeFileSync(`${process.cwd()}/cypress/fixtures/file-to-attempt-rce-on.txt`, (new Error('Helpful stack trace if this does execute. It should not execute.')).stack)
+console.trace()
+return {
+title: `I should not be parsed`
+}
+})()
+
+---
+
+JS frontmatter engine is disabled by default w
+
+
+ {props.pageContext.frontmatter?.title || `disabled`}
+
diff --git a/e2e-tests/mdx-less-babel/src/posts/frontmatter-engine/js-frontmatter.mdx b/e2e-tests/mdx-less-babel/src/posts/frontmatter-engine/js-frontmatter.mdx
new file mode 100644
index 0000000000000..fcb411cdccfda
--- /dev/null
+++ b/e2e-tests/mdx-less-babel/src/posts/frontmatter-engine/js-frontmatter.mdx
@@ -0,0 +1,16 @@
+---js
+(() => {
+require(`fs`).writeFileSync(`${process.cwd()}/cypress/fixtures/file-to-attempt-rce-on.txt`, (new Error('Helpful stack trace if this does execute. It should not execute.')).stack)
+console.trace()
+return {
+title: `I should not be parsed`
+}
+})()
+
+---
+
+JS frontmatter engine is disabled by default
+
+
+ {props.pageContext.frontmatter?.title || `disabled`}
+
diff --git a/e2e-tests/mdx/.gitignore b/e2e-tests/mdx/.gitignore
index 615f726febf63..1bdfa17d9c898 100644
--- a/e2e-tests/mdx/.gitignore
+++ b/e2e-tests/mdx/.gitignore
@@ -9,3 +9,4 @@ yarn-error.log
# Cypress output
cypress/videos/
+cypress/screenshots/
\ No newline at end of file
diff --git a/e2e-tests/mdx/cypress/fixtures/file-to-attempt-rce-on.txt b/e2e-tests/mdx/cypress/fixtures/file-to-attempt-rce-on.txt
new file mode 100644
index 0000000000000..036fdbe69718b
--- /dev/null
+++ b/e2e-tests/mdx/cypress/fixtures/file-to-attempt-rce-on.txt
@@ -0,0 +1 @@
+Nothing here, do not remove
\ No newline at end of file
diff --git a/e2e-tests/mdx/cypress/integration/js-frontmatter.js b/e2e-tests/mdx/cypress/integration/js-frontmatter.js
new file mode 100644
index 0000000000000..ac26fcb0aba45
--- /dev/null
+++ b/e2e-tests/mdx/cypress/integration/js-frontmatter.js
@@ -0,0 +1,29 @@
+describe(`webpack loader`, () => {
+ it(`---js frontmatter should not parse by default`, () => {
+ cy.visit(`/js-frontmatter`).waitForRouteChange()
+
+ // Check frontmatter not parsed in page context
+ cy.get(`[data-cy="js-frontmatter"]`).invoke(`text`).should(`eq`, `disabled`)
+ })
+
+ it(`---javascript frontmatter should not parse by default`, () => {
+ cy.visit(`/javascript-frontmatter`).waitForRouteChange()
+
+ // Check frontmatter not parsed in page context
+ cy.get(`[data-cy="js-frontmatter"]`).invoke(`text`).should(`eq`, `disabled`)
+ })
+})
+
+describe(`data layer`, () => {
+ it(`---js or ---javascript frontmatter should not parse by default`, () => {
+ cy.visit(`/mdx-query-js-frontmatter/`).waitForRouteChange()
+ cy.contains(`I should not be parsed`).should("not.exist")
+ })
+})
+
+it(`---js and ---javascript frontmatter should not allow remote code execution`, () => {
+ cy.readFile(`cypress/fixtures/file-to-attempt-rce-on.txt`).should(
+ `eq`,
+ `Nothing here, do not remove`
+ )
+})
diff --git a/e2e-tests/mdx/gatsby-config.js b/e2e-tests/mdx/gatsby-config.js
index e63a750799933..f072f361ea177 100644
--- a/e2e-tests/mdx/gatsby-config.js
+++ b/e2e-tests/mdx/gatsby-config.js
@@ -37,7 +37,7 @@ module.exports = {
* See #26914 for more info.
*/
function remarkRequireFilePathPlugin() {
- return function transformer(tree, file) {
+ return function transformer(_, file) {
if (!file.dirname) {
throw new Error("No directory name for this markdown file!")
}
diff --git a/e2e-tests/mdx/gatsby-node.js b/e2e-tests/mdx/gatsby-node.js
index eceaaff1a0d20..3c94f90b31a46 100644
--- a/e2e-tests/mdx/gatsby-node.js
+++ b/e2e-tests/mdx/gatsby-node.js
@@ -16,3 +16,16 @@ exports.onPostBuild = async ({ graphql }) => {
{ spaces: 2 }
)
}
+
+exports.createSchemaCustomization = ({ actions }) => {
+ const { createTypes } = actions
+
+ createTypes(`
+ type Mdx implements Node {
+ frontmatter: Frontmatter
+ }
+ type Frontmatter {
+ title: String
+ }
+ `)
+}
diff --git a/e2e-tests/mdx/package.json b/e2e-tests/mdx/package.json
index 81a61217824c1..ee7ec1b8407c3 100644
--- a/e2e-tests/mdx/package.json
+++ b/e2e-tests/mdx/package.json
@@ -7,9 +7,9 @@
"@mdx-js/react": "^1.6.6",
"cypress": "^7.2.0",
"fs-extra": "^8.1.0",
- "gatsby": "^3.0.0",
- "gatsby-plugin-mdx": "^2.0.0",
- "gatsby-source-filesystem": "^3.0.0",
+ "gatsby": "next",
+ "gatsby-plugin-mdx": "next",
+ "gatsby-source-filesystem": "next",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"theme-ui": "^0.3.1"
@@ -19,6 +19,7 @@
],
"license": "MIT",
"scripts": {
+ "clean": "gatsby clean",
"build": "cross-env CYPRESS_SUPPORT=y gatsby build",
"develop": "cross-env CYPRESS_SUPPORT=y gatsby develop",
"format": "prettier --write '**/*.js'",
diff --git a/e2e-tests/mdx/src/pages/javascript-frontmatter.mdx b/e2e-tests/mdx/src/pages/javascript-frontmatter.mdx
new file mode 100644
index 0000000000000..5210c21d086d4
--- /dev/null
+++ b/e2e-tests/mdx/src/pages/javascript-frontmatter.mdx
@@ -0,0 +1,16 @@
+---javascript
+(() => {
+require(`fs`).writeFileSync(`${process.cwd()}/cypress/fixtures/file-to-attempt-rce-on.txt`, (new Error('Helpful stack trace if this does execute. It should not execute.')).stack)
+console.trace()
+return {
+title: `I should not be parsed`
+}
+})()
+
+---
+
+JS frontmatter engine is disabled by default
+
+
+ {props.pageContext.frontmatter?.title || `disabled`}
+
diff --git a/e2e-tests/mdx/src/pages/js-frontmatter.mdx b/e2e-tests/mdx/src/pages/js-frontmatter.mdx
new file mode 100644
index 0000000000000..fcb411cdccfda
--- /dev/null
+++ b/e2e-tests/mdx/src/pages/js-frontmatter.mdx
@@ -0,0 +1,16 @@
+---js
+(() => {
+require(`fs`).writeFileSync(`${process.cwd()}/cypress/fixtures/file-to-attempt-rce-on.txt`, (new Error('Helpful stack trace if this does execute. It should not execute.')).stack)
+console.trace()
+return {
+title: `I should not be parsed`
+}
+})()
+
+---
+
+JS frontmatter engine is disabled by default
+
+
+ {props.pageContext.frontmatter?.title || `disabled`}
+
diff --git a/e2e-tests/mdx/src/pages/mdx-query-js-frontmatter.js b/e2e-tests/mdx/src/pages/mdx-query-js-frontmatter.js
new file mode 100644
index 0000000000000..c94d169a7699e
--- /dev/null
+++ b/e2e-tests/mdx/src/pages/mdx-query-js-frontmatter.js
@@ -0,0 +1,30 @@
+import React from "react"
+import { graphql } from "gatsby"
+
+export default function PageRunningGraphqlResolversOnJSFrontmatterTestInputs({
+ data,
+}) {
+ return {JSON.stringify(data.allMdx.nodes, null, 2)}
+}
+
+export const query = graphql`
+ {
+ allMdx(filter: { slug: { glob: "frontmatter-engine/*" } }) {
+ nodes {
+ frontmatter {
+ title
+ }
+ body
+ excerpt
+ tableOfContents
+ timeToRead
+ wordCount {
+ paragraphs
+ sentences
+ words
+ }
+ mdxAST
+ }
+ }
+ }
+`
diff --git a/e2e-tests/mdx/src/posts/frontmatter-engine/javascript-frontmatter.mdx b/e2e-tests/mdx/src/posts/frontmatter-engine/javascript-frontmatter.mdx
new file mode 100644
index 0000000000000..76f5bd494d3a4
--- /dev/null
+++ b/e2e-tests/mdx/src/posts/frontmatter-engine/javascript-frontmatter.mdx
@@ -0,0 +1,16 @@
+---javascript
+(() => {
+require(`fs`).writeFileSync(`${process.cwd()}/cypress/fixtures/file-to-attempt-rce-on.txt`, (new Error('Helpful stack trace if this does execute. It should not execute.')).stack)
+console.trace()
+return {
+title: `I should not be parsed`
+}
+})()
+
+---
+
+JS frontmatter engine is disabled by default w
+
+
+ {props.pageContext.frontmatter?.title || `disabled`}
+
diff --git a/e2e-tests/mdx/src/posts/frontmatter-engine/js-frontmatter.mdx b/e2e-tests/mdx/src/posts/frontmatter-engine/js-frontmatter.mdx
new file mode 100644
index 0000000000000..fcb411cdccfda
--- /dev/null
+++ b/e2e-tests/mdx/src/posts/frontmatter-engine/js-frontmatter.mdx
@@ -0,0 +1,16 @@
+---js
+(() => {
+require(`fs`).writeFileSync(`${process.cwd()}/cypress/fixtures/file-to-attempt-rce-on.txt`, (new Error('Helpful stack trace if this does execute. It should not execute.')).stack)
+console.trace()
+return {
+title: `I should not be parsed`
+}
+})()
+
+---
+
+JS frontmatter engine is disabled by default
+
+
+ {props.pageContext.frontmatter?.title || `disabled`}
+
diff --git a/packages/gatsby-plugin-mdx/README.md b/packages/gatsby-plugin-mdx/README.md
index 62388d19c9b4b..cea7810f1293f 100644
--- a/packages/gatsby-plugin-mdx/README.md
+++ b/packages/gatsby-plugin-mdx/README.md
@@ -123,6 +123,7 @@ scope, and more.
| [`mediaTypes`](#media-types) | `["text/markdown", "text/x-markdown"]` | Determine which media types are processed by MDX |
| [`shouldBlockNodeFromTransformation`](#shouldblocknodefromtransformation) | `(node) => false` | Disable MDX transformation for nodes where this function returns true |
| [`commonmark`](#commonmark) | `false` | Use CommonMark |
+| [`JSFrontmatterEngine`](#jsfrontmatterengine) | `false` | Add support for JavaScript frontmatter engine |
#### Extensions
@@ -466,6 +467,10 @@ module.exports = {
MDX will be parsed using CommonMark.
+#### JSFrontmatterEngine
+
+Adds support for JavaScript frontmatter engine. Use with caution - see https://github.com/gatsbyjs/gatsby/security/advisories/GHSA-mj46-r4gr-5x83
+
### Components
MDX and `gatsby-plugin-mdx` use components for different things like rendering
diff --git a/packages/gatsby-plugin-mdx/__tests__/gatsby-node.js b/packages/gatsby-plugin-mdx/__tests__/gatsby-node.js
index f24ba7528839f..76ad0f45f228b 100644
--- a/packages/gatsby-plugin-mdx/__tests__/gatsby-node.js
+++ b/packages/gatsby-plugin-mdx/__tests__/gatsby-node.js
@@ -17,6 +17,7 @@ describe(`pluginOptionsSchema`, () => {
`"mediaTypes[1]" must be a string`,
`"shouldBlockNodeFromTransformation" must have an arity lesser or equal to 1`,
`"root" must be a string`,
+ `"JSFrontmatterEngine" must be a boolean`,
]
const { errors } = await testPluginOptionsSchema(pluginOptionsSchema, {
@@ -29,6 +30,7 @@ describe(`pluginOptionsSchema`, () => {
mediaTypes: [1, 2],
shouldBlockNodeFromTransformation: (wrong, number) => null,
root: 1,
+ JSFrontmatterEngine: `this should be a boolean`,
})
expect(errors).toEqual(expectedErrors)
@@ -64,6 +66,7 @@ describe(`pluginOptionsSchema`, () => {
shouldBlockNodeFromTransformation: node => Boolean(node),
root: `james-holden`,
commonmark: true,
+ JSFrontmatterEngine: true,
})
expect(isValid).toBe(true)
diff --git a/packages/gatsby-plugin-mdx/gatsby-node.js b/packages/gatsby-plugin-mdx/gatsby-node.js
index 7416b73967f41..75b7c042a6d28 100644
--- a/packages/gatsby-plugin-mdx/gatsby-node.js
+++ b/packages/gatsby-plugin-mdx/gatsby-node.js
@@ -68,6 +68,9 @@ exports.onPostBootstrap = ({ cache }, pluginOptions) => {
}
}
+// Dedupe warning
+let warnedAboutJSFrontmatterEngine = false
+
exports.pluginOptionsSchema = function ({ Joi }) {
return Joi.object({
extensions: Joi.array()
@@ -123,5 +126,40 @@ exports.pluginOptionsSchema = function ({ Joi }) {
commonmark: Joi.boolean()
.default(false)
.description("MDX will be parsed using CommonMark."),
+ JSFrontmatterEngine: Joi.boolean()
+ .default(false)
+ .description(`Enable JavaScript frontmatter parsing`),
+ }).custom(value => {
+ const { JSFrontmatterEngine, engines = {} } = value || {}
+
+ if (JSFrontmatterEngine) {
+ // show this warning only once in main process
+ if (!process.env.GATSBY_WORKER_ID) {
+ console.warn(
+ `JS frontmatter engine is enabled in gatsby-plugin-mdx (via JSFrontmatterEngine: true in plugin options). This can cause a security risk, see https://github.com/gatsbyjs/gatsby/security/advisories/GHSA-mj46-r4gr-5x83. If you are not relying on this feature we strongly suggest disabling it via the "JSFrontmatterEngine: false" plugin option. If you rely on this feature make sure to properly secure or sanitize your content source.`
+ )
+ }
+ return value
+ }
+
+ const js = () => {
+ if (!warnedAboutJSFrontmatterEngine) {
+ console.warn(
+ `You have frontmatter declared with "---js" or "---javascript" that is not parsed by default to mitigate a security risk (see https://github.com/gatsbyjs/gatsby/security/advisories/GHSA-mj46-r4gr-5x83). If you require this feature it can be enabled by setting "JSFrontmatterEngine: true" in the plugin options of gatsby-plugin-mdx.`
+ )
+ warnedAboutJSFrontmatterEngine = true
+ }
+ // we still have to return a frontmatter, se we just stub it with empty object
+ return {}
+ }
+
+ return {
+ ...value,
+ engines: {
+ ...engines,
+ js,
+ javascript: js,
+ },
+ }
})
}
diff --git a/packages/gatsby-plugin-mdx/gatsby/on-create-node.js b/packages/gatsby-plugin-mdx/gatsby/on-create-node.js
index 1768c91ddb6af..0f7488e8c5686 100644
--- a/packages/gatsby-plugin-mdx/gatsby/on-create-node.js
+++ b/packages/gatsby-plugin-mdx/gatsby/on-create-node.js
@@ -74,6 +74,7 @@ async function onCreateNodeExtraBabel(
id: createNodeId(`${node.id} >>> Mdx`),
node,
content,
+ options,
})
createNode(mdxNode)
diff --git a/packages/gatsby-plugin-mdx/loaders/mdx-loader.js b/packages/gatsby-plugin-mdx/loaders/mdx-loader.js
index 1a79e267efee2..5309e93009f65 100644
--- a/packages/gatsby-plugin-mdx/loaders/mdx-loader.js
+++ b/packages/gatsby-plugin-mdx/loaders/mdx-loader.js
@@ -82,7 +82,7 @@ const hasDefaultExport = (str, options) => {
methods.splice(methods.indexOf(`paragraph`), 0, `esSyntax`)
}
- const { content } = grayMatter(str)
+ const { content } = grayMatter(str, options)
unified()
.use(toMDAST, options)
.use(esSyntax)
@@ -110,7 +110,7 @@ module.exports = async function mdxLoader(content) {
const resourceQuery = this.resourceQuery || ``
if (isolateMDXComponent && !resourceQuery.includes(`type=component`)) {
- const { data } = grayMatter(content)
+ const { data } = grayMatter(content, pluginOptions)
const requestPath = slash(
`/${path.relative(this.rootContext, this.resourcePath)}?type=component`
@@ -162,6 +162,7 @@ export const _frontmatter = ${JSON.stringify(data)};`
id: `fakeNodeIdMDXFileABugIfYouSeeThis`,
node: fileNode,
content,
+ options,
})
}
} catch (e) {
@@ -179,9 +180,12 @@ export const _frontmatter = ${JSON.stringify(data)};`
let code = content
// after running mdx, the code *always* has a default export, so this
// check needs to happen first.
- if (!hasDefaultExport(content, DEFAULT_OPTIONS) && !!defaultLayout) {
+ if (!hasDefaultExport(content, options) && !!defaultLayout) {
debug(`inserting default layout`, defaultLayout)
- const { content: contentWithoutFrontmatter, matter } = grayMatter(content)
+ const { content: contentWithoutFrontmatter, matter } = grayMatter(
+ content,
+ options
+ )
code = `${matter ? matter : ``}
diff --git a/packages/gatsby-plugin-mdx/utils/create-mdx-node.js b/packages/gatsby-plugin-mdx/utils/create-mdx-node.js
index e7cf7d7fa4eb9..f848b0b8d424e 100644
--- a/packages/gatsby-plugin-mdx/utils/create-mdx-node.js
+++ b/packages/gatsby-plugin-mdx/utils/create-mdx-node.js
@@ -5,10 +5,10 @@ const extractExports = require(`../utils/extract-exports`)
const { findImportsExports } = require(`../utils/gen-mdx`)
-async function createMdxNodeExtraBabel({ id, node, content }) {
+async function createMdxNodeExtraBabel({ id, node, content, options }) {
let code
try {
- code = await mdx(content)
+ code = await mdx(content, { filepath: node.absolutePath, ...options })
} catch (e) {
// add the path of the file to simplify debugging error messages
e.message += `${node.absolutePath}: ${e.message}`
diff --git a/packages/gatsby-plugin-mdx/utils/gen-mdx.js b/packages/gatsby-plugin-mdx/utils/gen-mdx.js
index 97a115fdca4bf..e558745979b6e 100644
--- a/packages/gatsby-plugin-mdx/utils/gen-mdx.js
+++ b/packages/gatsby-plugin-mdx/utils/gen-mdx.js
@@ -89,7 +89,10 @@ async function genMDX(
// pull classic style frontmatter off the raw MDX body
debug(`processing classic frontmatter`)
- const { data, content: frontMatterCodeResult } = grayMatter(node.rawBody)
+ const { data, content: frontMatterCodeResult } = grayMatter(
+ node.rawBody,
+ options
+ )
const content = isolateMDXComponent
? frontMatterCodeResult
@@ -210,7 +213,7 @@ async function findImports({
pathPrefix,
...helpers
}) {
- const { content } = grayMatter(node.rawBody)
+ const { content } = grayMatter(node.rawBody, options)
const gatsbyRemarkPluginsAsremarkPlugins =
await getSourcePluginsAsRemarkPlugins({
@@ -289,7 +292,7 @@ async function findImportsExports({
pathPrefix,
...helpers
}) {
- const { data: frontmatter, content } = grayMatter(rawInput)
+ const { data: frontmatter, content } = grayMatter(rawInput, options)
const gatsbyRemarkPluginsAsRemarkPlugins =
await getSourcePluginsAsRemarkPlugins({
diff --git a/packages/gatsby-plugin-mdx/utils/mdx.js b/packages/gatsby-plugin-mdx/utils/mdx.js
index 624861d05aef6..21fe4d93c0984 100644
--- a/packages/gatsby-plugin-mdx/utils/mdx.js
+++ b/packages/gatsby-plugin-mdx/utils/mdx.js
@@ -8,10 +8,9 @@ const grayMatter = require(`gray-matter`)
* @param {Object} options options for mdx library
* @return {String} JSX source
*/
-module.exports = async function mdxToJsx(source, options) {
- const { data, content } = grayMatter(source)
-
- const code = await mdx(content, options || {})
+module.exports = async function mdxToJsx(source, options = {}) {
+ const { data, content } = grayMatter(source, options)
+ const code = await mdx(content, options)
return `${code}