Skip to content

useEffect callbacks never fire after RSC hydration on Cloudflare Workers (App Router, "use client" pages) #695

@Hitesh-Sisara

Description

@Hitesh-Sisara

Description

useEffect callbacks in "use client" components never execute after RSC hydration when deployed to Cloudflare Workers. Components render correctly (JSX tree appears in DOM, React fiber tree is present), but React's passive effects are never flushed. Any client-side data fetching or side effects inside useEffect simply don't run.

Environment

  • vinext: 0.0.35 (also reproduced on 0.0.27)
  • vite: 8.0.3
  • @cloudflare/vite-plugin: 1.30.1
  • @vitejs/plugin-rsc: 0.5.21
  • react / react-dom: 19.2.4
  • next: 16.0.10
  • Deployment: Cloudflare Workers via wrangler deploy

vite.config.ts

import { defineConfig } from "vite";
import vinext from "vinext";
import { cloudflare } from "@cloudflare/vite-plugin";

export default defineConfig({
  plugins: [
    vinext(),
    cloudflare({
      viteEnvironment: { name: "rsc", childEnvironments: ["ssr"] },
    }),
  ],
});

Reproduction

Every page in our app is a "use client" component that fetches data via useEffect. Minimal example:

"use client";
import { useState, useEffect } from "react";

export default function MyPage() {
  const [data, setData] = useState([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    console.log("useEffect fired"); // Never executes
    fetch("https://api.example.com/data")
      .then(res => res.json())
      .then(result => { setData(result.items); setLoading(false); });
  }, []);

  if (loading) return <div>Loading...</div>;
  return <div>{data.length} items</div>;
}

What happens

  1. Page loads via RSC stream — component tree renders correctly in DOM
  2. useEffect callback never fires — no console.log, no fetch, no state update
  3. Page stays stuck showing initial state (empty data)
  4. Chrome DevTools Network tab shows zero API calls to backend after page load
  5. No console errors or warnings

Evidence from Chrome DevTools

We inspected the live deployed site extensively:

  • JS bundles load correctlyworker-entry-*.js, framework-*.js, index-*.js all return 200
  • RSC stream works.rsc responses contain correct component references (I["hash",[],...])
  • React fiber tree exists__reactFiber$* present on DOM elements, component state initialized
  • Component state shows defaults — hooks linked list shows initial values, never updated
  • API is reachable — manually calling fetch() from console returns 200 with data
  • No useEffect execution at all — effects registered in fiber tree (effect.tag === 8) but create() never called

What we tried

  • Upgrading from vinext 0.0.27 to 0.0.35 — same behavior
  • Adding auth state as useEffect dependency — no effect since initial useEffect never fires
  • vinext build completes successfully with all 20 routes detected
  • vinext check reports 94% compatibility with no blocking issues
  • Works perfectly with vinext dev locally — issue only in production on Workers

Expected behavior

useEffect callbacks should execute after RSC hydration completes, matching standard Next.js behavior.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions