Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exposing configuration to the server / client side (minor) #3882

Merged
merged 10 commits into from
Feb 26, 2018

Conversation

timneutkens
Copy link
Member

@timneutkens timneutkens commented Feb 24, 2018

Fixes #3856

The config key allows for exposing runtime configuration in your app. All keys are server only by default. To expose a configuration to both the server and client side you can use the public key.

// next.config.js
module.exports = {
  runtimeConfig: {
    mySecret: 'secret',
    public: {
      staticFolder: '/static'
    }
  }
}
// pages/index.js
import getConfig from 'next/config'
const config = getConfig()
console.log(config.mySecret) // Will be 'secret' on the server, `undefined` on the client
console.log(config.public.staticFolder) // Will be '/static' on both server and client
 
export default () => <div>
  <img src={`${config.public.staticFolder}/logo.png`} />
</div>

server/index.js Outdated

// Only the `public` key is exposed to the client side
// It'll be rendered as part of __NEXT_DATA__ on the client side
if (this.nextConfig.config.public) {
Copy link
Contributor

@arunoda arunoda Feb 25, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@timneutkens
May be this will allow to write code easily.

this.renderOpts.config = {
  public: this.nextConfig.config.public || {}
}

So, someone can write this without getting any errors:

import config from 'next/config'
const { mySecret } = config.public

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added here: 859c38a

Because I don't want to add it to getInitialProps if it's not configured.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@timneutkens hmm. Okay that's not what I wanted. But I feel like this is just fine.

@timneutkens timneutkens changed the title [WIP] Exposing configuration to the server / client side Exposing configuration to the server / client side (minor) Feb 25, 2018
Copy link
Contributor

@arunoda arunoda left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@timneutkens
Copy link
Member Author

After feedback from @rauchg I'm renaming the next.config.js key to runtimeConfig

@jcollum
Copy link

jcollum commented Mar 20, 2018

Has this been merged in to 5.0.1-canary.16? It looks to me like it has but when I try to use it my config is empty:

JSON.stringify(config)
"{"serverRuntimeConfig":{}}"

Code:

import getConfig from 'next/config';
const config = getConfig();

next.config.js:

module.exports = {
  distDir: 'dist',
  runtimeConfig: {
    public: {
      apiURL: process.env.API_URL || 'https://xxxxxx/api/v1'
    }
  }
};

build command:

yarn build:local 
yarn run v1.5.1
$ API_URL='http://localhost:8081/foo/api/v1' next build
> Using external babel configuration
> Location: "/Users/jcol53/work/get-help/fe/.babelrc"

Running with next build && next start was no different. Changing the config section to:

public: {
      test: "boo"
    }

was no different.

It sure looks like the relevant file is included in the local package.json:

✗ cat node_modules/next/package.json| grep -C 3 config
    "asset.js",
    "error.js",
    "constants.js",
    "config.js"
  ],
  "bin": {
    "next": "./dist/bin/next"

@timneutkens
Copy link
Member Author

timneutkens commented Mar 20, 2018

@jcheroske yes, the config signature was changed though, after this PR was merged:

https://github.com/zeit/next.js#exposing-configuration-to-the-server--client-side

@jcollum
Copy link

jcollum commented Mar 20, 2018

OK cool, that helps. How would I pull in an env variable though? My best attempt isn't working:

console.dir('process.env.API_URL', process.env.API_URL);
console.dir('process.env ', process.env);

module.exports = {
  distDir: 'dist',
  publicRuntimeConfig: {
    apiURL: process.env.API_URL || 'https://foo/api/v1'
  }
};

It seems like my env vars aren't getting through:

✗ API_URL='http://localhost:8081/foo/api/v1' next build
'process.env.API_URL'
'process.env '
> Using external babel configuration
> Location: "/Users/jcol53/work/get-help/fe/.babelrc"
✨  Done in 12.08s.

But clearly I'm calling them right:

✗ API_URL='foo' node -e 'console.log(process.env.API_URL)'
foo

Is there a sub-process involved here? I'm unclear on how next build wouldn't see my process variables.

@jcollum
Copy link

jcollum commented Mar 20, 2018

If you think this should be moved to an issue feel free to say so.

@timneutkens
Copy link
Member Author

It's runtime configuration, so it's not being replaced at build time.
You'll have to do API_URL='foo' next start or API_URL='foo' node server.js.

@jcollum
Copy link

jcollum commented Mar 21, 2018

Ah, ok cool thanks.

@gaz7
Copy link

gaz7 commented Jun 12, 2018

I've got a similar issue where I want to supply a different API_URL depending on whether the environment is local development, staging or production.

My problem though, is that I'm exporting static sites to run on s3.

I'd like to be able to run something like API_URL='http://staging.api' next build && next export or API_URL='http://production.api' next build && next export to build versions I can then sync to the appropriate s3 buckets.

publicRuntimeConfig: { apiURL: process.env.API_URL } will exist on the server when the pages are built, but is undefined on the client so subsequent api calls will fail.

I've managed to get it working using a custom _document.js similar to this example #1488 (comment).

However, it feels a bit hacky and something that would be better done in publicRuntimeConfig

@timneutkens
Copy link
Member Author

It's because you're not providing the variable to next export:

API_URL='http://production.api' next build && API_URL='http://production.api' next export

@gaz7
Copy link

gaz7 commented Jun 12, 2018

Thanks @timneutkens. I didn't realise you had to define the env variable every time. It now works a lot cleaner

@lock lock bot locked as resolved and limited conversation to collaborators Jun 12, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Ability to pass custom config information from next.config.js to the browser
4 participants