Server rendering
This guide will cover how to server render your React Native app using React Native for Web and React Navigation. We'll cover the following cases:
- Rendering the correct layout depending on the request URL
- Setting appropriate page metadata based on the focused screen
Pre-requisites¶
Before you follow the guide, make sure that your app already renders fine on server. To do that, you will need to ensure the following:
- All of the dependencies that you use are compiled before publishing to npm, so that you don't get syntax errors on Node.
- Node is configured to be able to
require
asset files such as images and fonts. You can try webpack-isomorphic-tools to do that. react-native
is aliased toreact-native-web
. You can do it with babel-plugin-module-resolver.
Note: Some of the libraries in React Navigation don't work well on Web, such as
@react-navigation/material-top-tabs
. SSR also doesn't work if you're using Expo libraries.
Rendering the app¶
First, let's take a look at an example of how you'd do server rendering with React Native Web without involving React Navigation:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
Here, ./src/App
is the file where you have AppRegistry.registerComponent('App', () => App)
.
If you're using React Navigation in your app, this will render the screens rendered by your home page. However, if you have configured links in your app, you'd want to render the correct screens for the request URL on server so that it matches what'll be rendered on the client.
We can use the ServerContainer
to do that by passing this info in the location
prop. For example, with Koa, you can use the path
and search
properties from the context argument:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
|
You may also want to set the correct document title and descriptions for search engines, open graph etc. To do that, you can pass a ref
to the container which will give you the current screen's options.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
|
Make sure that you have specified a title
option in your screens:
1 2 3 4 5 |
|
Handling 404 or other status codes¶
When rendering a screen for an invalid URL, we should also return a 404
status code from the server.
First, we need to create a context where we'll attach the status code. To do this, place the following code in a separate file that we will be importing on both the server and client:
1 2 3 4 5 |
|
Then, we need to use the context in our NotFound
screen. Here, we add a code
property with the value of 404
to signal that the screen was not found:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
You could also attach additional information in this object if you need to.
Next, we need to create a status object to pass in the context on our server. By default, we'll set the code
to 200
. Then pass the object in StatusCodeContext.Provider
which should wrap the element with ServerContainer
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
After we render the app with ReactDOMServer.renderToString
, the code
property of the status
object will be updated to be 404
if the NotFound
screen was rendered.
You can follow a similar approach for other status codes too, for example, 401
for unauthorized etc.
Summary¶
- Use the
location
prop onServerContainer
to render correct screens based on the incoming request. - Attach a
ref
to theServerContainer
get options for the current screen. - Use context to attach more information such as status code.