MDX and gatsby-plugin-sharp Graphql schema basics

July 19, 2020

I’ve had a lot of trouble understanding how featuredImage in the frontmatter of an MDX/MD post gets picked up by graphql.

Where does MDX get its schema from?

Anything you put inside the two lines with --- (called frontmatter) gets picked up as name: value pairs and gets populated in graphql as the schema for MDX/MD posts. Be sure to have a space after the ":".

Originally this was the frontmatter for this blog post:

---
title: 'MDX and gatsby-plugin-sharp schema basics'
date: '2020-07-19T05:11:00.000Z'
---

I changed it to the following:

---
title: 'MDX and gatsby-plugin-sharp schema basics'
date: '2020-07-19T05:11:00.000Z'
featuredImage: ../../assets/gatsby-icon.png
keywords: [featuredImage, graphql, gatsby, MDX, schema, fundamentals]
---

Run gatsby clean and gatsby develop and now in graphql you can run the following queries:

query MyQuery {
allMdx {
edges {
node {
frontmatter {
title
keywords
}
}
}
}
}

gives me the result:

{
"data": {
"allMdx": {
"edges": [
{
"node": {
"frontmatter": {
"title": "Adding a custom favicon to your Gatsy site",
"keywords": null <--- I DIDN'T SUPPLY KEYWORDS FOR THIS POST
}
}
},
...
{
"node": {
"frontmatter": {
"title": "MDX and gatsby-plugin-sharp schema basics",
"keywords": [
"featuredImage",
"graphql",
"gatsby",
"MDX",
"schema",
"fundamentals"
]
}
}
},
]
}
}
}

Now I can query for keywords and use it to plug into SEO for this blog post.

Adding featuredImage: ../../assets/gatsby-icon.png to the frontmatter allows me to run the following query:

query MyQuery {
allMdx { <---NOTE THIS
edges {
node {
frontmatter {
title
keywords
featuredImage {
childImageSharp {
fluid {
originalName
}
}
}
}
}
}
}
}

giving me the result:

{
"data": {
"allMdx": { <--- NOTE THIS
"edges": [
{
"node": {
"frontmatter": {
"title": "Adding a custom favicon to your Gatsy site",
"keywords": null, <---NOTE THAT THIS IS NULL
"featuredImage": null <---NOTE THAT THIS IS NULL
}
}
},
...
{
"node": {
"frontmatter": {
"title": "MDX and gatsby-plugin-sharp schema basics",
"keywords": [ <---NOTE THIS
"featuredImage",
"graphql",
"gatsby",
"MDX",
"schema",
"fundamentals"
],
"featuredImage": {
"childImageSharp": { <---THIS WAS CREATED BY
gatsby-plugin-sharp(?)
"fluid": {
"originalName": "gatsby-icon.png"<---THIS GOT PICKED UP
BY GRAPHQL
}
}
}
}
}
}
]
}
}
}

I can now use allMdx->…->featuredImage-> childImageSharp->fluid in my graphql queries.

Note that the key featuredImage can be named anything you want, it still gets a childImageSharp child as the value points to an image. keywords was something I made up.

Important: Sometimes you may get an error message in your gatsby code unable to access featuredImage. This is because featuredImage gets populated as a String instead of a structure. Here’s the error message from graphql: "message": "Field \"featuredImage\" must not have a selection since type \"String\" has no subfields.",

This happens when the file that featuredImage is pointing to doesn’t exist, typically because you have a typo in the file name, its extension or in the relative path.

One of the plugins, probably gatsby-plugin-sharp, populates allImageSharp in graphql, and can provide images in various sizes and puts them in the /static folder at the root of your project.

query MyQuery {
allImageSharp { <---NOTE THIS
edges {
node {
fluid {
originalName
src
srcSet
}
}
}
}
}```
giving me:
```jsx
{
"data": {
"allImageSharp": { <---NOTE THIS
"edges": [
{
"node": {
"fluid": {
"originalName": "gatsby-icon.png",
"src": "/static/4a9773549091c227cd2eb82ccd9c5e3a/bc59e/
gatsby-icon.png", <---NOTE src image in static folder
"srcSet": "/static/4a9773549091c227cd2eb82ccd9c5e3a/69585/
gatsby-icon.png 200w,\n/static/
4a9773549091c227cd2eb82ccd9c5e3a/497c6/gatsby-icon.png 400w,\n/
static/4a9773549091c227cd2eb82ccd9c5e3a/bc59e/gatsby-icon.png
512w" <---NOTE sizes 200w, 400w, 512w
}
}
}, ...
]
}
}
}

These images in srcSet(in fact, everything under fluid) are also available under allMdx as seen below. This makes it easy to query for this information only using the allMdx tree in graphql.

To see that run the following query:

query MyQuery {
allMdx { <---NOTE THIS
edges {
node {
frontmatter {
title
keywords
featuredImage {
childImageSharp {
fluid {
srcSet <---NOTE THIS
}
}
}
}
}
}
}
}

and the result is:

{
"data": {
"allMdx": { <---NOTE THIS
"edges": [
{
"node": {
"frontmatter": {
"title": "MDX and gatsby-plugin-sharp schema basics",
"keywords": [
"featuredImage",
"graphql",
"gatsby",
"MDX",
"schema",
"fundamentals"
],
"featuredImage": {
"childImageSharp": {
"fluid": {
"srcSet": "/static/ <---NOTE static
4a9773549091c227cd2eb82ccd9c5e3a/69585/
gatsby-icon.png 200w,\n/static/ <---NOTE 200w
4a9773549091c227cd2eb82ccd9c5e3a/497c6/
gatsby-icon.png 400w,\n/static/ <---NOTE 400w
4a9773549091c227cd2eb82ccd9c5e3a/bc59e
/gatsby-icon.png 512w" <---NOTE 512w
}
}
}
}
}
}
]
}
}
}

All of this might seem very basic to the initiated, but I thought it would be useful to know if you weren’t aware of it already. :-)

If you don’t see the featuredImage displayed on this blog post, it is because it is not implemented as yet on this website. This post is about finding it in graphql.

Resources for showing the featuredImage in blog posts:


tufan.io
Making it simple to create, manage & secure cloud applications.