Luke
Luke

Reputation: 1830

Failing to use document object inside of react component. "document is not defined" error

I've got some browser sniffing code that I'm using inside of a react component

import React, { useState } from 'react'

const SomeComponent = ({props}) => {
  const isIE = document.documentMode;
  return (
    <div>
      Some browser sniffing code here.
    </div>
  )
}

I'm getting this error on build, though, "document is not defined"

It also fails when I try it like this

import React, { useState } from 'react'

const isIE = document.documentMode;

const SomeComponent = ({props}) => {
  console.log(isIe)
  return (
    <div>
      Some browser sniffing code here.
    </div>
  )
}

I'm running from a create-react-library component in a next server.

What's the best way to access the document object inside of react?

I've seen some browser sniffing react code here but it didn't work cause I got the errors on build Browser Detection in ReactJS

Upvotes: 0

Views: 1317

Answers (2)

bcjohn
bcjohn

Reputation: 2523

Next.js is a SSR framework, your code will run both on server-side and client side. Window would be not defined when running on server-side. If you want to get property from window, you could try these way.

  1. Get the window when you need

    if (typeof window !== 'undefined') {
       console.log(window.document)
    }
    

  1. In some specific situation, you need to run your component only on client side. In that case, you could using dynamic.

    components/ClientSideComponent

    const ClientSideComponent = props => {
        // You could get window directly in this component 
        console.log(window.document)
        return (
          <div>
             run your code only on client side
          </div>
        )
    }
    

    pages/index

    import dynamic from 'next/dynamic';
    const ClientSideComponent = dynamic(() => import('../components/ClientSideComponent'), {
        ssr: false,
    });
    
    const HomePage = props => {
        return <ClientSideComponent />
    }
    

Upvotes: 1

hangindev.com
hangindev.com

Reputation: 4873

When you are using Next.js, you should be aware that some of your code will be run in the server-side where window, document and other browser specific APIs will be not available.

Since useEffect hook only runs in the client-side, you can use it together with useState to achieve your goal:

import React, { useState, useEffect } from "react";

const SomeComponent = ({ props }) => {
  const [isIE, setIsIE] = useState(false);
  useEffect(() => {
    setIsIE(document.documentMode);
  }, []);
  if (!isIE) return null;
  return <div>Some browser sniffing code here.</div>;
};

Upvotes: 1

Related Questions