1
votes

So, I'm attempting to pass a user's ip address in my app, as follows:

pages/Item.js

const Item = props => (
  <div>
    <SingleItem id={props.query.id} userIP={props.userIP} />
  </div>
);

Item.getInitialProps = async ({ req }) => {
  const userIP = req.headers['x-real-ip'] || req.connection.remoteAddress
  return { userIP }
}

export default withAmp(Item, { hybrid: true });

but get the above mentioned error message (See attached image) when navigating to the page. But if I then do a hard reload of the page the ip details are correctly displayed to the page.

What am I overlooking here and is there a better way to achieve this, for example obtaining the ip address from headers in _document.js?

enter image description here

1

1 Answers

2
votes

req will only be available when getInitialProps is called on the server. This is why it works when you do a refresh on the page.

When navigating to the page there is no server render so getInitialProps will be called on the client. Therefore, req will be undefined.

You can wrap the assignment in a condition to check if req is defined to prevent the error:

Item.getInitialProps = async ({ req }) => {
  let userIP
  if (req) {
    userIP = req.headers['x-real-ip'] || req.connection.remoteAddress
  }
  return { userIP }
}

However, if you want to have userIP available on every page, regardless of whether it's server or client rendered, then you will need to find a way to store it on first load, whichever page that may be.

Perhaps you could store it using context.

There is am example of using context here: https://github.com/zeit/next.js/tree/master/examples/with-context-api

I hope this helps.