-
-
Notifications
You must be signed in to change notification settings - Fork 632
Description
Problem
When RSC is enabled (enable_rsc_support = true), the packs generator classifies any component without 'use client' as a server component and registers it via registerServerComponent(). If an interactive component (using hooks, class components, etc.) is missing 'use client', it crashes at runtime with vague error messages that don't point to the actual problem.
Error messages users see
Depending on the component type and failure path, users get one of these:
-
TypeError: require is not a function— ExecJS fallback after Node renderer crashes. This is the error shown in the browser/Rails logs. Completely unrelated to the actual cause. -
Rails context does not have server side RSC payload parameters— Only visible in the Node renderer log file. The guidance says "ensureenable_rsc_support = true" which is already set. Never mentions'use client'. -
Class extends value undefined is not a constructor or null— For class-based components. No indication of what to do.
None of these tell the user: "Your component uses client-side features but is missing the 'use client' directive."
How Next.js handles this
Next.js gives a clear build-time error:
"You're importing a component that needs useState. It only works in a Client Component but none of its parents are marked with
"use client", so they're Server Components by default."
This tells you what's wrong, why, and how to fix it.
Reproduction (Pro dummy app)
- Remove
'use client'fromreact_on_rails_pro/spec/dummy/client/app/ror-auto-load-components/HelloWorld.jsx - Run
bundle exec rake react_on_rails:generate_packs— HelloWorld moves fromReactOnRails.register()toregisterServerComponent() - Build webpack, start the Node renderer and Rails server
- Visit
/server_side_hello_world— crashes withClass extends value undefined is not a constructor or null
The root cause: packs_generator.rb (line 135) uses client_entrypoint? to check for 'use client'. Without the directive, any interactive component gets wrapped by wrapServerComponentRenderer, which expects RSC streaming context that doesn't exist for regular SSR renders.
Suggested improvements
-
Build-time detection: The RSCWebpackPlugin or packs generator could detect when a component registered via
registerServerComponentuses client-only APIs (hooks, class components, event handlers) and warn at build time. -
Better runtime error message: The
assertRailsContextWithServerStreamingCapabilitieserror could mention'use client'as a possible cause:"If this component uses hooks, event handlers, or other client-side features, add
'use client'at the top of the file." -
Documentation/tips: When RSC is enabled, warn users that existing interactive components need
'use client'at the top of the file. Without it, they'll be treated as server components and may crash at runtime.
Related
Discovered during work on PR #2284.