Markdoc support in content collections #478
Replies: 6 comments 5 replies
-
Love this! Some thoughts:
|
Beta Was this translation helpful? Give feedback.
-
Why not support Some users may expect Markdoc support in
Given this, Markdoc may be a good chance to experiment with content only formats that do not exist as standalone pages. Why not support ESM imports? This was mainly excluded because supporting ESM and not |
Beta Was this translation helpful? Give feedback.
-
As a editor tooling author, I'm super biased against formats using other formats file extensions. If ex: a VS Code extension were to be created for Markdoc, every single project would need to configure their editor to recognize Apart from that, not much to comment on, I love the pattern with the wrapper component for using a custom config! Very Astro-y! |
Beta Was this translation helpful? Give feedback.
-
Mostly super excited about this. Love that this proposal has very explicit goals and non-goals that allow this to be introduced at a smaller scope to start (such as only being available within content collections). One question,
Would this not work? <Content
Aside={((props) => {
return (
<Aside client:load {...props} />
)
})}
/> I think the compiler is smart enough to pick that up. If that doesn't work it's worth investigating. Not a blocker at this point, but I do think that one of the major use-case people have for components in markdown is to add interactive components to posts. I think we can figure out how to get it to work. |
Beta Was this translation helpful? Give feedback.
-
Questions about the DX of custom componentsHow does a developer know they are passing the right components to
|
Beta Was this translation helpful? Give feedback.
-
This proposal has been moved to stage 2: #496 Please direct any feedback / comments to that issue now, thanks! |
Beta Was this translation helpful? Give feedback.
-
Body
Summary
This is a proposal to add Markdoc support to content collections.
Background & Motivation
We've received multiple user requests for Markdoc support since its public launch. In fact, we've seen early community projects bringing Markdoc to robust project themes.
Markdoc is also designed to solve existing limitations of MDX in Astro.
Markdoc is built to solve (2) by separating content from the components, styles, and assets you choose to render. You can use an Astro component renderer when using on your site, Markdoc's own
html
renderer for RSS, and even write your own renderer to traverse Markdoc pages yourself. (1) Is something we're excited to test, requiring a thorough performance benchmark.The content collections API was built generically to support this future, choosing format-agnostic naming like
data
instead offrontmatter
andbody
instead ofrawContent
. Because of this, introducing new authoring formats is possible without breaking changes.Goals
@astrojs/markdoc
integration that adds.mdoc
support to content collections.Non-goals
src/pages/
support for Markdoc files. See discussion for context..md
extension. This would mean overriding Astro's.md
renderer, which is tightly coupled to remark and yourmarkdown
configuration options today. We agree using.md
for Markdoc is a common use case, and deserves a separate proposal to make Astro's Markdown rendering flexible.client:
directive.headings
property (which can be tackled in future releases) and frontmatter manipulation via remark (since remark is incompatible with Markdoc).Example implementation
Markdoc will be introduced as an integration. To standardize our process for adding new collection teams, we may experiment with a (private) integration helper internally. This example shows an
addContentEntryType
hook to setup the.mdoc
extension, and attach logic for parsing thedata
andbody
properties:Example Usage
Say you've authored a collection of blog posts using Markdoc. You can store these entries as a
blog
collection, identically to Markdown or MDX:src/content/ blog/ # Could also use `.md` post-1.mdoc post-2.mdoc post-3.mdoc ...
Then, you can query entry frontmatter with the same
getCollection()
andgetEntryBySlug()
APIs:Users should also be free to render Markdoc contents using a
Content
component. This will be exposed from therender()
result, and feature two props:components?: Record<string, ComponentRenderer>
: A mapping from Markdoc tags or elements to Astro components.config?: import('@markdoc/markdoc').Config
: An (optional) Markdoc config to be used during the transformation step.Sharing config
This solution is flexible, but we expect users to reuse
config
andcomponents
across their project. For this, we will recommend creating a utility component to encapsulate that config. Here is one example that can render anyblog
collection entry with an{% aside /%}
shortcode:Now, you can pass any blog collection entry to render the result with this config:
See this example video for more.
Advanced use case: component prop mapping
Component renderers can also include a
props()
function to map Markdoc attributes and AST entries to component props. This is useful when:This example maps Markdoc's generated
data-language
attribute for code blocks to thelang
prop used by Astro'sCode
component, and stringifies the contents to HTML for use with Shiki:Beta Was this translation helpful? Give feedback.
All reactions