I have recently updated Gatsby from V3 to V4 (latest one) and also updated the plugins below.
"@mdx-js/mdx": "^2.1.3",
"@mdx-js/react": "^2.1.3",
"gatsby-plugin-mdx": "^4.1.0",
"gatsby": "^4.21.1",
The code in node-config.js:
{
resolve: `gatsby-plugin-mdx`,
options: {
defaultLayouts: { default: require.resolve(`./src/components/layout`), },
},
},
{
resolve: `gatsby-source-filesystem`,
options: {
name: `pages`,
path: `${__dirname}/src/pages/`,
},
},
In /src/pages/index.mdx
---
title: Title
description: Description
class: home
imageTwitter: /twitter-home.jpg
imageOg: "/og-home.jpg"
imageAlt: Image for the Title.
---
import { StaticImage } from "gatsby-plugin-image"
import { Container, Row, Col, Card } from "react-bootstrap"
import { Link } from "gatsby"
import { navigate } from "gatsby"
<div class="w-60 text-center home-intro">
content
</div>
Latest version of gatsby-plugin-mdx doesn't have defaultLayout so when I hit http://localhost:8000/ the page loads without header and footer because the layout doesn't work.
In /src/components/layout.js
import React from "react"
import PropTypes from "prop-types"
import { StaticQuery, graphql } from "gatsby"
import { Container, Row, Col } from "react-bootstrap"
import "../styles.scss"
import Footer from "./footer"
import Menu from "./menu"
import Helmet from "react-helmet"
const Layout = ({ location, children, pageContext, ...props }) => (
<StaticQuery
query={graphql`
query SiteTitleQuery {
site {
siteMetadata {
title
siteUrl
}
}
allMdx {
edges {
node {
frontmatter {
title
description
class
imageOg
imageTwitter
}
}
}
}
}
`}
render={data => (
<>
<Helmet>
<body className={pageContext.frontmatter.class} />
</Helmet>
<Container>
<Row>
<Col>
<Menu />
</Col>
</Row>
</Container>
<Container className="full-width">
<Row className="mx-0">
<Col>
<main>
<article id="content">
{children}
</article>
</main>
</Col>
</Row>
</Container>
<Footer />
</>
)}
/>
)
Layout.propTypes = {
children: PropTypes.node.isRequired,
}
export default Layout
Is there any way I can create a default template inside the page's directory and then reference each MDX file as a child? For example, if it's index page then it will select home.mdx
According to the migration guide, you have several options to use a common layout across dynamic page creation:
wrapPageElementAPI including its SSR counterpart.export default Layoutstatement to your MDX file, see MDX documentation on Layout.createPageaction to programatically create pages, you should use the following URI pattern for your page component:your-layout-component.js?__contentFilePath=absolute-path-to-your-mdx-file.mdx. To learn more about this, head to the programmatically creating pages guide.Given your scenario, I'd say option 2 and 3 fits better since they are easy to implement and has fewer changes to conflict to whatever you had already but. Chose wisely, whatever fits your specs (if you are or ain't using
gatsby-node.js, using global wrappers as Redux, etc.).Option 2
If you define a
Layout, it will be used to wrap all content. A layout can be defined from within MDX using a default export:Or:
The layout can also be passed as
components.wrapper(but a local one takes precedence).Option 3
In your
gatsby-node.js, in your page generation you need to point to the layout like:Note: this approach may force you to tweak a little bit the GraphQL query to add the needed data to build the
__contentFilePathproperly.