In this article we discuss handling environment variables in Astro projects when Deploying to Cloudflare workers
using Github integration with Cloudflare to have auto deployment of your site on on pushing to a branch
this also will act as a way to have multiple workers for different branches each will have its own envitonment variables (dev, stagin, production)
So to list what we need to achieve:
Have multiple branches (dev, production, staging) each will have its own Cloudflare worker and its own environment variables.
Integrate Cloudflare workers with each branch to trigger build and deploy on pushing to Github, and not run (npm run build && npx wrangler deploy) on your machine.
No need for Github actions for build and deploy to Cloudflare.
Use one Wrangler file to manage asset bindings, and other shared configurations for an Astro project to be integrated with Cloudflare.
Define different buildtime and runtime environment variables for each branch on Cloudflare dashboard for convenience.
this Astro project has main configurations needed to deploy to Cloudflare worker:
Wrangler file
this file has "keep_vars": true (to avoid overwriting variables defined on Cloudflare dashboard)
a recommended approach is to keep wrangler file as only source of truth
but for our use case this is a good option.
also it is missing name field like: "name": "worker name" we will add this for each worker when setting up deploy command
like npx wrangler delpoy --name dev-worker or npx wrangler delpoy --name prod-worker
you need to ensure you have .env file dedfined at the root of the project
.env
SECRET_VAR_ONE=SECRET_VAR_ONE_VALUE
add Cloudflare as adapter and set Astro output as ‘server’
astro.config.mjs
// @ts-check
import { defineConfig } from "astro/config";
import cloudflare from "@astrojs/cloudflare";
// some code ...
// https://astro.build/config
export default defineConfig({
output: "server",
adapter: cloudflare()
// some code ...
});
Accessing environment variables
there are multiple scenarios where we need to access any environment variables:
astro.config.mjs
ssg pages
ssr pages
For astro.config.mjs
we use loadEnv from 'vite'
astro.config.mjs
// @ts-check
import { defineConfig } from "astro/config";
import cloudflare from "@astrojs/cloudflare";
import { loadEnv } from "vite";
const { SECRET_VAR_ONE } = loadEnv(
process.env.TEST_SECRET || "",
process.cwd(),
""
);
console.log("SECRET_VAR_ONE in astro.config.mjs", SECRET_VAR_ONE);
// https://astro.build/config
export default defineConfig({
output: "server",
adapter: cloudflare()
// somde code ...
});
then we can use the environment variables in any needed actions such as:
communicating with external APIs and load any needed global Astro configurations
For SSG pages we can use two methods
we can use import.meta.env but we will see later how we can define a helper function
that will rerutn environment variables in buildtime or runtime on Cloudflare
using import { getSecret } from "astro:env/server";
and for this we need to define schema in astro.config.mjs to have type safety
and define scope of each environment variable if it is client or server
in this demo we are only interested in server side environment variables
here is the full code of astro.config.mjs
astro.config.mjs
// @ts-check
import { defineConfig, envField } from "astro/config";
import cloudflare from "@astrojs/cloudflare";
import { loadEnv } from "vite";
const { SECRET_VAR_ONE } = loadEnv(
process.env.TEST_SECRET || "",
process.cwd(),
""
);
console.log("SECRET_VAR_ONE in astro.config.mjs", SECRET_VAR_ONE);
for import.meta.env it will not work and will be undefined in runtime (ssr) when we deploy to Cloudflare
we can use import { getSecret } from "astro:env/server"; const envGetSecret = getSecret("SECRET_VAR_ONE");
you can find this used in both ssg-example and ssr-example pages in the demo repo
another way to access the environment variables in Cloudflare utilizing how it uses the bindings deined in wrangler config file
and you can access bindings from Astro.locals.runtime
for more details visit Astro documentation click here
so to access any environment variables during runtime like in your ssr pages
and we better adopt this across your entire project
even on ssg pages you can approach this in two different ways:
develop a helper function that takes in Astro (Astro global object available in all contexts in .astro files)
use getSecret function imported from “astro:env/server”