How to expose Next.js environment variables to the browser specific code

The Next.js React web application runs separate code on the server and in the browser. By default, the environment variables are only accessible in the server side script.

Warning: by exposing environment variables to the browser code you may reveal secrets. Make sure the exposed environment variables do not contain any secrets. If secrets are needed in the browser code, create an API page in the pages/api directory and fetch it from the browser code.

To use environment variables in the browser side script,

  • expose those in the next.config.js file
module.exports = {
  ...
  
  env: {
    // declare here all your variables
    MY_ENVIRONMENT_VARIABLE: process.env.MY_ENVIRONMENT_VARIABLE,
  }
};
  • Restart the server for the change to take effect !!!
  • Read the environment variable value from process.env in the browser specific file.
<div className={styles.footer} >
  Version: '2023-06-22_01' &nbsp;{process.env.ENVIRONMENT}
</div>

Error: Cannot find module ‘…’ outside of the development environment

When the Node.js application runs correctly in the development environment, but throws the following error in higher environments:

Error: Cannot find module ‘…’

Make sure the module is not listed in the “devDependencies” section of the package.json and package-lock.json files.

If you have installed a package with the --save-dev @types/... option, the package is considered a development-only tool, and will not be compiled into the production code.

To correct the issue:

  • If you use the Makefile to list all your installed packages, remove the --save-dev @types/... option from the npm install line
  • Uninstall the package with npm uninstall MY_PACKAGE_NAME
  • Install the package again with npm install but, without the --save-dev @types/MY_PACKAGE_NAME option
    The package.json and package-lock.json files are automatically updated by npm.
  • Rebuild and deploy the application.

error: INSERT has more expressions than target columns

When the parameterized PostgreSQL statement has more elements in the “VALUES” option than the number of columns specified, we get the error message:

error: INSERT has more expressions than target columns

In the sample code below there are two columns listed, and there are three elements in the “VALUES” option.

      const query = "INSERT INTO my_table (name, description) VALUES ($1, $2, $3)";

Solution

Remove the extra elements from the “VALUES” option.

error: could not determine data type of parameter $1

For security reasons we should always use parameterized queries to avoid SQL injections through parameters.

The usual format is

      const query = "INSERT INTO my_table (name, description) VALUES ($2, $3)";
      const parameters = ['not_used', 'my-name', 'my-description'];

When a PostgreSQL command runs and a parameter is not used, we get the error message

error: could not determine data type of parameter $1

Solution:

Remove the unused parameter from the “parameters” array, in this case the first one.

How to disable static page generation during Next.js site build

If your Next.js React TypeScript web application uses database calls to display data on the pages, and during build time the database is not available, we need to disable the static page generation, otherwise we get the following error:

info Generating static pages

TypeError: Failed to parse URL from …

code: ‘ERR_INVALID_URL’

To disable the static page generation during build, Add the getInitialProps function to the App object in the pages/_app.tsx file.

import '@/styles/globals.css'
import type { AppProps } from 'next/app'

export default function App({ Component, pageProps }: AppProps) {

  return <Component {...pageProps} />
}

App.getInitialProps = async ({}) => {
  return {  }
}

 

How to disable linting during React Next.js Node.js application build

If your application is in the proof of concept phase, it works and you just want to build it, you can disable the linting process to have a successful build regardless of linting errors.

  • To disable TSLint for one line only, add the // @ts-ignore before the line.
  • To disable TSLint on the entire file add // @ts-nocheck as the first line of the file.
  • To disable ESLint during build add the DISABLE_ESLINT_PLUGIN=true environment variable to the .env file in your project root directory
  • To disable ESLint during Docker image build add the ARG DISABLE_ESLINT_PLUGIN=true to the Dockerfile

Object is possibly ‘undefined’

The ESLint static code analysis tool flags code where we operate on objects which can be undefined.

Object is possibly ‘undefined’

The end of the red line shows the extent of the object which can be undefined, as the “children” element is defined as optional in the type definition:

To satisfy the linter, we need to add another question mark after “children” to guard against undefined values.

hashTable[parent]?.children?.push(hashTable[element.id]);

Type error: Type ‘string’ is not assignable to type ‘number’

When you create an array in TypeScript the type of the first element defines the type of all elements of the array.

When we reuse an array with new data, the array type has already been defined, so when we assign new values to the same array we get the error message:

Type error: Type ‘string’ is not assignable to type ‘number’

If the array only contained one type of data during definition, all elements will be defined as that data type.

let myArray = [1, 2, 3, 4, 5];
// error: Type 'string' is not assignable to type 'number' 
myArray = ['1', '2', '3', '4', '5']; 

If the array definition contained mixed data type, the elements will be defined as “objects”.

let myArray = [1, 'a', 3, 4, 5];
// No error 
myArray = ['b', 6, 'd', 7, 'f']; 

Type ‘null’ is not assignable to type ‘string’

In a TypeScript application ESLint flags code when we try to assign “null” value to string type variables and attributes. This can be necessary when we want to set the value of a database column to “null”.

To make a string type attribute nullable, add ” | null ” to the type definition:

export type Incident = {
  id: number;
  name: string;
  start_date_utc: string | null;
  end_date_utc: string | null;
  description: string;
}