Skip to content

fix: prevent script dedup inside <template>#15980

Open
seroperson wants to merge 1 commit intowithastro:mainfrom
seroperson:i15389-template-script-dedup
Open

fix: prevent script dedup inside <template>#15980
seroperson wants to merge 1 commit intowithastro:mainfrom
seroperson:i15389-template-script-dedup

Conversation

@seroperson
Copy link

@seroperson seroperson commented Mar 18, 2026

Closes #15389

When a component with a script was first used inside a <template>, Astro's deduplication prevented the script from rendering outside the template, breaking non-template instances. This PR makes such scripts are not deduplicated. Should be merged after withastro/compiler#1156.

Changes

  • Adds templateEnter / templateExit functions to be inlined by compiler inside of <template> tags. These functions add instructions that track <template> nesting depth during rendering.
  • stringifyChunk skips dedup for scripts when templateDepth > 0. The script still renders inside the template but is also rendered outside for non-template instances.

Testing

Added astro-script-template-dedup integration test with four cases:

  • Component used inside <template> first, then outside: verifies script appears in both places
  • Component used outside first, then inside: verifies normal dedup still works
  • Two components outside, then inside: verifies normal dedup still works x2
  • Nested <template> elements: verifies depth tracking handles nesting

Docs

Docs aren't required as it's a bugfix.

@changeset-bot
Copy link

changeset-bot bot commented Mar 18, 2026

🦋 Changeset detected

Latest commit: 6202b78

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions github-actions bot added pkg: astro Related to the core `astro` package (scope) docs pr labels Mar 18, 2026
@seroperson seroperson force-pushed the i15389-template-script-dedup branch 2 times, most recently from 8a2e551 to a11ac94 Compare March 18, 2026 12:07
@codspeed-hq
Copy link

codspeed-hq bot commented Mar 18, 2026

Merging this PR will not alter performance

✅ 18 untouched benchmarks


Comparing seroperson:i15389-template-script-dedup (6202b78) with main (3e7a9d5)

Open in CodSpeed

@seroperson seroperson force-pushed the i15389-template-script-dedup branch 2 times, most recently from 866a50e to 949a1e1 Compare March 18, 2026 12:49
Copy link
Contributor

@matthewp matthewp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a very expensive change, for something that is a bit of a corner case. I don't want to make this change this way. Will explain an alternative approach in a comment.

@matthewp
Copy link
Contributor

Basically we need to know that we are "inside of a template" in order to maybe not emit the script. I think that's really only possible through a compiler change.

If you have that, you would know when you've exited all possible templates and then could emit the script. cc @Princesseuh

@seroperson
Copy link
Author

seroperson commented Mar 19, 2026

@matthewp Thank you for the review! Oh, I wasn't aware about such ability at all. Yea, compiler-based approach looks much better.

I filled the PR to compiler and did necessary changes here to support it. Well, then waiting compiler to be merged and then I'll update the version here.

P.S. I actually "moved" this render instruction to be inlined by compiler, so logic within this PR left mostly unchanged (except placing instructions of course).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs pr pkg: astro Related to the core `astro` package (scope)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Custom web components wrapped in <template> prevent other instances from initialising

2 participants