Thanks to visit codestin.com
Credit goes to github.com

Skip to content

fix(render): preserve script position in Astro.slots.render() output#15705

Open
umutkeltek wants to merge 1 commit intowithastro:mainfrom
umutkeltek:fix/script-position-slot-render
Open

fix(render): preserve script position in Astro.slots.render() output#15705
umutkeltek wants to merge 1 commit intowithastro:mainfrom
umutkeltek:fix/script-position-slot-render

Conversation

@umutkeltek
Copy link
Contributor

Summary

Fixes #15627

Scripts rendered through Astro.slots.render('default') with set:html were being hoisted to the top of the slot output instead of rendering at their original position. This regression was introduced by PR #15147, which changed renderScript() from returning a plain HTML string to returning a RenderInstruction object.

Root Cause

In renderSlotToString(), RenderInstruction objects (including scripts) were collected into a separate instructions array. When the SlotString was stringified in stringifyChunk(), all instructions were rendered before the content string — causing scripts to be hoisted to the top of the slot output regardless of their original position.

Fix

Uses positional placeholders (<!--astro:script:N-->) embedded in the content string at each script's original position. The actual script instructions are stored in a scriptInstructions map on SlotString. At stringification time, placeholders are replaced with the real script HTML.

This preserves:

  • Script position — the placeholder marks where the script should appear
  • Script deduplication — still goes through stringifyChunk which checks renderedScripts
  • Unused Fragment slot behavior — if a slot is unused, script instructions are never stringified (PR Fixes scripts not rendering with unused Fragment slots #15147's fix preserved)
  • Server island slot scripts — updated server-islands.ts to resolve script placeholders in island responses

Files Changed

  • packages/astro/src/runtime/server/render/slot.ts — Added scriptInstructions field to SlotString, script instructions now use positional placeholders in content string
  • packages/astro/src/runtime/server/render/common.ts — Replace script placeholders with stringified content during SlotString processing
  • packages/astro/src/runtime/server/render/server-islands.ts — Resolve script placeholders when serializing slot content for island responses

Test plan

  • New test: "Scripts rendered via Astro.slots.render preserve their position" — verifies script is inside <li>, not hoisted before <ol>
  • Existing test passes: "Scripts in Fragment slots are processed when another slot is unused"
  • Existing test passes: "includes script from slotted component in island response"
  • All 35 script + server-island tests pass
  • Build passes

…ithastro#15627)

Scripts rendered through Astro.slots.render('default') with set:html were
being hoisted to the top of the slot output because renderSlotToString()
collected script RenderInstructions into a separate instructions array,
and stringifyChunk() rendered all instructions before the content string.

This fix uses positional placeholders (<!--astro:script:N-->) embedded in
the content string at the script's original position, with the actual
script instructions stored in a separate scriptInstructions map on
SlotString. At stringification time, placeholders are replaced with the
real script HTML, preserving both original position and deferred
deduplication.

Also updated server-islands.ts to resolve script placeholders when
serializing slot content for island responses.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@changeset-bot
Copy link

changeset-bot bot commented Feb 28, 2026

🦋 Changeset detected

Latest commit: b5cde8a

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 the pkg: astro Related to the core `astro` package (scope) label Feb 28, 2026
@codspeed-hq
Copy link

codspeed-hq bot commented Feb 28, 2026

Merging this PR will improve performance by 10.85%

⚡ 1 improved benchmark
✅ 17 untouched benchmarks

Performance Changes

Mode Benchmark BASE HEAD Efficiency
Simulation Build: hybrid site (static + server) 8.8 s 7.9 s +10.85%

Comparing umutkeltek:fix/script-position-slot-render (b5cde8a) with main (830a267)

Open in CodSpeed

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

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

<script> location regression in Astro 5.16.9

1 participant