Next.js: Add `hostname` parameter to getInitialProps

Created on 10 Sep 2019  路  6Comments  路  Source: vercel/next.js

Feature request

Add hostname parameter in ctx which returns current hostname on both server and client.

Is your feature request related to a problem? Please describe.

We have 2 web apps - Next.js frontend and Django API. We use Nginx to proxy routes so both are using the same host but API is hosted under /api. And because we deliver our app to VPS we don't know the current host so we can't just use localhost.

I have to use custom _app without prerendering so my page only renders on server.

Here's my _app:

import React from 'react'
import App from 'next/app'

class CustomApp extends App {
  static async getInitialProps({ Component, ctx }) {
    let host

    if (ctx.req) {
      host = ctx.req.headers.host
    } else {
      host = location.hostname
    }

    let pageProps = {}

    if (Component.getInitialProps) {
      pageProps = await Component.getInitialProps({ ...ctx, host })
    }
    return { pageProps }
  }
  render() {
    const { Component, pageProps } = this.props
    return <Component {...pageProps} />
  }
}
export default CustomApp

Describe the solution you'd like

I can make a PR with this custom getInitialProps argument so it will be accessible via ctx.hostname:

Page.getInitialProps = async ({ hostname }) => {
  const res = await fetch(`${hostname}/some-proxied-api/data`)
}

Describe alternatives you've considered

Write a function getHost and call it in every getInitialProps. Not very suitable especially when you have tons of pages with using getInitialProps.

Most helpful comment

May I suggest reviving this? ctx.hostname appears to me as the only way to retrieve the hostname inside getInitialProps when ctx.req does not exist because the user followed a <Link>. Another way of passing info to getInitialProps such as a ctx.state could be an alternative too.

If I actually didn't see a way of doing this that already exists, please let me know.

All 6 comments

This is unnecessary and can be handled by creating your own fetch wrapper. We typically don't increase the API surface for features easily/better handled in user-land.

Thanks for the suggestion!


By the way, you don't need hostname on the client.

This should be sufficient:

fetch(`${req ? req.headers.host : ''}/some-proxied-api/data`)

You can subscribe to https://github.com/zeit/next.js/pull/7300 and we'll post there if we ever revive that feature, but the tl;dr is to allow fetch('/bla') to "just work" on the server as it does on the client.

This is unnecessary and can be handled by creating your own fetch wrapper. We typically don't increase the API surface for features easily/better handled in user-land.

Thanks for the suggestion!

By the way, you don't need hostname on the client.

This should be sufficient:

fetch(`${req ? req.headers.host : ''}/some-proxied-api/data`)

But I still can't use getInitialProps in _app with CSR, right? so I have to write this every time. Although, nice suggestion :+1:

Yes, you need to write it once for each page. This will be better as your application naturally evolves and maybe short-circuits the HTTP API and uses a direct code call or similar.

Note that req.headers.host is not always safe and can be spoofed when hosting yourself. Many platforms override it to be consistent with say a deployment url, hence why we can't provide it just like that, as it would introduce potential security issues for a subset of users.

May I suggest reviving this? ctx.hostname appears to me as the only way to retrieve the hostname inside getInitialProps when ctx.req does not exist because the user followed a <Link>. Another way of passing info to getInitialProps such as a ctx.state could be an alternative too.

If I actually didn't see a way of doing this that already exists, please let me know.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

havefive picture havefive  路  3Comments

wagerfield picture wagerfield  路  3Comments

rauchg picture rauchg  路  3Comments

flybayer picture flybayer  路  3Comments

jesselee34 picture jesselee34  路  3Comments