Skip to content

ServerlessReact.dev

Student Login
  • Welcome to the workshop
Before the workshop
The workshop
Before you head out

Markdown and MDX for content

As you worked on new pages in the previous exercies, you may have noticed they were kind of cumbersome. Lots of typing.

To create a Bacon Ipsum page with a few paragraphs, subheadings, text styles, and an image takes lots of markup.

<Container>
<Heading fontSize={6}>Bacon</Heading>
<p>
Spicy jalapeno bacon ipsum dolor amet <b>turducken porchetta</b> tail, ...
</p>
<Heading fontSize={4}>Ipsum</Heading>
<p>
Hamburger pork belly tenderloin buffalo tail <em>jerky corned beef</em>. ...
</p>
<Image src="https://i.imgur.com/kEj1ePK.png" />
</Container>

Using markdown, that same content looks like this:

# Bacon
Spicy jalapeno bacon ipsum dolor amet **turducken porchetta** tail, ...
## Ipsum
Hamburger pork belly tenderloin buffalo tail _jerky corned beef_. ...
![](https://i.imgur.com/kEj1ePK.png)

Which would you rather write? 😉

Gatsby MDX

As often happens with Gatsby, there's a plugin for this. Add the MDX source plugin, configure a few options and voila: you can create new pages by adding *.mdx files.

The benefit of MDX over Markdown is that it supports all the usual Markdown syntax and lets you mix with React components.

Exercise

Continue with your previous solution or jump to my exercise-3/gatsby project.

Install gatsby-plugin-mdx, @mdx-js/mdx, and @mdx-js/react. Enable the plugin in your gatsby-config.js file.

// gatsby-config.js
{
resolve: 'gatsby-plugin-mdx',
options: {
extensions: ['.mdx', '.md']
}
}

Then create an .mdx page in src/pages and check it out. Try importing <Container> from ThemeUI and wrapping the whole markdown page.

Markdown becomes a first-class citizen in React and vice-versa 🤘

Sub exercise 0

Add a page title with the SEO component.

Sub exercise 1

Try installing the gatsby-remark-images plugin and enable it in MDX options

// gatsby-config.js
options: {
gatsbyRemarkPlugins: [{
resolve: "gatsby-remark-images",
options: {
markdownCaptions: false,
maxWidth: 890,
linkImagestoOriginal: false,
showCaptions: ["title", "alt"],
withWebp: true,
wrapperStyle: "text-align: center; font-style: italic",
tracedSVG: {
color: `lightgray`,
optTolerance: 0.4,
turdSize: 100,
turnPolicy: "TURNPOLICY_MAJORITY",
},
loading: "lazy",
}
}],
plugins: [{ resolve: "gatsby-remark-images" }]
}

Link to an image in src/images. You'll see a cool effect.

Sub exercise 2

To prove that Markdown is now a full member of your toolkit, try this:

  1. Create an mdx file in src/components
  2. Import the file on your MDX page
  3. Render it as a React component
  4. Do the same in index.js

Solution

Find mine in the exercise-3-solution branch.

NextJS MDX

Much like Gatsby, there's an official MDX plugin for NextJS. Gives you all of the same options, configuration is a little different.

Exercise

Continue with your previous solution or jump to my exercise-3/nextjs project.

Start by installing the @next/mdx and @mdx-js/loader. Then create a next.config.js file in project root.

// next.config.js
const withMDX = require("@next/mdx")({
extension: /\.mdx?$/,
})
module.exports = withMDX({
pageExtensions: ["js", "jsx", "mdx"],
})

Then create an .mdx page in src/pages and check it out. Try importing <Container> from ThemeUI and wrapping the whole markdown page.

Markdown becomes a first-class citizen in React and vice-versa 🤘

Sub exercise 0

NextJS won't let you render a <Head> component in MDX like you could with Gatsby. Instead you'll have to:

  1. make a Layout component in components/layout
  2. have it render children and a Head
  3. 👇
// top MDX file
import { Layout } from "../components/Layout"
export default ({ children }) => <Layout title="Bacon Ipsum">{children}</Layout>

Sub exercise 1

You can embed images by adding them to the public/images directory and linking with ![](/images/...)

Solution

Find mine in the exercise-3-solution branch.

Did you enjoy this chapter?

Previous:
Routing and pages
Next:
Dynamic data in the browser
Created bySwizecwith ❤️