Fix Safari next/image error by excluding ?ts= cache-busting from script tags#92484
Open
lukesandberg wants to merge 2 commits intocanaryfrom
Open
Fix Safari next/image error by excluding ?ts= cache-busting from script tags#92484lukesandberg wants to merge 2 commits intocanaryfrom
lukesandberg wants to merge 2 commits intocanaryfrom
Conversation
…pt tags In Safari dev mode, the Pages Router adds ?ts=<timestamp> to all asset URLs as a workaround for WebKit preload caching (bugs.webkit.org/show_bug.cgi?id=187726). The Turbopack runtime reads this query string from the script's src attribute into ASSET_SUFFIX, which then leaks onto static asset URLs (images, fonts), causing next/image localPatterns validation to reject them. The ?ts= param is only needed for CSS resources (to bust Safari's preload cache and Firefox's stylesheet cache). Script tags don't need it — the WebKit bug affects <link rel="preload"> caching, not scripts themselves, and removing ?ts= from both the preload hint and the script tag keeps their URLs in sync. Introduce scriptAssetQueryString (containing only ?dpl= when applicable) and use it for all script-related tags, while CSS and font tags continue using the original assetQueryString with ?ts=. Fixes #92118 Co-Authored-By: Claude <noreply@anthropic.com>
Collaborator
Failing test suitesCommit: 5f5623a | About building and testing Next.js
Expand output● instant-nav-panel › should show loading skeleton during SPA navigation after clicking Start |
Collaborator
Stats from current PR✅ No significant changes detected📊 All Metrics📖 Metrics GlossaryDev Server Metrics:
Build Metrics:
Change Thresholds:
⚡ Dev Server
📦 Dev Server (Webpack) (Legacy)📦 Dev Server (Webpack)
⚡ Production Builds
📦 Production Builds (Webpack) (Legacy)📦 Production Builds (Webpack)
📦 Bundle SizesBundle Sizes⚡ TurbopackClient Main Bundles
Server Middleware
Build DetailsBuild Manifests
📦 WebpackClient Main Bundles
Polyfills
Pages
Server Edge SSR
Middleware
Build DetailsBuild Manifests
Build Cache
🔄 Shared (bundler-independent)Runtimes
📝 Changed Files (4 files)Files with changes:
View diffspages-turbo...ntime.dev.jsDiff too large to display pages-turbo...time.prod.jsDiff too large to display pages.runtime.dev.jsDiff too large to display pages.runtime.prod.jsDiff too large to display 📎 Tarball URL |
…outer Previously a separate scriptAssetQueryString was introduced to strip ?ts= from script tags. This refactors the approach more cleanly: assetQueryString (used by scripts) never includes ?ts=, while a new cssAssetQueryString (only used by CSS <link> and font <link> tags) carries the timestamp. This makes the invariant explicit at the source rather than maintaining two parallel query string paths. Co-Authored-By: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What?
In Safari dev mode (Pages Router + Turbopack), statically imported images fail with:
This introduces separate query string handling for script tags vs CSS/font tags in the Pages Router HTML rendering, so that the
?ts=Safari cache-busting parameter only appears on CSS and font resources — not on script tags.Why?
The Pages Router adds
?ts=<timestamp>to all asset URLs in dev mode for Safari as a workaround for WebKit bug #187726 (Safari caches<link rel="preload">resources forever, ignoring "Disable Cache" in DevTools).The Turbopack browser runtime function
getAssetSuffixFromScriptSrc()reads the query string from the currently-executing<script>tag and stores it asASSET_SUFFIX. This suffix is then appended to all exported static asset URLs, including images. Whennext/imagereceives a src like/_next/static/media/image.hash.png?ts=12345, it fails validation against the defaultlocalPatternsconfig ({ pathname: '**', search: '' }).The
?ts=param is only needed for CSS resources:<link rel="preload">caching, not script loading itselfdev-backend-dom.tsalready adds its own per-HMR-event?ts=for both Safari and Firefox independentlyThe original reason
?ts=was on<script>tags was to keep<link rel="preload" as="script">URLs in sync with<script src>URLs (avoiding double downloads). By removing?ts=from both the preload hints and the script tags, they still match.How?
scriptAssetQueryStringandscriptMutableAssetQueryStringfields toHtmlProps(only contain?dpl=<id>when applicable, never?ts=)render.tsxalongside the existingassetQueryString/mutableAssetQueryString_document.tsxwhere script-related tags (<script>,<link rel="preload" as="script">) use the newscriptAssetQueryString<link rel="stylesheet">,<link rel="preload" as="style">) and font (<link rel="preload" as="font">) tags continue using the originalassetQueryStringwith?ts=Fixes #92118