Angular Universal ENV Variables on Vercel

Jonathan Gamble - Apr 8 '22 - - Dev Community

So, I moved my website Code.Build to Vercel from Cloud Run after writing all these Angular Universal articles.

Cloud Run VS AWS Lambdas

My cold start time was cut in a quarter of the time. My build time went from 15min to 3min. Granted, I didn't add any horse power to my Google Cloud Run, and I spend a total of $7 a month on hosting. I went with the default options, which Vercel uses more power. I admit my website is probably not too popular either since all my articles are cross posted here. ☹️

After reading many articles, AWS Lambdas are just faster than Docker and Cloud Run. This was extremely important to me. Google needs to spend more money developing on its Cloud Functions in order to compete. However, it is worth noting that Cloud Run does support things like Web Sockets for streaming data, while AWS Lambdas do no such thing. This is important if you're hosting a database or middleware.

So, last thing I needed to do was configure my ENV variables to work correctly in Vercel.

Firebase

For this example, I am using the Firebase env variables, and storing them in a json file. You can read about that in my Google Cloud Build article.

Basically just put the firebase information in environment.json and import it into environment.ts.

On the server, go to your project in Vercel, and add a new variable FIREBASE with your json keys.

process.env

The developers at Vercel HATE Angular. Angular is not inferior, it is just different. Notice they don't even have a tab for Angular to use ENV variables. They don't support Angular Universal, even though I wrote an aritcle about how to do it. I guess they want a plugin written. You don't need one, but I digress. Perhaps someone could write one. It may be necessary for automating advanced features like lazy loading modules to their own serverless function etc.

So, it is worth noting that process.env is available on the server, but not on the browser due to reasons listed above.

There is a probably a way to just echo the env variables to a file like I did in Cloud Build, but I went with the classic script version.

Build File

set-env.js

function setEnv() {
  fs = require("fs");
  writeFile = fs.writeFile;
  // Configure Angular `environment.prod.json` file path
  targetPath = "/vercel/path1/src/environments/environment.prod.json";
  targetPath2 = "/vercel/path2/src/environments/environment.prod.json";

  // `environment.prod.json` file structure
  envConfigFile = process.env.FIREBASE;

  console.log(
    "The file `environment.prod.json` will be written with the following content: \n"
  );
  writeFile(targetPath, envConfigFile, function (err) {
    if (err) {
      console.error(err);
      throw err;
    } else {
      console.log(
        "Angular environment.prod.json file generated correctly at" +
          targetPath +
          "\n"
      );
    }
  });
  writeFile(targetPath2, envConfigFile, function (err) {
    if (err) {
      console.error(err);
      throw err;
    } else {
      console.log(
        "Angular environment.prod.json file generated correctly at" +
          targetPath +
          "\n"
      );
    }
  });
}

setEnv();
Enter fullscreen mode Exit fullscreen mode

Create this file in your environments folder. Notice it must build two copies of the json files: one for the server, and one for the browser.

Follow my Vercel Setup instructions, add scripts.config and update scripts.vercel-build.

"config": "node src/environments/set-env.js",
"vercel-build": "npm run config && npm run build:ssr"
Enter fullscreen mode Exit fullscreen mode

Done.

Now the script runs when you build to populate the env variables on BOTH server and browser. Remember, if you just want the variables on the server, you can simple check for process.env.FIREBASE and get it that way. The problem is development environments.

Hope this helps someone,

J

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .