I am using a customer express server with Next.js. It's running within a container. I am doing an http request with isomorphic-fetch to get data for my render. I'd like to do localhost when running on server and mysite.com when running on client. Not sure the best way to accomplish this. I can do it hackily by doing const isServer = typeof window === 'undefined' but that seems pretty bad. 
 
    
    - 110,530
- 99
- 389
- 494
 
    
    - 8,653
- 13
- 56
- 104
5 Answers
Now (2020 Jan) it should be typeof window === 'undefined' since process.browser is deprecated
Refer to https://github.com/zeit/next.js/issues/5354#issuecomment-520305040
 
    
    - 8,449
- 3
- 35
- 25
- 
                    15Great answer! Adding a note, though, that if you're using Typescript and, like me, you get the error "cannot find name window", it is because you need to add `"dom"` to your `lib` array in tsconfig.json. For some reason Next.js doesn't include this by default. – Zack Jan 29 '21 at 13:00
- 
                    Client side also has worker thread scopes, where `window` is not defined. A keyword that is available in both the main browser thread and workers would be `self`, so the check could be `typeof self === 'undefined'`. On top of that, you can define a global named `window` or `self` on the server, which would invalidate this method. – Javier Rey Jan 03 '23 at 19:51
You can use process.browser to distinguish between server environment (NodeJS) and client environment (browser).
process.browser is true on the client and undefined on the server.
 
    
    - 22,666
- 2
- 56
- 61
- 
                    Also `isServer` is a thing, depending on the Next function call. I did need to use `process.browser` from where I needed the logic though :) – Dave Stein Mar 22 '18 at 17:43
- 
                    2I think `process.browser` is added by webpack which then propagates to next.js – Divyanshu Maithani Jun 22 '19 at 07:40
- 
                    10Please look at @kenberkeley's answer below instead of using this. `process.browser` is deprecated and using `typeof window` instead will get you in-framework optimizations. – Zack Jan 29 '21 at 12:58
Since I don't like depending on odd third party things for this behavior (even though process.browser seems to come from Webpack), I think the preferred way to check is for presence of appContext.ctx.req like this:
async getInitialProps (appContext) {
    if (appContext.ctx.req) // server? 
    {
        //server stuff
    }
    else {
        // client stuff
    }
}
 
    
    - 7,112
- 10
- 62
- 98
- 
                    7This assumes you are in `getInitialProps` or have access to `appContext` – monokrome May 21 '20 at 09:23
- 
                    2I wouldn't use an obscure syntax for a basic concept - an `isClient(appContext)` helper would read much better. – Dean Radcliffe Jun 21 '21 at 15:34
One additional note is that componentDidMount() is always called on the browser. I often load the initial data set (seo content in getInitialProps(), then load more in depth data in the  componentDidMount() method.
 
    
    - 1,544
- 2
- 17
- 24
- 
                    3
- 
                    1@jonhobbs Yes, `useEffect` directly replaces `componentDidMount` (plus `componentDidUpdate` and `componentWillUnmount` all in one). If you just write `useEffect(() => { .. }, [])` then it's the exact equivalent. See https://reactjs.org/docs/hooks-effect.html – Petr Bela Apr 01 '20 at 21:03
getServerSideProps and getStaticProps are added in Next 9.3(Mar 2020), and these functions are recommended.
If you're using Next.js 9.3 or newer, we recommend that you use
getStaticPropsorgetServerSidePropsinstead ofgetInitialProps.
So no need to detect, just put server side stuff in getServerSideProps.
const MyPage = () => {
  useEffect(() => {
    // client side stuff
  }, [])
  return (
    <div> ... </div>
  )
}
MyPage.getServerSideProps = async () => {
  // server side stuff
}
 
    
    - 5,651
- 2
- 24
- 36