docs icon indicating copy to clipboard operation
docs copied to clipboard

Cannot access MDX exports in layout file

Open connor-baer opened this issue 3 years ago • 2 comments

What version of astro are you using?

1.2.6

Are you using an SSR adapter? If so, which one?

None

What package manager are you using?

npm

What operating system are you using?

Mac

Describe the Bug

Variables that are exported from an MDX file aren't accessible in the layout component.

// pages/posts/example.mdx
---
layout: '../../layouts/post.astro'
---

export const published = new Date('2022-09-17');

Here's some markdown...
// layouts/post.astro
---
// published is undefined
const { published } = Astro.props;
---

<p>Published on: {published}.</p>
<slot />

The docs on MDX variables state:

MDX supports export statements to add variables to your templates. These variables are accessible both from the template itself and as named properties when importing the template somewhere else.

I've verified that the exported variables are accessible when importing the MDX file individually or using a glob.

Link to Minimal Reproducible Example

https://stackblitz.com/edit/github-7oqnyx?file=src/layouts/post.astro

Participation

  • [X] I am willing to submit a pull request for this issue.

connor-baer avatar Sep 17 '22 16:09 connor-baer

Found a workaround by importing the layout in the MDX file and passing it the variable directly (aka the standard MDX way):

// pages/posts/example.mdx
import Layout from '../../layouts/post.astro'

export const published = new Date('2022-09-17');

export default ({ children }) => <Layout published={published}>{children}</Layout>

Here's some markdown...

The downside is that Astro-style frontmatter in yaml format can't be used/passed to the layout this way.

connor-baer avatar Sep 17 '22 16:09 connor-baer

@connor-baer thanks for reporting! Yes, this is a known limitation of setting a layout from your frontmatter. I'd definitely recommend your workaround as the way to pass these exports.

Also, you can pass your YAML-based frontmatter using the frontmatter prop:

---
title: My title!
---
import Layout from '../../layouts/post.astro'

export const published = new Date('2022-09-17');

export default ({ children }) => <Layout published={published} title={frontmatter.title}>{children}</Layout>

This is in our @astrojs/mdx docs today, but sadly absent from the main Markdown docs. Might be worth some content tweaking if you're up for a PR 😁

bholmesdev avatar Sep 19 '22 21:09 bholmesdev

Closing this issue, as I believe Docs shows an example of this now. (importing the layout component, and then passing both something defined in frontmatter, and something defined not in frontmatter as props) https://docs.astro.build/en/core-concepts/layouts/#importing-layouts-manually-mdx

sarah11918 avatar Dec 29 '22 11:12 sarah11918