diff --git a/.changeset/forty-rice-provide.md b/.changeset/forty-rice-provide.md
new file mode 100644
index 000000000..cff1ec123
--- /dev/null
+++ b/.changeset/forty-rice-provide.md
@@ -0,0 +1,5 @@
+---
+'astro': minor
+---
+
+Support for dynamic Markdown through the content attribute.
diff --git a/docs/markdown.md b/docs/markdown.md
index 116f807a6..c20124096 100644
--- a/docs/markdown.md
+++ b/docs/markdown.md
@@ -97,7 +97,7 @@ const expressions = 'Lorem ipsum';
### Remote Markdown
-If you have Markdown in a remote source, you may pass it directly to the Markdown component. For example, the example below fetches the README from Snowpack's GitHub repository and renders it as HTML.
+If you have Markdown in a remote source, you may pass it directly to the Markdown component through the `content` attribute. For example, the example below fetches the README from Snowpack's GitHub repository and renders it as HTML.
```jsx
---
@@ -107,7 +107,27 @@ const content = await fetch('https://raw.githubusercontent.com/snowpackjs/snowpa
---
- {content}
+
+
+```
+
+Some times you might want to combine dynamic markdown with static markdown. You can nest `Markdown` components to get the best of both worlds.
+
+```jsx
+---
+import Markdown from 'astro/components/Markdown.astro';
+
+const content = await fetch('https://raw.githubusercontent.com/snowpackjs/snowpack/main/README.md').then(res => res.text());
+---
+
+
+
+ ## Markdown example
+
+ Here we have some __Markdown__ code. We can also dynamically render content from remote places.
+
+
+
```
diff --git a/examples/remote-markdown/src/pages/test.astro b/examples/remote-markdown/src/pages/test.astro
new file mode 100644
index 000000000..d0a050f35
--- /dev/null
+++ b/examples/remote-markdown/src/pages/test.astro
@@ -0,0 +1,6 @@
+---
+import Markdown from 'astro/components/Markdown.astro';
+const content = await fetch('https://raw.githubusercontent.com/snowpackjs/snowpack/main/README.md').then(res => res.text());
+---
+
+
diff --git a/packages/astro/components/Markdown.astro b/packages/astro/components/Markdown.astro
index 8e4e17cee..ae27876a9 100644
--- a/packages/astro/components/Markdown.astro
+++ b/packages/astro/components/Markdown.astro
@@ -1,3 +1,24 @@
-
-
-
+---
+import { renderMarkdown } from 'astro/dist/frontend/markdown.js';
+
+export let content: string;
+export let $scope: string;
+let html = null;
+
+// This flow is only triggered if a user passes ``
+if (content) {
+ const { content: htmlContent } = await renderMarkdown(content, {
+ mode: 'md',
+ $: {
+ scopedClassName: $scope
+ }
+ });
+ html = htmlContent;
+}
+
+/*
+ If we have rendered `html` for `content`, render that
+ Otherwise, just render the slotted content
+*/
+---
+{html ? html : }
diff --git a/packages/astro/package.json b/packages/astro/package.json
index a4e29e1cf..237f72a8d 100644
--- a/packages/astro/package.json
+++ b/packages/astro/package.json
@@ -10,7 +10,8 @@
"./package.json": "./package.json",
"./snowpack-plugin": "./snowpack-plugin.cjs",
"./components/*": "./components/*",
- "./runtime/svelte": "./dist/frontend/runtime/svelte.js"
+ "./runtime/svelte": "./dist/frontend/runtime/svelte.js",
+ "./dist/frontend/markdown.js": "./dist/frontend/markdown.js"
},
"imports": {
"#astro/compiler": "./dist/compiler/index.js",
diff --git a/packages/astro/src/compiler/codegen/index.ts b/packages/astro/src/compiler/codegen/index.ts
index 68ff8d853..a37861a28 100644
--- a/packages/astro/src/compiler/codegen/index.ts
+++ b/packages/astro/src/compiler/codegen/index.ts
@@ -557,6 +557,12 @@ async function compileHtml(enterNode: TemplateNode, state: CodegenState, compile
if (componentName === 'Markdown') {
const { $scope } = attributes ?? {};
state.markers.insideMarkdown = { $scope };
+ if (attributes.content) {
+ if (curr === 'markdown') {
+ await pushMarkdownToBuffer();
+ }
+ buffers[curr] += `,${componentName}.__render(${attributes ? generateAttributes(attributes) : 'null'}),`;
+ }
curr = 'markdown';
return;
}
diff --git a/packages/astro/src/dev.ts b/packages/astro/src/dev.ts
index 5d1f20cff..a7da0c863 100644
--- a/packages/astro/src/dev.ts
+++ b/packages/astro/src/dev.ts
@@ -33,6 +33,7 @@ export default async function dev(astroConfig: AstroConfig) {
const server = http.createServer(async (req, res) => {
timer.load = performance.now();
+
const result = await runtime.load(req.url);
debug(logging, 'dev', `loaded ${req.url} [${stopTimer(timer.load)}]`);
diff --git a/packages/astro/src/external.ts b/packages/astro/src/external.ts
index f8ae0e23c..63abeffad 100644
--- a/packages/astro/src/external.ts
+++ b/packages/astro/src/external.ts
@@ -17,7 +17,7 @@ const isAstroRenderer = (name: string) => {
// These packages should NOT be built by `esinstall`
// But might not be explicit dependencies of `astro`
-const denyList = ['prismjs/components/index.js', '@vue/server-renderer'];
+const denyList = ['prismjs/components/index.js', '@vue/server-renderer', 'astro/dist/frontend/markdown.js'];
export default Object.keys(pkg.dependencies)
// Filter out packages that should be loaded threw Snowpack
diff --git a/packages/astro/src/frontend/markdown.ts b/packages/astro/src/frontend/markdown.ts
new file mode 100644
index 000000000..3a446092f
--- /dev/null
+++ b/packages/astro/src/frontend/markdown.ts
@@ -0,0 +1 @@
+export { renderMarkdown } from '../compiler/utils';
\ No newline at end of file
diff --git a/packages/astro/test/astro-markdown.test.js b/packages/astro/test/astro-markdown.test.js
index bb5a540e0..ecd946f47 100644
--- a/packages/astro/test/astro-markdown.test.js
+++ b/packages/astro/test/astro-markdown.test.js
@@ -45,4 +45,14 @@ Markdown('Bundles client-side JS for prod', async (context) => {
assert.ok(counterJs, 'Counter.jsx is bundled for prod');
});
+Markdown('Renders dynamic content though the content attribute', async ({ runtime }) => {
+ const result = await runtime.load('/external');
+ if (result.error) throw new Error(result.error);
+
+ const $ = doc(result.contents);
+ assert.equal($('#outer').length, 1, 'Rendered markdown content');
+ assert.equal($('#inner').length, 1, 'Nested markdown content');
+ assert.ok($('#inner').is('[class]'), 'Scoped class passed down');
+});
+
Markdown.run();
diff --git a/packages/astro/test/fixtures/astro-markdown/src/pages/external.astro b/packages/astro/test/fixtures/astro-markdown/src/pages/external.astro
new file mode 100644
index 000000000..a39209d4a
--- /dev/null
+++ b/packages/astro/test/fixtures/astro-markdown/src/pages/external.astro
@@ -0,0 +1,15 @@
+---
+import Markdown from 'astro/components/Markdown.astro';
+import Hello from '../components/Hello.jsx';
+
+const outer = `# Outer`;
+const inner = `## Inner`;
+---
+
+
+
+
+ # Nested
+
+
+
\ No newline at end of file