withastro / docs

Astro documentation
https://docs.astro.build/
MIT License
1.3k stars 1.44k forks source link

Using a common Layout component for Markdown pages and content collections #8934

Closed rgov closed 1 month ago

rgov commented 1 month ago

📚 Subject area/topic

Layouts

📋 Page(s) affected (or suggested, for new content)

https://docs.astro.build/en/basics/layouts/#using-one-layout-for-md-mdx-and-astro

📋 Description of content that is out-of-date or incorrect

I can't decide if this is a proposal, a bug report against Astro, or a documentation issue. It boils down to an ugliness with trying to re-use a Layout component between a Markdown page and a Markdown content collection entry, and how frontmatter keys are passed to the Layout component.

The Layout component of a Markdown page accesses frontmatter like Astro.props.frontmatter.author (docs).

The .astro file that renders a Markdown content entry accesses the frontmatter via Astro.props.data (docs). Following the documented conventions, these are passed through to a Layout component, which can then access the frontmatter like Astro.props.author.

This leads to confusion using the same Layout for both content entries and Markdown pages, how should the frontmatter be accessed? This is [partially covered in the documentation](), giving a workaround like this:

const { author } = Astro.props.frontmatter || Astro.props;

However, this is an incomplete solution, because content collections have a Zod schema that can include field transformations. For example, "dates written without quotes around them are interpreted as Date objects", and arbitrary transformations can be applied with .transform(). These transformations are skipped entirely for Markdown pages.

I think a more complete version would be:

import { collections } from '../content/config';
const { author } = Astro.props.frontmatter ? collections.blog.schema.parse(Astro.props.frontmatter) : Astro.props;

However, I think it would be conceptually clearer to address this another way. It's odd for a Layout component to have to invoke a parser / validator on its props.

🖥️ Reproduction in StackBlitz (if reporting incorrect content or code samples)

No response

sarah11918 commented 1 month ago

Hi, thank you for this report! We already have an issue about this exact line in docs, and an open PR #8763 where someone is attempting to improve this. I think that tells us this is pretty problematic, indeed! :sweat_smile:

I'd love it if you commented in the PR itself to let us know whether that is on the right track for addressing your concern, and honestly, there's a case for removing that entire example entirely.

Fun fact: if I recall, that section was added after a breaking change to the Markdown props exported to .astro files (I think maybe even for v1.0!) At the time, we were helping to bridge the gap between people who might have needed to update projects and handle their props differently. We thought showing something like this was helpful back then, but certainly, it may have outgrown its use!

Please take a look and see whether the proposed PR seems like a helpful change, and/or let us know if you'd suggest removing this section entirely! Two issues is a pretty big indication that maybe the content is more harmful than helpful!