//TODO: This post needs a revision to a recent Astro version.
//TODO: Accompanying demo material for this article has been deleted as it did not work with Astro V1+.
We want to access “compiled” markdown content from our .md
files.
In Astro, working with markdown files .md
is very easy, and for most of your tasks you rely on the file’s frontmatter
. There are a lot of use-cases where this is sufficient.
But there are some use-cases, where you need the actual content of your markdown, and getting to it has proven difficult.
After a few failed attempts, I now have the secret formula for grabbing the markdown content without resorting to something like node:fs
and doing a custom implementation.
Kudos to clarkio on the Astro Discord for figuring it out!
The thread
Using Astro.glob(); and import.meta.globEager()
for non-Astro pages.
For this scenario, we’ll use import.meta.globEager('./blog/*.md')
.
//-- /src/pages/exportSearchIndexWithContent.json.js
export async function get() {
let posts = await import.meta.globEager(`./blog/*.md`);
let ary = [];
for (let postkey in posts) {
if (posts[postkey].frontmatter.published && posts[postkey].frontmatter.title) {
let post = posts[postkey];
let awaitedPost = await post.default(); //1//
ary.push({
title: post.frontmatter.title,
summary: post.frontmatter.summary,
tags: post.frontmatter.tags.join(' '),
appCode: 'roc',
published: post.frontmatter.published,
slug: post.url,
image: post.frontmatter.og.basic.image,
content: awaitedPost.metadata.source //2//
});
}
}
let body = { entries: ary };
return {
body: JSON.stringify(body, false, 2)
};
};
The snippet contains a full operational non-HTML page, and you can view the results in the following link:
The relevant/key lines on the above snippet I have commented with (1) and (2).
md
properties that are “unlocked” by calling the async .default()
method.metadata
and it contains source
Another unlocked property is html which contains compiled markdown, except for parts where AstroComponents are used, which cannot be compiled during markdown and require an extra step.
For this scenario, we’ll use the available Astro.glob('./blog/*.md')
.
//-- /src/pages/blog/samples/astro-md-content/using-markdown.astro
---
import { Markdown } from 'astro/components';
let posts = await Astro.glob('./sample-md.md');
let post = posts[0];
let awaitedContent = await post.default(); //1//
---
<Markdown>
{awaitedContent.metadata.source} //2//
</Markdown>
The relevant/key lines on the above snippet I have commented with (1) and (2).
glob element
has been stored in Astro.props.content
, and we can still “unlock” by calling the async .default()
method.metadata
has been “unlocked” and it contains source
A variant pointed out by clarkio is achieved by:
//-- /src/pages/blog/samples/astro-md-content/using-content.astro
---
let posts = await Astro.glob('./sample-md.md');
let post = posts[0];
---
<post.Content />
Turns out the Content
property is an AstroComponent
and will take care of outputting the compiled markdown.
The markdown content is “hidden” away behind an async default()
method, and found at .metadata.source
.
Content
property on the glob results, is an AstroComponent
and you can use it as such.It makes sense that it is not readily available as it could fill someone’s memory resources if the amount of files is considerably large.
Perhaps we will see an official way to obtain this content in the near future when the documentation reaches a more stable state.