diff --git a/.changeset/large-mangos-look.md b/.changeset/large-mangos-look.md
new file mode 100644
index 000000000..65129ee98
--- /dev/null
+++ b/.changeset/large-mangos-look.md
@@ -0,0 +1,5 @@
+---
+"@astrojs/compiler": patch
+---
+
+Fixes a bug where the compiler couldn't correctly parse `select` elements, preventing elements from being incorrectly nested
diff --git a/internal/parser.go b/internal/parser.go
index 42d7eb0d8..ba607ea84 100644
--- a/internal/parser.go
+++ b/internal/parser.go
@@ -2319,6 +2319,8 @@ func inSelectIM(p *parser) bool {
p.resetInsertionMode()
case a.Template:
return inHeadIM(p)
+ default:
+ return inBodyIM(p)
}
case CommentToken:
p.addChild(&Node{
diff --git a/internal/printer/__printer_js__/select_with_2_options_containing_element.snap b/internal/printer/__printer_js__/select_with_2_options_containing_element.snap
new file mode 100755
index 000000000..25bf28851
--- /dev/null
+++ b/internal/printer/__printer_js__/select_with_2_options_containing_element.snap
@@ -0,0 +1,41 @@
+
+[TestPrinter/select_with_2_options_containing_element - 1]
+## Input
+
+```
+
+```
+
+## Output
+
+```js
+import {
+ Fragment,
+ render as $$render,
+ createAstro as $$createAstro,
+ createComponent as $$createComponent,
+ renderComponent as $$renderComponent,
+ renderHead as $$renderHead,
+ maybeRenderHead as $$maybeRenderHead,
+ unescapeHTML as $$unescapeHTML,
+ renderSlot as $$renderSlot,
+ mergeSlots as $$mergeSlots,
+ addAttribute as $$addAttribute,
+ spreadAttributes as $$spreadAttributes,
+ defineStyleVars as $$defineStyleVars,
+ defineScriptVars as $$defineScriptVars,
+ renderTransition as $$renderTransition,
+ createTransitionScope as $$createTransitionScope,
+ renderScript as $$renderScript,
+ createMetadata as $$createMetadata
+} from "http://localhost:3000/";
+
+export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
+
+const $$Component = $$createComponent(($$result, $$props, $$slots) => {
+
+return $$render`${$$maybeRenderHead($$result)}`;
+}, undefined, undefined);
+export default $$Component;
+```
+---
diff --git a/internal/printer/__printer_js__/select_with_2_options_containing_element_with_div_sibling.snap b/internal/printer/__printer_js__/select_with_2_options_containing_element_with_div_sibling.snap
new file mode 100755
index 000000000..6e404e4b6
--- /dev/null
+++ b/internal/printer/__printer_js__/select_with_2_options_containing_element_with_div_sibling.snap
@@ -0,0 +1,41 @@
+
+[TestPrinter/select_with_2_options_containing_element_with_div_sibling - 1]
+## Input
+
+```
+
Orange
+```
+
+## Output
+
+```js
+import {
+ Fragment,
+ render as $$render,
+ createAstro as $$createAstro,
+ createComponent as $$createComponent,
+ renderComponent as $$renderComponent,
+ renderHead as $$renderHead,
+ maybeRenderHead as $$maybeRenderHead,
+ unescapeHTML as $$unescapeHTML,
+ renderSlot as $$renderSlot,
+ mergeSlots as $$mergeSlots,
+ addAttribute as $$addAttribute,
+ spreadAttributes as $$spreadAttributes,
+ defineStyleVars as $$defineStyleVars,
+ defineScriptVars as $$defineScriptVars,
+ renderTransition as $$renderTransition,
+ createTransitionScope as $$createTransitionScope,
+ renderScript as $$renderScript,
+ createMetadata as $$createMetadata
+} from "http://localhost:3000/";
+
+export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
+
+const $$Component = $$createComponent(($$result, $$props, $$slots) => {
+
+return $$render`${$$maybeRenderHead($$result)}Orange
`;
+}, undefined, undefined);
+export default $$Component;
+```
+---
diff --git a/internal/printer/__printer_js__/select_with_option_containing_element.snap b/internal/printer/__printer_js__/select_with_option_containing_element.snap
new file mode 100755
index 000000000..50d4fa234
--- /dev/null
+++ b/internal/printer/__printer_js__/select_with_option_containing_element.snap
@@ -0,0 +1,41 @@
+
+[TestPrinter/select_with_option_containing_element - 1]
+## Input
+
+```
+
+```
+
+## Output
+
+```js
+import {
+ Fragment,
+ render as $$render,
+ createAstro as $$createAstro,
+ createComponent as $$createComponent,
+ renderComponent as $$renderComponent,
+ renderHead as $$renderHead,
+ maybeRenderHead as $$maybeRenderHead,
+ unescapeHTML as $$unescapeHTML,
+ renderSlot as $$renderSlot,
+ mergeSlots as $$mergeSlots,
+ addAttribute as $$addAttribute,
+ spreadAttributes as $$spreadAttributes,
+ defineStyleVars as $$defineStyleVars,
+ defineScriptVars as $$defineScriptVars,
+ renderTransition as $$renderTransition,
+ createTransitionScope as $$createTransitionScope,
+ renderScript as $$renderScript,
+ createMetadata as $$createMetadata
+} from "http://localhost:3000/";
+
+export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
+
+const $$Component = $$createComponent(($$result, $$props, $$slots) => {
+
+return $$render`${$$maybeRenderHead($$result)}`;
+}, undefined, undefined);
+export default $$Component;
+```
+---
diff --git a/internal/printer/__printer_js__/select_with_option_containing_element_and_button_containing_selected_content.snap b/internal/printer/__printer_js__/select_with_option_containing_element_and_button_containing_selected_content.snap
new file mode 100755
index 000000000..eb1d207e8
--- /dev/null
+++ b/internal/printer/__printer_js__/select_with_option_containing_element_and_button_containing_selected_content.snap
@@ -0,0 +1,41 @@
+
+[TestPrinter/select_with_option_containing_element_and_button_containing_selected_content - 1]
+## Input
+
+```
+
+```
+
+## Output
+
+```js
+import {
+ Fragment,
+ render as $$render,
+ createAstro as $$createAstro,
+ createComponent as $$createComponent,
+ renderComponent as $$renderComponent,
+ renderHead as $$renderHead,
+ maybeRenderHead as $$maybeRenderHead,
+ unescapeHTML as $$unescapeHTML,
+ renderSlot as $$renderSlot,
+ mergeSlots as $$mergeSlots,
+ addAttribute as $$addAttribute,
+ spreadAttributes as $$spreadAttributes,
+ defineStyleVars as $$defineStyleVars,
+ defineScriptVars as $$defineScriptVars,
+ renderTransition as $$renderTransition,
+ createTransitionScope as $$createTransitionScope,
+ renderScript as $$renderScript,
+ createMetadata as $$createMetadata
+} from "http://localhost:3000/";
+
+export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
+
+const $$Component = $$createComponent(($$result, $$props, $$slots) => {
+
+return $$render`${$$maybeRenderHead($$result)}`;
+}, undefined, undefined);
+export default $$Component;
+```
+---
diff --git a/internal/printer/__printer_js__/select_with_option_containing_element_with_div_sibling.snap b/internal/printer/__printer_js__/select_with_option_containing_element_with_div_sibling.snap
new file mode 100755
index 000000000..f8b51d8b2
--- /dev/null
+++ b/internal/printer/__printer_js__/select_with_option_containing_element_with_div_sibling.snap
@@ -0,0 +1,41 @@
+
+[TestPrinter/select_with_option_containing_element_with_div_sibling - 1]
+## Input
+
+```
+Orange
+```
+
+## Output
+
+```js
+import {
+ Fragment,
+ render as $$render,
+ createAstro as $$createAstro,
+ createComponent as $$createComponent,
+ renderComponent as $$renderComponent,
+ renderHead as $$renderHead,
+ maybeRenderHead as $$maybeRenderHead,
+ unescapeHTML as $$unescapeHTML,
+ renderSlot as $$renderSlot,
+ mergeSlots as $$mergeSlots,
+ addAttribute as $$addAttribute,
+ spreadAttributes as $$spreadAttributes,
+ defineStyleVars as $$defineStyleVars,
+ defineScriptVars as $$defineScriptVars,
+ renderTransition as $$renderTransition,
+ createTransitionScope as $$createTransitionScope,
+ renderScript as $$renderScript,
+ createMetadata as $$createMetadata
+} from "http://localhost:3000/";
+
+export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
+
+const $$Component = $$createComponent(($$result, $$props, $$slots) => {
+
+return $$render`${$$maybeRenderHead($$result)}Orange
`;
+}, undefined, undefined);
+export default $$Component;
+```
+---
diff --git a/internal/printer/printer_test.go b/internal/printer/printer_test.go
index fedea94a3..73d28744c 100644
--- a/internal/printer/printer_test.go
+++ b/internal/printer/printer_test.go
@@ -1234,19 +1234,19 @@ import { Container, Col, Row } from 'react-bootstrap';
source: `Default
Named
`,
},
{
- name: "Fragment with await",
+ name: "Fragment with await",
source: ` { await Promise.resolve("Awaited") } `,
},
{
- name: "Fragment shorthand with await",
+ name: "Fragment shorthand with await",
source: `<> { await Promise.resolve("Awaited") } >`,
},
{
- name: "Fragment wrapping link with awaited href",
+ name: "Fragment wrapping link with awaited href",
source: ``,
},
{
- name: "Component with await",
+ name: "Component with await",
source: ` { await Promise.resolve("Awaited") } `,
},
{
@@ -2092,6 +2092,26 @@ const meta = { title: 'My App' };
name: "namespace is preserved when inside an expression",
source: ``,
},
+ {
+ name: "select with option containing element",
+ source: ``,
+ },
+ {
+ name: "select with 2 options containing element",
+ source: ``,
+ },
+ {
+ name: "select with option containing element with div sibling",
+ source: `Orange
`,
+ },
+ {
+ name: "select with 2 options containing element with div sibling",
+ source: `Orange
`,
+ },
+ {
+ name: "select with option containing element and button containing selected content",
+ source: ``,
+ },
}
for _, tt := range tests {
if tt.only {