Frontmatter introduction
As stated in the GitHub frontmatter documentation, the Jekyll static site generator was the first to popularize frontmatter, but today a lot of frameworks and libraries add support for frontmatter. So maybe your markdown files already have frontmatter and you want to be able to use that data, or you are like me and just learned about frontmatter now and think it is a good way to store metadata in your MDX files
You might have noticed that frontmatter is sometimes called "yaml frontmatter" or "frontmatter yaml", this is because frontmatter uses the YAML data language
To add frontmatter to a document, you start by adding 3 dashes (---
), then add your frontmatter yaml, and finally close the frontmatter block with another 3 dashes (---
)
I already mentioned the GitHub and Jekyll documentation about frontmatter, they both specify predefined frontmatter variables, but because we will add our own frontmatter support, we are free to use whatever variables we think are useful for our project. One convention that I follow, is to always put the frontmatter part on top of the MDX page (or top of the markdown document)
Frontmatter plugins installation
What we will do in this chapter is add 2 plugins to our next/mdx setup that will read the frontmatter part of our MDX pages and then automatically populate the Next.js metadata object (using the frontmatter metadata) for us
Use the following command to install the 2 remark frontmatter plugins:
remark-frontmatter is a plugin that will parse the frontmatter, without this plugin, an MDX page with frontmatter would just display the frontmatter as text (when getting rendered), after enabling this plugin, the frontmatter part will not show up in your MDX pages anymore but will get parsed as frontmatter yaml
remark-mdx-frontmatter is a plugin that is important as it will put the parsed frontmatter values into a variable inside of our MDX documents, the variable is called frontmatter
by default but you can change the name using the options of the plugin
Next, we add the frontmatter plugins to our next/mdx configuration:
Lines 11 to 12: we import the 2 frontmatter plugins
Line 58: we add both to our remark plugins list
Something I will not cover here, but if you want to go a step further and are interested in adding linting for the frontmatter part, then have a look at remark-lint-frontmatter-schema
Frontmatter for metadata (and more)
Now it is time to create an example where we define some frontmatter. Then we let both plugins do their magic, and finally we can use the frontmatter variable to populate the Next.js metadata object
Let's reuse our gfm plaground page one more time
First, remove the current metadata and then add this instead:
Lines 1 to 8: we first added our frontmatter block on top of the page with some custom variables that suit our needs
Lines 10 to 21: we created a Next.js metadata object and used the frontmatter object (that holds all the key/value pairs from our frontmatter above) to populate the metadata object
Finally, make sure the dev server is running, then open the playground page http://localhost:3000/gfm_playground
in your browser and then right-click in the page to have a look at the meta tags inside of the <head>
element
You should be getting the following result:
Lines 1 to 2: are the viewport and charset Next.js adds by default
Line 3: is the default HTML title element that has the frontmatter.title
as value and uses the template we have set in the layout file
Line 4: we have the description meta tag
Line 5: we have a keywords meta tag, which contains some keywords we added to our frontmatter, it is an example of how an array gets transformed into a string, but search engines like google apparently don't use it
Lines 6 and 7: we have open graph title and description, which Next.js sets based on the default title and description
Lines 8 and 9: we have the open graph URL and sitename, which are two values we have set in our frontmatter
Line 10: we have the open graph type to article, just to demonstrate the following two meta tags at lines 11 and 12
Line 11 and 12: we have two new meta tags, which have a property that is NOT prefixed with og:
, opengraph has a documentation page for the https://ogp.me/#type_article about the open graph article namespace, it needs to have the open graph type set to article and then you get tags that are prefixed with article:
, if however the type is for example set to website, then those two metatags will disappear from the head element (even if you define them in your page source)
Lines 13 to 16: we have the keywords that get used as tags for our open graph article, unlike the keywords meta tag, the tags get split into multiple tags
Frontmatter linting errors
If you followed the remark lint tuturial part, you might have noticed that as soon as you add the frontmatter block to your MDX documents, remark-lint will start complaining about non valid content, if you hover with your mouse over the part that is underlined with a green wave, it will open a modal that shows you one of those linting problems:
Unexpected setext heading, expected ATX (remark-lint-heading-style)
If you launch use the npm run lint
linting command you will see even more:
Unexpected setext heading, expected ATX (remark-lint-heading-style)
Unexpectedxxx
characters in heading, expected at most100
characters (remark-lint-maximum-heading-length)
Unexpected reference to undefined definition, expected corresponding definition ('foo'
) for a link or escaped opening bracket (\[
) for regular text (remark-lint-no-undefined-references)
To solve this problem need to add frontmatter as a plugin to our remark lint configuration file (that is in root of the project):
Line 13: we import the frontmatter plugin
Line 34: we add the frontmatter plugin to the remark lint configuration
If you now run the linting process again the errors should be gone (if they are not gone yet, then you might want to clear the ESLint cache) and they should also disappear in VSCode (you might have to restart the ESLint server in VSCode to update the linting process)
Congratulations 🎉 you just learned how to set metadata for MDX pages and how to add frontmatter to MDX documents
If you liked this post, please consider making a donation ❤️ as it will help me create more content and keep it free for everyone