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

Public runtime config is missing in server-rendered pages when visited from statically optimized pages #9275

Closed
MrOrz opened this issue Nov 1, 2019 · 6 comments

Comments

@MrOrz
Copy link

@MrOrz MrOrz commented Nov 1, 2019

Bug report

Describe the bug

It is known that runtime config is not supported in static-optimized pages.
However, this repo demonstrates that even when runtime config is used only in server-rendered pages, the runtime config can still be missing, which is not expected.

To Reproduce

I have constructed a minimal demo app for the bug: https://github.com/MrOrz/nextjs-runtime-config-bug

This demo consists of 2 pages:

  • pages/index.js - A landing page that contains a link to data page. The page is meant to be static-optimized.
  • pages/data.js - The data page that depends on API_URL in public runtime config (Actually it prints publicRuntimeConfig.API_URL directly). This page is meant to be server-rendered.

Reproduction steps are:

  1. Clone this repository & yarn
  2. yarn build
  3. API_URL=https://my.api yarn start and visit http://localhost:3000
  4. Click "Data page" link on http://localhost:3000. Browser will navigate to http://localhost:3000/data without full reload.

Expected behavior

The /data page shows:

We show data from API URL: https://my.api

Actual behavior

The /data page shows:

We show data from API URL:

Runtime config "API_URL" in server-rendered page does not present.

However, if we visit http://localhost:3000/data directly, we can see the API URL again.

Screenshots

scenario

System information

  • OS: macOS
  • Browser (if applies) Google Chrome
  • next: 9.1.2
  • react: 16.11.0
  • react-dom: 16.11.0

Additional context

The scenario is the simplified from this website. I want to have a statically rendered landing page linking to a server-rendered article list; however, when users go to article list from the landing page, the HTTP requests always fail because API URL in config is not set.

When I deploy the website, I put the built website in Docker image. Production sites and staging sites will share the same docker image to ensure consistency between the two environments; the only difference between them are the API endpoints they connect to, which is specified in docker-compose file. This is why I put API URL in publicRuntimeConfig instead of build-time config.

@MrOrz MrOrz changed the title Public runtime config not exist for server rendered pages Public runtime config is missing from server-rendered pages when visited from statically optimized pages Nov 1, 2019
@MrOrz MrOrz changed the title Public runtime config is missing from server-rendered pages when visited from statically optimized pages Public runtime config is missing in server-rendered pages when visited from statically optimized pages Nov 1, 2019
@Baukaalm

This comment has been minimized.

Copy link
Contributor

@Baukaalm Baukaalm commented Nov 1, 2019

Add _app.js in /pages and write this configuration in gip

import React from 'react';

import App from 'next/app';

class MyApp extends App {
  static async getInitialProps({ Component, ctx }) {
    const pageProps = Component.getInitialProps
      ? await Component.getInitialProps(ctx)
      : {};

    return { pageProps };
  }

  render() {
    const { Component, pageProps } = this.props;
    return <Component {...pageProps} />;
  }
}

export default MyApp;

and import React lib in data page

It works for me

@MrOrz

This comment has been minimized.

Copy link
Author

@MrOrz MrOrz commented Nov 1, 2019

@Baukaalm Thanks for the info. Doesn't adding getInitialProps to App forces all pages to serve from server?

What I wanted is keeping the landing page (pages/index.js) optimized as a static page, but I should be able to navigate to server-rendered pages without problem.

@MrOrz

This comment has been minimized.

Copy link
Author

@MrOrz MrOrz commented Nov 1, 2019

A workaround would be replacing

// pages/index.js
<Link href="/data">
  <a>
    Data page
  </a>
</Link>

with this:

<a href="/data">
  Data page
</a>

This actually forces the browser to load the full page when navigating from landing page to data page. But it is an acceptable workaround to me, because I want a statically optimized landing page anyway.

@MrOrz

This comment has been minimized.

Copy link
Author

@MrOrz MrOrz commented Nov 1, 2019

I guess another "workaround" I learned from #7827 is, I can build a API route that proxies requests to the real API server according to the environment variable. In this case I won't need to put publicRuntimeConfig.API_URL in pages/data.js, I just need /api/<the_proxy>, in both staging and production environments.

Does next.js 9 discourage people to use APIs other than its built-in API routes?

@xyy94813

This comment has been minimized.

Copy link

@xyy94813 xyy94813 commented Nov 4, 2019

I got the same problem.

Next Version: 9.1.1 and 9.1.2

step 1:

// in next.config.js

function getPublicRuntimeConfig () {
    const runtimeConfig = {};
    
    if (process.env.VAR) {
        runtimeConfig.VAR = process.env.VAR;
    }

    return runtimeConfig;
}

module.exports = {
    publicRuntimeConfig: getPublicRuntimeConfig()
}

step2:

yarn run build

step3:

VAR=test yarn run start

import getConfig from "next/config";

const Demo = () => {
    return `Demo`;
}

Demo.getInitialProps = async () => {
    const { publicRuntimeConfig } = getConfig();

    // work well in server side, but `publicRuntimeConfig.VAR` is undefined in browser;
    console.log(publicRuntimeConfig.VAR);

    return {};
}
@Timer

This comment has been minimized.

Copy link
Member

@Timer Timer commented Nov 9, 2019

Duplicate of #7844

@Timer Timer marked this as a duplicate of #7844 Nov 9, 2019
@Timer Timer closed this Nov 9, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants
You can’t perform that action at this time.