Hi, today I’d like to share some tips when you’re developing server-side rendered application with React.

Web API usage

Be careful when you use Web API(s) since they won’t work on server-side. These are common Web API we usually use:

Avoid using them on these lifecycles since they’re called during server render:

constructor

getDerivedStateFromProps

componentWillMount (deprecated)

You can do it safely in componentDidMount and componentDidUpdate lifecycle and any class methods that run after componentDidMount phase.

I assume we use either renderToString and renderToNodeStream API for server-side rendering. Pre-rendering libraries don’t count as doing SSR since client-only lifecycles still get executed

So, you might be thinking:

“But can I just check if window is available?”

Well, it depends, but don’t do this!

constructor(props) {

super(props)

this.state = {

data: typeof window !== 'undefined' ? 'client' : 'server'

}

} render()

return <div>{this.state.data}</div>

}

You will get the following warning on your browser console:

index.js:2178 Warning: Text content did not match. Server: "server" Client: "client"

So what’s wrong here? It’s because React expects the one rendered on the server should be the same with one rendered on client during hydration. It’s okay to use window type-checking before doing DOM access/operations but make sure it won’t affect rendering difference between client and server.

Okay, now you might be asking:

“But I need to render based on window/browser APIs…”

If you have some cases where you need to render based on DOM objects or Web APIs, then you need to render them after componentDidMount lifecycle, and on the server, you can render the placeholder (loading component, or just null )

constructor(props) {

super(props)

this.state = {

ssrDone: false

}

} componentDidMount() {

this.setState({ ssrDone: true, online: navigator.onLine })

} render() {

if(!this.state.ssrDone) {

return (

<div>loading...</div>

)

}

return <div>{this.state.online ? 'on' : 'off'}</div>

}

This is especially useful when you use non-SSR friendly 3rd party React components (which will throw errors during server render). The official React doc also shows the same technique (the name is “two-pass rendering”), but it also states:

“Note that this approach will make your components slower because they have to render twice, so use it with caution.”

Make sure you encapsulate these DOM-dependent components so the double rendering will only happen to them, not the whole page.

Hydration warning

If you got some hydration warnings and want to ignore them for some reason, you can use suppressHydrationWarning prop on the element.

Bonus