summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Nate Moore <natemoo-re@users.noreply.github.com> 2021-07-08 16:47:23 -0500
committerGravatar GitHub <noreply@github.com> 2021-07-08 16:47:23 -0500
commit42a6acee284caebf597f9f0a11dcc01219d4230b (patch)
treee3b0979eec4809db49cc4551c7f850803e1cfeed
parentb4f145a0e736b37824123033893df16aabedab52 (diff)
downloadastro-42a6acee284caebf597f9f0a11dcc01219d4230b.tar.gz
astro-42a6acee284caebf597f9f0a11dcc01219d4230b.tar.zst
astro-42a6acee284caebf597f9f0a11dcc01219d4230b.zip
Add support for components defined in frontmatter (#637)
* fix: add support for components defined in frontmatter * chore: add changeset * test: update test to match example use case
-rw-r--r--.changeset/twelve-lions-tie.md14
-rw-r--r--packages/astro/src/compiler/codegen/index.ts16
-rw-r--r--packages/astro/test/astro-basic.test.js8
-rw-r--r--packages/astro/test/fixtures/astro-basic/src/pages/frontmatter-component.astro6
4 files changed, 43 insertions, 1 deletions
diff --git a/.changeset/twelve-lions-tie.md b/.changeset/twelve-lions-tie.md
new file mode 100644
index 000000000..2010637ca
--- /dev/null
+++ b/.changeset/twelve-lions-tie.md
@@ -0,0 +1,14 @@
+---
+'astro': patch
+---
+
+Add support for components defined in Frontmatter. Previously, the following code would throw an error. Now it is officially supported!
+
+```astro
+---
+const { level = 1 } = Astro.props;
+const Element = `h${level}`;
+---
+
+<Element>Hello world!</Element>
+```
diff --git a/packages/astro/src/compiler/codegen/index.ts b/packages/astro/src/compiler/codegen/index.ts
index 7bfb55f53..6a5b5e546 100644
--- a/packages/astro/src/compiler/codegen/index.ts
+++ b/packages/astro/src/compiler/codegen/index.ts
@@ -688,7 +688,21 @@ async function compileHtml(enterNode: TemplateNode, state: CodegenState, compile
componentInfo = components.get(componentNamespace);
}
if (!componentInfo && !isCustomElementTag(componentName)) {
- throw new Error(`Unknown Component: ${componentName}`);
+ if (hydrationAttributes.method) {
+ throw new Error(`Unable to hydrate "${componentName}" because it is statically defined in the frontmatter script. Hydration directives may only be used on imported components.`);
+ }
+
+ // Previously we would throw here, but this is valid!
+ // If the frontmatter script defines `const Element = 'h1'`,
+ // you should be able to statically render `<Element>`
+
+ if (curr === 'markdown') {
+ await pushMarkdownToBuffer();
+ }
+
+ paren++;
+ buffers[curr] += `h(${componentName}, ${attributes ? generateAttributes(attributes) : 'null'}`;
+ return;
}
if (componentName === 'Markdown') {
const { $scope } = attributes ?? {};
diff --git a/packages/astro/test/astro-basic.test.js b/packages/astro/test/astro-basic.test.js
index 38f62085e..c2051b3eb 100644
--- a/packages/astro/test/astro-basic.test.js
+++ b/packages/astro/test/astro-basic.test.js
@@ -95,4 +95,12 @@ Basics('Allows spread attributes with TypeScript (#521)', async ({ runtime }) =>
assert.equal($('#spread-ts').attr('c'), '2');
});
+Basics('Allows Components defined in frontmatter', async ({ runtime }) => {
+ const result = await runtime.load('/frontmatter-component');
+ const html = result.contents;
+ const $ = doc(html);
+
+ assert.equal($('h1').length, 1);
+});
+
Basics.run();
diff --git a/packages/astro/test/fixtures/astro-basic/src/pages/frontmatter-component.astro b/packages/astro/test/fixtures/astro-basic/src/pages/frontmatter-component.astro
new file mode 100644
index 000000000..69f708505
--- /dev/null
+++ b/packages/astro/test/fixtures/astro-basic/src/pages/frontmatter-component.astro
@@ -0,0 +1,6 @@
+---
+const { level = 1 } = Astro.props;
+const Element = `h${level}`;
+---
+
+<Element>Hello world!</Element>