Link to the code that reproduces this issue
https://github.com/AriajSarkar/nextjs-webview-hydration-repro
To Reproduce
- Create a Next.js App Router project with
output: "export" and assetPrefix pointing to a network IP
- Load the app in a WebView from a cross-origin context (e.g., Tauri v2 Android dev mode, where the WebView loads from
http://192.168.x.x:3000 while the dev server runs on 0.0.0.0:3000)
- Observe that on Next.js 16.0.10, React hydrates correctly —
useEffect fires, onClick handlers work, HMR may fail but the app is interactive
- Upgrade to Next.js 16.2.6 — React never hydrates. The server-rendered HTML displays, but no client-side JavaScript takes effect
Minimal next.config.ts:
const internalHost = process.env.TAURI_DEV_HOST || "localhost";
const nextConfig = {
output: "export",
images: { unoptimized: true },
assetPrefix: `http://${internalHost}:3000`,
};
export default nextConfig;
Minimal page.tsx:
"use client";
import { useEffect, useState } from "react";
export default function Home() {
const [hydrated, setHydrated] = useState(false);
useEffect(() => {
console.log("React hydrated!");
setHydrated(true);
}, []);
return (
<div>
<p>{hydrated ? "✅ Hydrated" : "⏳ Waiting..."}</p>
<button onClick={() => alert("clicked!")}>Click me</button>
</div>
);
}
Current vs. Expected behavior
Expected Behavior
React should hydrate and become interactive even when the HMR WebSocket connection fails (cross-origin context). The initial page load and hydration should not depend on a successful HMR WebSocket handshake. This was the behavior in Next.js 16.0.10.
Actual Behavior
On Next.js 16.2.6, Turbopack's module loader appears to get stuck waiting for the HMR WebSocket connection. Since the connection cannot be established from the cross-origin WebView, React's client-side code never executes, and the page remains a static HTML shell with no interactivity.
Provide environment information
Operating System:
Platform: win32
Arch: x64
Version: Windows 11 Home Single Language
Available memory (MB): 16069
Available CPU cores: 16
Binaries:
Node: 25.9.0 // nvm-version
npm: 11.12.1
Yarn: N/A
pnpm: 10.19.0
Relevant Packages:
next: 16.0.10 // There is a newer version (16.2.6) available, upgrade recommended!
eslint-config-next: N/A
react: 19.2.6
react-dom: 19.2.6
typescript: 5.9.3
Which area(s) are affected? (Select all that apply)
Turbopack
Which stage(s) are affected? (Select all that apply)
next dev (local)
Additional context
When running next dev with Turbopack (default in Next.js 16) and loading the app inside a cross-origin Android WebView (via Tauri v2), React never hydrates on Next.js 16.2.6. The same setup works perfectly on 16.0.10.
What happens:
- Server-rendered HTML appears in the WebView ✅
- The React runtime chunk loads (React DevTools suggestion message appears in
Tauri/Console logcat) ✅
useEffect never fires ❌
onClick handlers never attach ❌ — buttons are visible but dead
- Native HTML elements (textarea) still accept input because they don't require React
- No JavaScript errors appear in the WebView console — the failure is completely silent
Evidence from adb logcat:
# This appears (React runtime loaded):
I Tauri/Console: File: http://192.168.1.7:3000/_next/static/chunks/073a_next_dist_....js
Msg: %cDownload the React DevTools...
# This NEVER appears (useEffect never fires):
# [expected] I Tauri/Console: ... Msg: React hydrated!
Context:
- The WebView loads from
http://192.168.1.7:3000 (network IP)
- The dev server listens on
0.0.0.0:3000
assetPrefix is set to http://192.168.1.7:3000
- The HMR WebSocket likely fails to connect (cross-origin), but on 16.0.10 this doesn't prevent hydration — React still mounts and becomes interactive
- On 16.2.6, the Turbopack module loader appears to block on the failed WebSocket connection, preventing client-side JavaScript from executing
Comparison with working project:
I have another project (Tin) using the exact same Tauri + Next.js + App Router + output: "export" setup but pinned to Next.js 16.0.10. It works perfectly in Android dev mode — React hydrates, events work, everything is interactive. The only significant difference is the Next.js version.
|
Working (Tin) |
Broken (A4Chat) |
| Next.js |
16.0.10 |
16.2.6 |
| React |
19.2.1 |
19.2.6 |
output |
"export" |
"export" |
assetPrefix |
http://${ip}:3000 |
http://${ip}:3000 |
| Hydration |
✅ Works |
❌ Silent failure |
Link to the code that reproduces this issue
https://github.com/AriajSarkar/nextjs-webview-hydration-repro
To Reproduce
output: "export"andassetPrefixpointing to a network IPhttp://192.168.x.x:3000while the dev server runs on0.0.0.0:3000)useEffectfires,onClickhandlers work, HMR may fail but the app is interactiveMinimal
next.config.ts:Minimal
page.tsx:Current vs. Expected behavior
Expected Behavior
React should hydrate and become interactive even when the HMR WebSocket connection fails (cross-origin context). The initial page load and hydration should not depend on a successful HMR WebSocket handshake. This was the behavior in Next.js 16.0.10.
Actual Behavior
On Next.js 16.2.6, Turbopack's module loader appears to get stuck waiting for the HMR WebSocket connection. Since the connection cannot be established from the cross-origin WebView, React's client-side code never executes, and the page remains a static HTML shell with no interactivity.
Provide environment information
Operating System: Platform: win32 Arch: x64 Version: Windows 11 Home Single Language Available memory (MB): 16069 Available CPU cores: 16 Binaries: Node: 25.9.0 // nvm-version npm: 11.12.1 Yarn: N/A pnpm: 10.19.0 Relevant Packages: next: 16.0.10 // There is a newer version (16.2.6) available, upgrade recommended! eslint-config-next: N/A react: 19.2.6 react-dom: 19.2.6 typescript: 5.9.3Which area(s) are affected? (Select all that apply)
Turbopack
Which stage(s) are affected? (Select all that apply)
next dev (local)
Additional context
When running
next devwith Turbopack (default in Next.js 16) and loading the app inside a cross-origin Android WebView (via Tauri v2), React never hydrates on Next.js 16.2.6. The same setup works perfectly on 16.0.10.What happens:
Tauri/Consolelogcat) ✅useEffectnever fires ❌onClickhandlers never attach ❌ — buttons are visible but deadEvidence from
adb logcat:Context:
http://192.168.1.7:3000(network IP)0.0.0.0:3000assetPrefixis set tohttp://192.168.1.7:3000Comparison with working project:
I have another project (Tin) using the exact same Tauri + Next.js + App Router +
output: "export"setup but pinned to Next.js 16.0.10. It works perfectly in Android dev mode — React hydrates, events work, everything is interactive. The only significant difference is the Next.js version.output"export""export"assetPrefixhttp://${ip}:3000http://${ip}:3000