summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Mihkel Eidast <mihkel@play.ee> 2021-08-10 00:36:12 +0300
committerGravatar GitHub <noreply@github.com> 2021-08-09 16:36:12 -0500
commit618ea3a8ea8155e80e61f6a4718f6661d6297997 (patch)
treea8b31dcd04e193bcabdae62381dbc2a8e4cd6ec6
parentbef7247812f6b446ffd5cd273452bacd2b032f73 (diff)
downloadastro-618ea3a8ea8155e80e61f6a4718f6661d6297997.tar.gz
astro-618ea3a8ea8155e80e61f6a4718f6661d6297997.tar.zst
astro-618ea3a8ea8155e80e61f6a4718f6661d6297997.zip
Fix nested client load directive (#1030)
* escape </script> in string literals * add changeset
-rw-r--r--.changeset/fair-dogs-tie.md5
-rw-r--r--packages/astro/src/internal/__astro_component.ts18
2 files changed, 21 insertions, 2 deletions
diff --git a/.changeset/fair-dogs-tie.md b/.changeset/fair-dogs-tie.md
new file mode 100644
index 000000000..caf00c755
--- /dev/null
+++ b/.changeset/fair-dogs-tie.md
@@ -0,0 +1,5 @@
+---
+'astro': patch
+---
+
+Properly escapes script tags with nested client:load directives when passing Astro components into framework components via props. Browsers interpret script end tags in strings as script end tags, resulting in syntax errors.
diff --git a/packages/astro/src/internal/__astro_component.ts b/packages/astro/src/internal/__astro_component.ts
index 9470e5b14..0543df203 100644
--- a/packages/astro/src/internal/__astro_component.ts
+++ b/packages/astro/src/internal/__astro_component.ts
@@ -1,12 +1,26 @@
import type { Renderer, AstroComponentMetadata } from '../@types/astro';
import hash from 'shorthash';
import { valueToEstree, Value } from 'estree-util-value-to-estree';
-import { generate } from 'astring';
+import { generate, GENERATOR, Generator } from 'astring';
import * as astroHtml from './renderer-html';
// A more robust version alternative to `JSON.stringify` that can handle most values
// see https://github.com/remcohaszing/estree-util-value-to-estree#readme
-const serialize = (value: Value) => generate(valueToEstree(value));
+const customGenerator: Generator = {
+ ...GENERATOR,
+ Literal(node, state) {
+ if (node.raw != null) {
+ // escape closing script tags in strings so browsers wouldn't interpret them as
+ // closing the actual end tag in HTML
+ state.write(node.raw.replace('</script>', '<\\/script>'));
+ } else {
+ GENERATOR.Literal(node, state);
+ }
+ },
+};
+const serialize = (value: Value) => generate(valueToEstree(value), {
+ generator: customGenerator,
+});
export interface RendererInstance {
source: string | null;