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';
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 on the second line of each of these examples.
Per Webpack Docs.
function 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: {
... // blah blah
SomeJsFile,
... // blah blah
},
Then you have this import:
import SomeJsFile from 'SomeJsFile';
function setResolve(builderConfig, webpackConfig) {
// Use a different resolution for Client and Server file
let variant;
if (builderConfig.serverRendering) {
variant = path.resolve(__dirname, "../bundles/variant/ClientOnly");
} else {
variant = path.resolve(__dirname, "../bundles/variant/serverOnly");
}
const resolve = {
alias: {
... // blah blah
variant
... // blah blah
},
b. Add different versions of the file to the bundles/variant/ClientOnly
and bundles/variant/ServerOnly
directories
import SomeJsFile from 'variant/SomeJsFile';
import AnotherJsFile from 'variant/AnotherJsFile';
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;
}