docs/oss/building-features/how-to-use-different-files-for-client-and-server-rendering.md
[!NOTE] React Server Components (RSC) users: With RSC, server components run exclusively on the server and client components handle browser interactivity. This component model eliminates the need for separate
.server/.clientfile variants. Using file variants with RSC can cause issues — see the auto-bundling troubleshooting guide for details.
There are 3 main ways to use different code for server vs. client rendering.
Many projects will have different entry points for client and server rendering. This only works for a top-level entry point such as the entry point for a React Router app component.
Your Client Entry can look like this:
import ReactOnRails from 'react-on-rails/client';
import App from './ClientApp';
ReactOnRails.register({ App });
So your Server Entry can look like:
import ReactOnRails from 'react-on-rails';
import App from './ServerApp';
ReactOnRails.register({ App });
Note that the only difference is in the imports.
Per Webpack Docs.
webpack/set-resolve.js to have a different resolution for the exact filefunction setResolve(builderConfig, webpackConfig) {
// Use a different resolution for Client and Server file
let SomeJsFile;
if (builderConfig.serverRendering) {
SomeJsFile = path.resolve(__dirname, "../bundles/SomeJsFileServer");
} else {
SomeJsFile = path.resolve(__dirname, "../bundles/SomeJsFileClient");
}
const resolve = {
alias: {
// ... other aliases
SomeJsFile,
// ... other aliases
},
Then you have this import:
import SomeJsFile from 'SomeJsFile';
webpack/set-resolve.js to have something likefunction setResolve(builderConfig, webpackConfig) {
// Use a different resolution for Client and Server file
let variant;
if (builderConfig.serverRendering) {
variant = path.resolve(__dirname, "../bundles/variant/ServerOnly");
} else {
variant = path.resolve(__dirname, "../bundles/variant/ClientOnly");
}
const resolve = {
alias: {
// ... other aliases
variant,
// ... other aliases
},
bundles/variant/ClientOnly and bundles/variant/ServerOnly directoriesvariant in import in a file that can be used both for client and server renderingimport SomeJsFile from 'variant/SomeJsFile';
import AnotherJsFile from 'variant/AnotherJsFile';
window is defined.This is probably the ugliest and hackiest way to do this, but it's quick! Essentially you wrap code that cannot execute server side in a conditional:
if (window) {
// window should be falsy on the server side
doSomethingClientOnly();
// or do an import
const foobar = require('foobar').default;
}