Skip to content

if head contains a server:defer-ed component the server-island wipes all other head elements after a ClientRouter page transition #17105

Description

@Gr3q

Astro Info

Astro                    v6.4.2
Node                     v24.15.0
System                   macOS (arm64)
Package Manager          pnpm
Output                   static
Adapter                  @astrojs/node
Integrations             @astrojs/react
                         @astrojs/mdx
                         @astroscope/boot (v0.6.10)
                         astro-icon
                         @astrojs/sitemap
                         @astrojs/markdoc (v1.0.4)
                         astro:md
                         @astrojs/svelte (v8.1.1)

If this issue only occurs in one browser, which browser is a problem?

No response

Describe the Bug

I have some global stylesheets included (and preloaded) in the head of every page (tailwind theme, css layers etc). After adding ClientRouter to the head, on page transitions all of those styles were gone.

After talking to my robot this is what it identified:

Root cause confirmed. Let me read Astro's server-island replacer (bottom of that file) carefully — it walks previousSibling backward removing nodes until it hits the comment marker. Let me verify the components and the mechanism, then fix.

The mechanism is now clear:

  • DataDog and GTM are server:defer server islands placed in <head>.
  • Astro's ClientRouter head swap (swapHeadElements) only moves element children (document.head.children) — it does not carry over the HTML comment delimiters (<!--[if astro]>server-island-start<![endif]-->) that bound each island.
  • After navigation, the island's <script> re-runs replaceServerIsland, which deletes every previousSibling until it finds that comment marker. Since the marker was lost in the head swap, it walks back and deletes the preceding global stylesheets (global.css, layers.css).
    This is why only the shared global s vanish, and only after navigation. Let me confirm the components are just scripts, then move them to the <body> (where the whole element — comments included — is swapped intact).

I've confirmed it that by moving the server:deferred components to the body page transitions work fully.

What's the expected result?

Pages should include all the same head tags as the previous page even with server:deferred components.

Link to Minimal Reproducible Example

https://stackblitz.com/edit/github-xpcko3w4?file=src%2Flayouts%2FLayout.astro

Participation

  • I am willing to submit a pull request for this issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    - P3: minor bugAn edge case that only affects very specific usage (priority)pkg: astroRelated to the core `astro` package (scope)triage: fix rejectedReporter says the proposed fix does not work

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions