fix(react-router): remove async/defer attributes during hydration to prevent warnings#6479
fix(react-router): remove async/defer attributes during hydration to prevent warnings#6479Kyujenius wants to merge 2 commits intoTanStack:mainfrom
Conversation
Strip async, defer, and src attributes from script tags during client-side hydration to match the server-rendered output and prevent React hydration mismatch warnings.
Adds unit tests to verify server output includes async/defer attributes, and e2e tests to verify no hydration warnings occur on the client.
📝 WalkthroughWalkthroughThis PR fixes a hydration mismatch issue triggered by async scripts. It modifies the client-side script placeholder to exclude src, async, and defer attributes while preserving them server-side, adds e2e tests to verify correct behavior, and includes a new example route demonstrating async and deferred script loading. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~15 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
My question is, why do we have to strip them and render a placeholder <script /> in the first place? |
Description
Fixes #6438
When using
asyncordeferattributes on script tags viauseHeadorScripts, React throws a hydration warning even ifsuppressHydrationWarningis used. This is because of how React handles hydration mismatches for specific attributes on script tags during streaming/suspense boundaries.This PR solves the root cause by stripping
async,defer, andsrcattributes from the script tag on the client-side only (during hydration).<script src="..." async />to ensure the browser loads it.<script />(viaAsset.tsx) that matches the server's hydration expectation for a controlled script tag, effectively preventing the mismatch warning.Solution
The
Assetcomponent now explicitly destructures and removes these attributes when!router.isServer:Verification
New tests added to cover these scenarios:
script-duplication.spec.ts): Verifies that no hydration warnings are logged to the console when loading a page withasyncscripts.Scripts.test.tsx): Verifies that the server output correctly includesasync/deferattributes (using regex to be resilient to attribute ordering).Summary by CodeRabbit
New Features
/async-scriptsroute demonstrating asynchronous and deferred script loading.Bug Fixes
asyncanddeferattributes without hydration warnings.Tests
✏️ Tip: You can customize this high-level summary in your review settings.