Skip to content

AJShippify/isomorphic-relay

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

28 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Isomorphic React Relay npm version

Adds server side rendering support to React Relay.

If you are using react-router-relay, then you might also be interested in isomorphic-relay-router, which uses isomorphic-relay.

Acknowledgments

Thanks to @voideanvalue for the information that helped create the initial version this project. I also thanks @josephsavona for valuable advices that helped improve it.

Installation

npm install -S isomorphic-relay

How to use

Make sure isomorphic-relay module is loaded before react-relay on the server, because isomorphic-relay includes a hack to prevent "self is not defined" error (see facebook/fbjs#47):

// First load isomorphic-relay:
import IsomorphicRelay from 'isomorphic-relay';

// And only then load react-relay:
import Relay from 'react-relay';

Don't forget to inject a network layer to Relay on the server. And if you are using Relay.DefaultNetworkLayer, specify the full url to the GraphQL endpoint:

const GRAPHQL_URL = `http://localhost:8080/graphql`;

Relay.injectNetworkLayer(new Relay.DefaultNetworkLayer(GRAPHQL_URL));

Inject a no-op batching strategy into the Relay change emitter, but only on the server:

import RelayStoreData from 'react-relay/lib/RelayStoreData';

RelayStoreData.getDefaultInstance().getChangeEmitter().injectBatchingStrategy(() => {});

When processing a request on the server, prepare the data using IsomorphicRelay.prepareData, then render React using IsomorphicRelay.RootContainer in place of Relay.RootContainer, and send the React output along with the data to the client:

app.get('/', (req, res, next) => {
  const rootContainerProps = {
    Component: MyContainer,
    route: new MyRoute(),
  };

  IsomorphicRelay.prepareData(rootContainerProps).then(data => {
    const reactOutput = ReactDOMServer.renderToString(
      <IsomorphicRelay.RootContainer {...rootContainerProps} />
    );

    res.render('index.ejs', {
      preloadedData: JSON.stringify(data),
      reactOutput
    });
  }, next);
});

On page load in the browser, inject the prepared data to the Relay store using IsomorphicRelay.injectPreparedData, then render React using IsomorphicRelay.RootContainer in place of Relay.RootContainer:

const data = JSON.parse(document.getElementById('preloadedData').textContent);

IsomorphicRelay.injectPreparedData(data);

const rootElement = document.getElementById('root');

// use the same rootContainerProps as on the server
ReactDOM.render(<IsomorphicRelay.RootContainer {...rootContainerProps} />, rootElement);

Example

See here.

About

Adds server side rendering support to React Relay

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • JavaScript 100.0%