GraphQL queries inside MDX files
When you want to query data with GraphQL inside your MDX pages, you have the following options:
Default MDX config
If you are using the default configuration of gatsby-plugin-mdx
, just export a GraphQL query as you would do in a regular Gatsby page. By default configuration, I mean that you installed gatsby-plugin-mdx
, @mdx-js/mdx
, and @mdx-js/react
, and finally, you added gatsby-plugin-mdx
as a plugin in gatsby-config.js
. Then, you can access the query data from props.data.yourdata
.
In the following example, I render the astronaut image from the default Gatsby starter, and I display the props:
# Example
Example MDX page. Here's the image of an astronaut:
import { graphql } from "gatsby";
import Image from "gatsby-image";
export const query = graphql`
query {
astronaut: file(relativePath: { regex: "/gatsby-astronaut/i" }) {
childImageSharp {
fluid(maxWidth: 600) {
...GatsbyImageSharpFluid_tracedSVG
}
}
}
}
`;
<Image
title="astronaut"
fluid={props.data.astronaut.childImageSharp.fluid}
/>
Log the `props.data`:
<pre>{JSON.stringify(props, null, 2)}</pre>
Custom templates
If you create the MDX pages programmatically, and you render them with a custom template, create a new component that uses a StaticQuery
, then import that component in your MDX page and render it.
If you try to create a page query inside the MDX file or try to render a StaticQuery
, you ’ll get the following error:
Error: It appears like Gatsby is misconfigured. Gatsby related GraphQL calls are supposed to only be evaluated at compile time, and then compiled away…
Recommended folder structure:
__ src
____ components
______ AstronautImage.jsx
____ pages
______ index.js
______ example.mdx
The MDX file:
# Example
Here's the image of an astronaut:
import AstronautImage from "../components/AstronautImage";
<AstronautImage />
And finally, the custom component that uses the StaticQuery:
import React from "react";
import { graphql, StaticQuery } from "gatsby";
import Image from "gatsby-image";
export default () => (
<StaticQuery
query={graphql`
query {
astronaut: file(relativePath: { regex: "/gatsby-astronaut/i" }) {
childImageSharp {
fluid(maxWidth: 600) {
...GatsbyImageSharpFluid_tracedSVG
}
}
}
}
`}
render={(data) => (
<Image
title="astronaut"
fluid={data.astronaut.childImageSharp.fluid}
/>
)}
/>
);
Extra
In this section you can find an MDX template, a gatsby-node.js
file that creates programmatically MDX pages, and some links.
Custom template file
import React from "react";
import { graphql } from "gatsby";
import { MDXRenderer } from "gatsby-plugin-mdx";
import Layout from "../components/layout";
export default ({
data: {
mdx: { body },
},
}) => {
return (
<Layout>
<h1>Hello from the template</h1>
<MDXRenderer>{body}</MDXRenderer>
</Layout>
);
};
// Notice the slug field in the MDX type you created
// in onCreateNode.
// The $slug variable comes from the page context
// you passed while creating the page.
export const query = graphql`
query MDXBySlug($slug: String!) {
mdx(fields: { slug: { eq: $slug } }) {
body
}
}
`;
gatsby-node.js
const { createFilePath } = require("gatsby-source-filesystem");
const mdxTemplate = require.resolve("./src/templates/MDXTemplate.jsx");
exports.onCreatePage = ({
page,
actions: { createPage, deletePage },
}) => {
const { frontmatter } = page.context;
// Assuming only MDX pages have a frontmatter field...
if (frontmatter) {
deletePage(page);
createPage({
...page,
component: mdxTemplate,
context: {
...page.context,
slug: page.path,
},
});
}
};
exports.onCreateNode = ({ node, actions, getNode }) => {
const { createNodeField } = actions;
if (node.internal.type === "Mdx") {
const value = createFilePath({ node, getNode });
createNodeField({
name: "slug",
node,
value,
});
}
};
Links
Other things to read
Popular
- Reveal animations on scroll with react-spring
- Gatsby background image example
- Extremely fast loading with Gatsby and self-hosted fonts