summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;