mirror of
https://github.com/cloudflare/vinext.git
synced 2026-05-09 08:25:34 +02:00
[PR #7] [MERGED] fix: add 'use client' to next/dynamic shim for App Router RSC compatibility #240
Labels
No labels
enhancement
enhancement
good first issue
help wanted
nextjs-tracking
nextjs-tracking
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
starred/vinext#240
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/cloudflare/vinext/pull/7
Author: @threepointone
Created: 2/24/2026
Status: ✅ Merged
Merged: 2/24/2026
Merged by: @southpolesteve
Base:
main← Head:fix/dynamic-ssr-false-use-client📝 Commits (1)
bd474c9fix: add 'use client' to next/dynamic shim for App Router RSC compatibility📊 Changes
6 files changed (+53 additions, -0 deletions)
View changed files
📝
packages/vinext/src/shims/dynamic.ts(+1 -0)📝
tests/e2e/app-router/nextjs-compat/dynamic.spec.ts(+22 -0)📝
tests/fixtures/app-basic/app/nextjs-compat/dynamic/dynamic-imports/dynamic-server.tsx(+2 -0)📝
tests/fixtures/app-basic/app/nextjs-compat/dynamic/named-export/page.tsx(+2 -0)➕
tests/fixtures/app-basic/app/nextjs-compat/dynamic/ssr-false-server/client-wrapper.tsx(+12 -0)➕
tests/fixtures/app-basic/app/nextjs-compat/dynamic/ssr-false-server/page.tsx(+14 -0)📄 Description
Problem
next/dynamicwithssr: falseproduces a blank page when used from the App Router with the Cloudflare Vite plugin. The dynamically imported component never loads on the client.Root cause
The
shims/dynamic.tsmodule wasn't marked as a client module. When a server component callsdynamic(), the RSC serializer executes the function on the server. Forssr: false, the server path returnsnull, which is serialized into the RSC payload and sent to the client as-is. The client never runs the mount-on-client code path.In Next.js's App Router,
next/dynamicresolves to a"use client"module (app-dynamic.tsx). The RSC serializer emits a client reference instead of executing the function inline.Fix
Added
"use client"to the top ofpackages/vinext/src/shims/dynamic.ts. This makes the dynamic shim a client module, matching Next.js behavior.Both
ssr: trueandssr: falsework correctly:ssr: true— SSR environment resolves the client reference and renders the component to HTML. Client hydrates. No behavior change.ssr: false— SSR rendersnull(viaisServercheck). Client hydrates,useEffectfires → lazy component loads.Test fixture updates
Existing test fixtures that called
dynamic()from server modules now include"use client"— this is required sincedynamic()is a client export. This matches Next.js's App Router behavior where you must calldynamic()from a client module.Added a new E2E test (
ssr:false from server component loads after hydration) with a server component page that imports a client wrapper usingdynamic()withssr: false.All 47 test files pass (1803 tests).
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.