11

I have a Strapi backend and Next.js frontend app deployed on DigitalOcean. On DigitalOcean is set an environment variable for the frontend: API_URL = ${APP_URL}/api

I fetch this variable to generate the base url:

// constants.js
export const BASE_URL =
  process.env.NODE_ENV === "production"
    ? process.env.API_URL
    : "http://localhost:1337";

It seems to work fine, the app fetch the content from the backend in localhost and in deploy as well. The problem comes when I try to load images which path should be the concatination of the base url and the fetched relative path. I have created a utilitz function for this:

// utilities.js
import { BASE_URL } from "./constants";
export const getImageURL = (relPath) => `${BASE_URL}${relPath}`;

When I use this function for an html img tag it loads both in dev and in prod environments:

<img src={getImageURL(homePage.Hero[0].Image.url)} />

But when I try to set a background for a div in the same component the base url is undefined and the image doesn't appear in the deployed site (works fine on localhost).

I have no idea why the url generation is OK for some part of the code and not OK for the other.

The build command for deploy is: yarn build && next export -o _static

Here is the full component:

import styles from "../styles/Home.module.css";
import { getImageURL } from "../lib/utilities";
import { useEffect } from "react";
import { BASE_URL } from "../lib/constants";

export default function Home({ homePage }) {
  console.log(BASE_URL); // undefined

  useEffect(() => {
    if (window) {
      console.log(BASE_URL); // undefined
      document.getElementById("container").style.backgroundImage = `url('${getImageURL(homePage.Hero[0].Image.url)}')`; // url is undefined/realtivepath
    }
  });


  return (
    <div id="container">
      <img src={getImageURL(homePage.Hero[0].Image.url)} />
    </div>
  );
}

export const getStaticProps = async () => {
  const res = await fetch(`${BASE_URL}/home-page`); // OK for dev and deploy
  const homePage = await res.json();
  return {
    props: {
      homePage,
    },
  };
};

Hordon
  • 603
  • 2
  • 9
  • 21

2 Answers2

16

By default, Next.js not exposing all process.env.X variables, due to security concerns, to the browser.

In order to expose environment variable to the browser it must have a prefix of NEXT_PUBLIC_ in the name.

In your case, rename API_URL to NEXT_PUBLIC_API_URL, and use it.

For more info: https://nextjs.org/docs/basic-features/environment-variables

felixmosh
  • 32,615
  • 9
  • 69
  • 88
0

I achieve it like this

const fetchProducts = async () => {
  const response = await fetch(`${process.env.NEXT_PUBLIC_APP_API_ENDPOINT}/products`);
  const data = await response.json();
  setProducts(data.products);
};
Tyler2P
  • 2,324
  • 26
  • 22
  • 31