In React, how do I detect if my component is rendering from the client or the server?

I'm building a isomorphic application, but I'm using a third-party component that only renders on the client. So, particularly for this component, I need to only render it when I'm rendering in the client.

How do I detect if I'm at the client or at the server? I'm looking for something like isClient() or isServer().


Internally, React uses a utility called ExecutionEnvironment for this. It implements a few useful properties like canUseDOM and canUseEventListeners. The solution is essentially just what's suggested here though.

The implementation of canUseDOM

var canUseDOM = !!(
  (typeof window !== 'undefined' &&
  window.document && window.document.createElement)
);

I use this in my application like this

var ExecutionEnvironment = require('react/node_modules/fbjs/lib/ExecutionEnvironment');
...
render() {
  <div>{ ExecutionEnvironment.canUseDOM ? this.renderMyComponent() : null }</div>
}

EDIT This is an undocumented feature that shouldn't be used directly. Its location will likely change from version to version. I shared this as a way of saying "this is the best you can do" by showing what the Facebook team uses internally. You may want to copy this code (it's tiny) into your own project, so you don't have to worry about keeping up with its location from version to version or potential breaking changes.

ANOTHER EDIT Someone created an npm package for this code. I suggest using that.

npm install exenv --save

You can use reacts lifecyle events (e.g.: componentDidMount) to detect server/client side rendering.

Examples

As Hook

import { useState, useEffect } from 'react'

function useIsServer () {
  const [isServer, setIsServer] = useState(true)
  useEffect(() => {
    setIsServer(false)
  }, [])
  return isServer
}

Usage

See below (Functional Component)

As Functional Component

import useIsServer from './above'

function ServerOnly ({ children = null, onClient = null }) {
  const isServer = useIsServer()
  return isServer
    ? children
    : onClient
}

Usage

<ServerOnly
  children='This String was rendered on the server'
  onClient='This String was rendered on the client'
/>

As Class Component

class ServerOnly extends React.Component {
  constructor (props) {
    super(props)
    this.state = {
      isServer: true
    }
  }

  componentDidMount() {
    this.setState({
      isServer: false
    })
  }

  render () {
    const { isServer } = this.state
    const { children, onClient } = this.props
    return isServer
      ? children
      : onClient
  }
}

Usage

<ServerOnly
  children='This String was rendered on the server'
  onClient='This String was rendered on the client'
/>