How to read build time secrets in Fly.io for Remix react application?

I’m getting errors when running my remix application in production mode. I thing this is the fact that my Remix application is launched in Fly.io and I am not exactly sure how to access these secrets. I have the route where I am trying to access my secret keys as follows:

type LoaderData = {
  ALGOLIA_ID: string;
  ALGOLIA_KEY: string;
};

export const loader: LoaderFunction = async () => {
  const ALGOLIA_ID = process.env.ALGOLIA_ID;
  const ALGOLIA_KEY = process.env.ALGOLIA_KEY;
  if (!ALGOLIA_ID || !ALGOLIA_KEY) throw new Error('Env Variables not found');
  const data: LoaderData = { ALGOLIA_ID, ALGOLIA_KEY };
  return data;
};
//... code here
export default function Index() {
  let searchClient;
  if (process.env.NODE_ENV === 'development') {
    const data = useLoaderData<LoaderData>();
    searchClient = algoliasearch(data.ALGOLIA_ID, data.ALGOLIA_KEY);
  } else if (process.env.NODE_ENV === 'production') {
    if (!process.env.ALGOLIA_ID || !process.env.ALGOLIA_KEY)
      throw new Error('Env Variables not found');

    searchClient = algoliasearch(
      process.env.ALGOLIA_ID,
      process.env.ALGOLIA_KEY
    );
  }
//... more code after
}

I am getting the error ReferenceError: process is not defined so I can’t even use process when I am in production. I am not sure how to go about accessing my secrets for production. This also makes me wonder how would I go about adding conditionals for my remix app depending whether I am in production or not since I cannot use process.env ?

Hey,

I guess the first thing to say is that Fly’s secrets are only available (by default) at run-time, not build-time. If you do need them at build-time, take a look at Build Secrets · Fly Docs

If the intent is to only access the secrets server-side (so to call Algolia from the server), my understanding is that you can only reference process.env within the loader. As that runs on the server. Not in the component (the Index Function, in this case). At least I haven’t seen that done. To use the data in your component, you would use useLoaderData to get at those server-side variables. For example:

export default function Products() {
  const products = useLoaderData();

  return (
    <div>
      <h1>Products</h1>
      {products.map((product) => (
        <div key={product.id}>{product.name}</div>
      ))}
    </div>
  );
}

So you shouldn’t be getting process is not defined when you reference process.env in your loader. As (at run-time) that is available, and is indeed (or should be!) populated with any secrets you have.

On the other hand, if you want to make your algolia secret available to the client (so the browser would call algolia, client-side) then there is an additional step to pass it along from the server to the client. Take a look at the 1,2,3 in their example:

https://remix.run/docs/en/v1/guides/envvars#browser-environment-variables

I’m guessing algolia will make clear whether the secret is intended to be kept secret (so must stay on the server) or can be safely exposed to the client (for some kind of typeahead).

2 Likes