Astro is a modern site builder with web best practices, performance, and DX front-of-mind.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Astro provides runtime utilities for working with environment variables, including validation, type checking, and custom environment providers.
Astro provides environment variables through two types of modules:
Virtual Modules (astro:env/server and astro:env/client):
import { getSecret } from 'astro:env/server' (for server-side vars)import { PUBLIC_VAR } from 'astro:env/client' (for public client vars)Runtime Module (astro/env/runtime):
import { validateEnvVariable } from 'astro/env/runtime'Gets a secret environment variable from the server virtual module.
/**
* Gets a secret environment variable
* Available only in server context (SSR, API routes, actions)
*/
function getSecret(key: string): string | undefined;// src/pages/api/data.ts
import { getSecret } from 'astro:env/server';
export async function GET() {
const apiKey = getSecret('API_KEY');
if (!apiKey) {
return new Response('API key not configured', { status: 500 });
}
const data = await fetchData(apiKey);
return Response.json(data);
}Advanced APIs from astro/env/runtime for custom environment handling and validation.
Gets the TypeScript type string for an environment field from the schema.
/**
* Gets the TypeScript type string for an environment field
*/
function getEnvFieldType(options: EnvFieldType): string;
interface EnvFieldType {
type: 'string' | 'number' | 'boolean' | 'enum';
values?: string[];
optional?: boolean;
}Validates an environment variable against its schema.
/**
* Validates an environment variable value
*/
function validateEnvVariable(
value: string | undefined,
options: EnvFieldType
): ValidationResult;
type ValidationResult = ValidationResultValid | ValidationResultInvalid;
interface ValidationResultValid {
ok: true;
value: string | number | boolean;
}
interface ValidationResultInvalid {
ok: false;
errors: Array<'missing' | 'type' | string>;
}import { validateEnvVariable } from 'astro/env/runtime';
const result = validateEnvVariable('3000', {
type: 'number',
optional: false
});
if (result.ok) {
console.log('Valid port:', result.value);
} else {
console.error('Validation errors:', result.errors);
}Set a custom function for retrieving environment variables.
/**
* Sets a custom environment getter function
*/
function setGetEnv(getter: GetEnv): void;
/**
* Sets a callback for when the environment getter changes
*/
function setOnSetGetEnv(callback: () => void): void;
/**
* Gets an environment variable using the configured getter
*/
function getEnv(key: string): string | undefined;
type GetEnv = {
(key: string): string | undefined;
};import { setGetEnv, getEnv } from 'astro/env/runtime';
// Custom environment provider for Cloudflare Workers
setGetEnv((key) => {
return globalThis.MY_ENV?.[key];
});
const value = getEnv('DATABASE_URL');import { setOnSetGetEnv, getEnv } from 'astro/env/runtime';
// React to environment getter changes
setOnSetGetEnv(() => {
console.log('Environment getter was configured');
const dbUrl = getEnv('DATABASE_URL');
if (dbUrl) {
initializeWithEnv(dbUrl);
}
});Creates an error for invalid environment variables.
/**
* Creates an error for invalid environment variables
*/
function createInvalidVariablesError(
key: string,
type: string,
result: ValidationResultInvalid
): AstroError;import { createInvalidVariablesError, validateEnvVariable } from 'astro/env/runtime';
const result = validateEnvVariable(process.env.PORT, {
type: 'number',
optional: false
});
if (!result.ok) {
throw createInvalidVariablesError('PORT', 'number', result);
}Environment fields are defined in configuration (see Configuration for complete field definition APIs).
import { defineConfig, envField } from 'astro/config';
export default defineConfig({
env: {
schema: {
PUBLIC_API_URL: envField.string({
context: 'client',
access: 'public',
default: 'https://api.example.com',
}),
DATABASE_URL: envField.string({
context: 'server',
access: 'secret',
}),
PORT: envField.number({
context: 'server',
access: 'public',
default: 3000,
min: 1,
max: 65535,
int: true,
}),
ENABLE_ANALYTICS: envField.boolean({
context: 'client',
access: 'public',
default: false,
}),
LOG_LEVEL: envField.enum({
context: 'server',
access: 'public',
values: ['debug', 'info', 'warn', 'error'],
default: 'info',
}),
},
},
});Client-side environment variables (public only):
import { PUBLIC_API_URL } from 'astro:env/client';
console.log(PUBLIC_API_URL);Server-side environment variables (public and secret):
import { DATABASE_URL, PORT, getSecret } from 'astro:env/server';
console.log(DATABASE_URL);
console.log(PORT);
const apiKey = getSecret('API_KEY');// Client-side (public variables only)
import { PUBLIC_API_URL } from 'astro:env/client';
// Server-side (all variables + secrets)
import { DATABASE_URL, PORT, getSecret } from 'astro:env/server';
// Runtime utilities
import {
getEnvFieldType,
validateEnvVariable,
setGetEnv,
setOnSetGetEnv,
getEnv,
createInvalidVariablesError,
type GetEnv,
} from 'astro/env/runtime';
// Setup utilities
import { setGetEnv, type GetEnv } from 'astro/env/setup';Define environment variable types in src/env.d.ts:
/// <reference types="astro/client" />
interface ImportMetaEnv {
readonly DATABASE_URL: string;
readonly PORT: number;
readonly PUBLIC_API_URL: string;
readonly ENABLE_ANALYTICS: boolean;
readonly LOG_LEVEL: 'debug' | 'info' | 'warn' | 'error';
}
interface ImportMeta {
readonly env: ImportMetaEnv;
}context: 'client' and access: 'public'. Secret vars are server-only.setGetEnv() should be configured early in the application lifecycle.