We’ve lost our primary frontend developer and I’m having to step in midway through an upgrade from Next.js 12 to Next.js 14. I’m not particularly proficient in either version and I’ve long struggling identifying code meant for server-side rendering vs. client-side rendering. This is exasperated by the introduction of the app router we’ve begun moving towards.
Below is a trimmed down example of a page that was ported into the app router.
import { JSX } from 'react';
import { Metadata } from 'next';
import { env } from '@/lib/utils';
export const metadata: Metadata = {
title: 'Test',
};
export default function Page(): JSX.Element {
return (
<>
<div className='pt-8'>
<div className='mt-1 grid grid-cols-1 gap-3'>
Something, Something, Something, Dark Side...
</div>
</div>
{(env('E2E_ENV') === 'true') && (
<>
<div className='mt-6 relative'>
You're our only hope!
</div>
</>
)}
</>
);
}
From @/lib/utils
:
// Simplified from https://github.com/andrewmclagan/react-env/blob/master/packages/node/src/index.js
export function env(key = '') {
console.log(key+' env = '+process.env[key])
if (isBrowser() && window.__env) {
console.log(key+' __env = '+(window.__env[key] === "''" ? '' : window.__env[key]))
return window.__env[key] === "''" ? '' : window.__env[key]
}
return process.env[key] === "''" ? '' : process.env[key]
}
This previously worked fine with the E2E_ENV
variable being picked up to display the enclosed HTML when appropriate, and env()
always just worked given its compatibility with either server-side or client-side use.
This also works perfectly fine in our development environment, where env()
can be seen running server-side.
The problem comes when it’s built for non-development use. env()
is then seen operating client-side instead of server-side and while it still returns the expected value, the enclosed HTML is never displayed. That is to say, the condition looks like it should be testing true as the call and result is present in the browser console, but the additional HTML content isn’t rendered.
I’m sure I’m just running afoul of client-/server-side principles and the fix is probably stupid simple, but I could use a direct example of how to make this right. That’ll hopefully help me understand the underlying principles that I’ve had a hell of a time with so far.