0

Let's say I have following simple set of files:

  • ./components/layout.js
import Navbar from './Navbar'
import Footer from './Footer'

import Header from '../components/Header'
import Head from 'next/head'
import Script from 'next/script'
import { app__mode } from '../settings/settings'

export default function Layout({
  children,
}) {
  return (
    <>
      <Head>
        <meta charSet="utf-8" />
        <meta name="viewport" content="initial-scale=1.0, width=device-width" />
      </Head>
      <div className="__app__">
        {app__mode === "development" ? <Header /> : <><div>hoge.</div></>}
        <Navbar />
        <main>{children}</main>
        <Footer />
      </div>
    </>
  )
}
  • ./pages/_app.js
import './../styles/styles.css';
import './../styles/styles.scss';

import Layout from '../components/layout'

export default function MyApp({ Component, pageProps }) {
  return <>
    <Layout>
      <Component {...pageProps} />
    </Layout>
  </>
}
  • ./settings/settings.js
const app__mode = process.env.APP__MODE === 'production' ? 'production' : 'development';
const app__url = process.env.APP__URL;

export { app__mode, app__url, }

The problem is, when I build then npx next start to start the server (with APP__MODE=production env variable on the shell), on the page it shows the <Header /> component while it actually shouldn't, because I'm clearly stating {app__mode === "development" ? <Header /> : <><div>hoge.</div></>}, and currently the app__mode value is production, it should be physically impossible, right?? (I also confirmed that actually the app__mode value is production by placing a breakpoint nearby; )

But one more weird point is, in the source code, I mean ctrl-U to show the html of the shown page, it doesn't contain the <Header /> html part, but instead it contains <div>hoge.</div>. What's happening???

Also, if I change {app__mode === "development" ? <Header /> : <><div>hoge.</div></>} to {app__mode === "development" && <Header />} instead, this time the whole page gets broken styled/layout.

So my question:

  1. Is this an intended behavior? If yes how/why? If no give me related SO posts or links
  2. So is it a bad idea to use conditional component rendering jsx on next.js layout pages?
  3. Is this likely to be a some sort of caching issue? (But I ensured that 1. deleting .next each time 2. also tested on chrome browser with a fresh new profile...)

Thanks.

  • edit: edit to "highlight the difference between the associated question and yours"

The two are totally different.

Since while in the mentioned question the OP knew his problem is caused by environmental variables from the beginning, and the answer is "hey you need to have them in next.config.js", in my question, the OP had a problem on component rendering, then the solve was "hey I needed to have NEXT_PUBLIC_ variables instead". Thanks for your understanding.

  • 2
    hey In order to read from envvariable in nextJs you have to start the variables with NEXT_PUBLIC_ prefix , like : NEXT_PUBLIC_APP_MODE otherwise it will stay undefined – Shadi Amr Aug 23 '22 at 13:56
  • didn't check the doc part.. just read the doc and tried with the prefix, the problem has gone away and now works as expected. Thanks!! – 丶 Limeー来夢 丶 Aug 23 '22 at 14:53

1 Answers1

0

Thanks to the Shadi Amr 's comment I noticed that the whole set of problems is from the environmental variable part in the ./settings/settings.js;

In the doc Basic Features: Environment Variables, the key parts it says are:

  • By default environment variables are only available in the Node.js environment; expose a variable to the browser you have to prefix the variable with NEXT_PUBLIC_
  • This inlining occurs at build time

So the weird problem is caused by 1. the env variables were working on node.js (so I saw it on the breakpoint) 2. but weren't working on browser (so the page layout/style broke) 3. and I thought I can pass env variables on the start too but actually on the build;

So I changed the file as:

- const mode = process.env.NODE_ENV === 'production' ? 'production' : 'development';
- const app__mode = process.env.APP__MODE === 'production' ? 'production' : 'development';
+ const app__mode = process.env.NEXT_PUBLIC_APP_MODE === 'production' ? 'production' : 'development';
+ const app__url = process.env.NEXT_PUBLIC_APP_URL;

export { app__mode, app__url, }

And also making sure to change the variables on the shell (or vscode tasks.json env values or whatever), re-build then re-start, it worked as expected.