nextjs - ✅(Solved) Fix Statically imported image in Next 16.2 (Pages Router) breaks ‎`next dev` in Safari 26.4 [2 pull requests, 10 comments, 6 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
vercel/next.js#92118Fetched 2026-04-08 01:51:53
View on GitHub
Comments
10
Participants
6
Timeline
27
Reactions
1
Author
Timeline (top)
commented ×10subscribed ×6mentioned ×5labeled ×3

Error Message

  1. The page immediately crashes with the runtime error:

Runtime Error In Safari 26.4, a statically imported image used with the Pages Router in Next 16.2.1-canary.13 crashes the page in development with an error about a query string not being configured in ‎images.localPatterns. The same code runs without issue in Chrome and Firefox.

PR fix notes

PR #92484: Scope Safari ?ts= cache-buster to CSS/font assets only (Pages Router)

Description (problem / solution / changelog)

What?

Refactors the Safari ?ts= cache-busting workaround in the Pages Router so it only appears on CSS and font URLs, not on script tags or script preload links.

Why?

The ?ts= timestamp was originally added to all preloaded assets as a workaround for a Safari caching bug (see #5860). When it appears on <script> tags, the Turbopack runtime's getAssetSuffixFromScriptSrc() reads the executing script's query string and infers it as the ASSET_SUFFIX, which then leaks onto all static asset URLs — including images. This causes next/image validation errors because the image URL gets an unexpected ?ts= parameter.

Fixes #92118

How?

Instead of maintaining parallel assetQueryString (with ?ts=) and scriptAssetQueryString (without ?ts=) paths, this PR:

  1. assetQueryString carries only the deployment token (?dpl=...) and is used for all script-related URLs (script tags, script preloads)
  2. safariCacheBuster is a new, separate field (?ts=<timestamp> or "") that is only combined with assetQueryString at the 3 CSS/font URL sites via a joinQueryStrings() helper
  3. Removes the scriptAssetQueryString / scriptMutableAssetQueryString / cssAssetQueryString fields entirely

The Safari cache-buster is computed the same way as before (dev server only, Safari user-agent check) — it just no longer contaminates the base query string.

Test plan

  • Updated existing test in test/e2e/app-document/rendering.test.ts to assert ?ts= appears only on <link rel="preload" as="style"> and <link rel="preload" as="font">, and does NOT appear on <script> or <link rel="preload" as="script">
  • pnpm --filter=next types passes
<!-- NEXT_JS_LLM_PR -->

Changed files

  • packages/next/src/pages/_document.tsx (modified, +5/-5)
  • packages/next/src/server/render.tsx (modified, +29/-18)
  • packages/next/src/shared/lib/html-context.shared-runtime.ts (modified, +13/-0)
  • test/e2e/app-document/rendering.test.ts (modified, +21/-5)
  • turbopack/crates/turbo-tasks-backend/src/backend/storage.rs (modified, +3/-0)

PR #92580: Scope Safari ?ts= cache-buster to CSS/font assets only (Pages Router)

Description (problem / solution / changelog)

What?

Refactors the Safari ?ts= cache-busting workaround in the Pages Router so it only appears on CSS and font URLs, not on script tags or script preload links.

Why?

The ?ts= timestamp was originally added to all preloaded assets as a workaround for a Safari caching bug (see #5860). When it appears on <script> tags, the Turbopack runtime's getAssetSuffixFromScriptSrc() reads the executing script's query string and infers it as the ASSET_SUFFIX, which then leaks onto all static asset URLs — including images. This causes next/image validation errors because the image URL gets an unexpected ?ts= parameter.

Fixes #92118

How?

Instead of maintaining parallel assetQueryString (with ?ts=) and scriptAssetQueryString (without ?ts=) paths, this PR:

  1. assetQueryString carries only the deployment token (?dpl=...) and is used for all script-related URLs (script tags, script preloads)
  2. safariCacheBuster is a new, separate field (?ts=<timestamp> or "") that is only combined with assetQueryString at the 3 CSS/font URL sites via a joinQueryStrings() helper
  3. Removes the scriptAssetQueryString / scriptMutableAssetQueryString / cssAssetQueryString fields entirely

The Safari cache-buster is computed the same way as before (dev server only, Safari user-agent check) — it just no longer contaminates the base query string.

Test plan

  • Updated existing test in test/e2e/app-document/rendering.test.ts to assert ?ts= appears only on <link rel="preload" as="style"> and <link rel="preload" as="font">, and does NOT appear on <script> or <link rel="preload" as="script">
  • pnpm --filter=next types passes
<!-- NEXT_JS_LLM_PR -->

Changed files

  • packages/next/src/pages/_document.tsx (modified, +5/-5)
  • packages/next/src/server/render-result.ts (modified, +0/-2)
  • packages/next/src/server/render.tsx (modified, +35/-30)
  • packages/next/src/shared/lib/html-context.shared-runtime.ts (modified, +5/-0)
  • test/e2e/app-document/rendering.test.ts (modified, +21/-5)

Code Example

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 24.6.0: Fri Feb 27 19:30:16 PST 2026; root:xnu-11417.140.69.709.8~1/RELEASE_ARM64_T8112
  Available memory (MB): 24576
  Available CPU cores: 8
Binaries:
  Node: 22.22.0
  npm: 11.11.0
  Yarn: 1.22.22
  pnpm: 10.33.0
Relevant Packages:
  next: 16.2.1-canary.13 // Latest available version is detected (16.2.1-canary.13).
  eslint-config-next: N/A
  react: 19.2.4
  react-dom: 19.2.4
  typescript: 5.9.3
Next.js Config:
  output: N/A
RAW_BUFFERClick to expand / collapse

Link to the code that reproduces this issue

https://github.com/lsvs/next-16.2-statically-imported-image-bug-safari-reproduction-pages

To Reproduce

  1. Start the app in development mode with ‎next dev.
  2. Open the app in Safari 26.4 on macOS Sequoia.
  3. The page immediately crashes with the runtime error:

    Runtime Error Image with src "/_next/static/media/image.3_pmqoemjixc0.png?ts=..." is using a query string which is not configured in images.localPatterns.

Current vs. Expected behavior

Current behavior:

In Safari 26.4, a statically imported image used with the Pages Router in Next 16.2.1-canary.13 crashes the page in development with an error about a query string not being configured in ‎images.localPatterns. The same code runs without issue in Chrome and Firefox.

Expected behavior:

A statically imported image should work out of the box with the Pages Router in development, without requiring any ‎images.localPatterns configuration, and should behave consistently across browsers (Safari, Chrome, Firefox).

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 24.6.0: Fri Feb 27 19:30:16 PST 2026; root:xnu-11417.140.69.709.8~1/RELEASE_ARM64_T8112
  Available memory (MB): 24576
  Available CPU cores: 8
Binaries:
  Node: 22.22.0
  npm: 11.11.0
  Yarn: 1.22.22
  pnpm: 10.33.0
Relevant Packages:
  next: 16.2.1-canary.13 // Latest available version is detected (16.2.1-canary.13).
  eslint-config-next: N/A
  react: 19.2.4
  react-dom: 19.2.4
  typescript: 5.9.3
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

Image (next/image), Pages Router

Which stage(s) are affected? (Select all that apply)

next dev (local)

Additional context

I tested the reproduction against:

  • 16.1.7 → works as expected
  • 16.2.x (including ‎16.2.1-canary.13) → bug is present

This appears to be a regression introduced between 16.1.7 and 16.2.x.

  • The issue is reproducible locally on macOS Sequoia.
  • It only happens in Safari; Chrome and Firefox work fine with the same dev server and code.
  • The reproduction uses a statically imported image in a Pages Router page without additional ‎next.config.js image configuration.

extent analysis

Fix Plan

To resolve the issue with statically imported images in Safari using Next 16.2.1-canary.13, you can try the following steps:

  • Update next.config.js to include a configuration for images.localPatterns to allow query strings.
  • Alternatively, you can disable static image imports for Safari or use a different image loading approach.

Here's an example of how you can configure images.localPatterns in next.config.js:

module.exports = {
  //... other configurations ...
  images: {
    localPatterns: [
      {
        pathname: '/_next/static/media/**',
      },
    ],
  },
}

Or, you can use the next/image component with the loader prop set to 'default' to bypass the static image import issue:

import Image from 'next/image';

function MyPage() {
  return (
    <Image
      src="/_next/static/media/image.3_pmqoemjixc0.png"
      loader={'default'}
      alt="My Image"
    />
  );
}

Verification

To verify that the fix worked, start the app in development mode with next dev and open it in Safari 26.4 on macOS Sequoia. The page should no longer crash with the runtime error, and the image should be displayed correctly.

Extra Tips

  • Make sure to update next.config.js and restart the development server after making changes.
  • If you're using a custom next.config.js file, ensure that the images.localPatterns configuration is correctly merged with the default configurations.
  • Consider using a polyfill or a different image loading library if you're experiencing issues with static image imports in Safari.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

nextjs - ✅(Solved) Fix Statically imported image in Next 16.2 (Pages Router) breaks ‎`next dev` in Safari 26.4 [2 pull requests, 10 comments, 6 participants]