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
getStaticProps
orgetServerSideProps
instead 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