Tags & Environments

Tags and environments work together to give you flexible control over where your applications get deployed and how users access them. Think of tags as smart bookmarks that automatically point to the right version, and environments as deployment destinations with their own custom settings.

Understanding Tags

Tags are smart pointers that automatically find and serve the right version of your application based on rules you set. Unlike static bookmarks, tags actively evaluate your deployment conditions and always point to the most relevant version.

How Tags Work

When you create a tag, you define conditions that describe which version it should point to. Every time someone visits your tag's URL, Zephyr looks through all your versions, finds the ones that match your conditions, and serves the most recent match.

For example, you might create a "production" tag that always points to the latest version built from your main branch by your CI system. When you push new code to main and your CI deploys it, the production tag automatically switches to that new version without you doing anything.

Tag Conditions

Tags use flexible condition rules to decide which version to serve. You can combine multiple conditions using "AND" and "OR" logic:

Branch-based tags: Point to versions from specific git branches

  • Perfect for environment-specific deployments
  • Example: All versions from "main" branch

User-based tags: Point to versions built by specific team members

  • Great for personal development environments
  • Example: All versions built by "john@company.com"

CI/CD tags: Distinguish between automated and manual builds

  • Useful for separating production from development builds
  • Example: Only CI-built versions vs only manually built versions

Git tag matching: Point to versions that match semantic versioning patterns

  • Essential for release management
  • Example: All versions tagged like "v1.2.3"

Platform targeting: Point to versions built for specific platforms

  • Important for multi-platform applications
  • Example: Web versions vs mobile versions

You can create sophisticated rules by combining conditions. A "stable" tag might point to versions that are from the main branch, built by CI, and match a version pattern - ensuring only production-ready builds are served.


Nested Conditions

Tag conditions can be nested, allowing deeply flexible and expressive logic trees using combinations of AND and OR groups.

Each condition group can contain:

  • Individual conditions, and/or
  • Other nested groups of conditions.

This lets you describe logic such as:

Example:

  • isCI is true
  • AND
    • (branch is main OR branch is release)
    • AND
    • (user is Zephyr User OR user is Tech Team)

This rule means:
“Select CI builds from the main or release branches made by Zephyr User or the Tech team.”


Tag URLs and Access

Every tag gets its own permanent URL that you can share, bookmark, or use in other applications. These URLs never change, even when the tag switches to point to different versions. This means your links always work, but they automatically serve the most up-to-date content based on your rules.

Tag URL Format:

https://t-{tagname}-{app-uid}-{hash}.{domain}

Example: https://t-main-header-component-ecommerce-acme-abc123.zephyr-cloud.io

URL Components:

  • t- prefix indicates this is a tag URL
  • tagname - Your tag name (e.g., "main", "staging", "production")
  • app-uid - Application unique identifier
  • hash - Content hash for uniqueness
  • domain - Your edge domain

When someone visits a tag URL, they see whatever version the tag currently points to. Behind the scenes, Zephyr evaluates your tag conditions in real-time against your application's version history, finds the most recent version matching the conditions, and serves that content from its global edge network.

How Tag Resolution Works:

  1. Request arrives at tag URL
  2. Zephyr queries the database for versions matching the tag's conditions
  3. The most recent matching version is selected
  4. That version's assets are served from the edge network

This dynamic evaluation means tags automatically update to serve the latest matching version without any manual intervention.

Automatic Tag Creation

Zephyr creates useful tags automatically when you deploy. These default tags follow patterns like "web_main_yourname" and include sensible conditions based on your build context. You can customize these or create entirely new ones with your own rules.

Understanding Environments

Environments are deployment destinations that represent different stages of your application lifecycle. They're like dedicated hosting slots where specific versions of your application live, each with their own configuration and custom domains.

What Environments Enable

Think of environments as separate deployment targets for your application. You might have a "development" environment that automatically deploys the latest code for testing, a "staging" environment for final review, and a "production" environment that serves your live application to users.

Each environment can have its own custom domain, environment variables, and deployment settings. This lets you run the same application code in different contexts - maybe your staging environment uses test data while production uses real customer information.

Environment URL Format:

https://{env-name}-{app-uid}-{hash}.{domain}

Example: https://production-header-component-ecommerce-acme-abc123.zephyr-cloud.io

URL Components:

  • env-name - Your environment name (e.g., "production", "staging", "dev")
  • app-uid - Application unique identifier
  • hash - Content hash for uniqueness
  • domain - Your edge domain

Environment Configuration

Environments can be configured to deploy in two ways:

Tag-based environments point to a specific tag and automatically serve whatever version that tag currently resolves to. For example, if your staging environment points to the "beta" tag, it will always serve whichever version the beta tag's conditions currently select. When the beta tag resolves to a new version (either because you built a new version matching its conditions, or because you updated the tag's conditions), the staging environment automatically reflects that change.

Version-based environments point to a specific locked version that doesn't change until you manually deploy a different version. This gives you complete control over exactly what's running in that environment, with no automatic updates.

Custom Domains and DNS

Each environment can have multiple custom domains pointing to it. This is perfect for:

  • White-label deployments where different clients see the same application on their own domain
  • Geographic routing where different regions use different domains
  • A/B testing where you can split traffic between different versions
  • Brand management where staging uses "staging.company.com" and production uses "app.company.com"

Setting up custom domains is straightforward. When you add a domain to an environment, Zephyr automatically handles SSL certificates and creates the necessary routing. You just need to point your DNS records to Zephyr's edge network.

Environment Variables (ZEPUBLIC*)

Zephyr provides a powerful system for managing environment variables that can be overridden on a per-environment basis at runtime. By prefixing environment variables with ZE_PUBLIC_ in your local configuration, Zephyr captures them at build time and makes them available for environment-specific overrides.

How It Works

The system operates through three stages:

  1. Build-time capture: During the build process, Zephyr identifies all environment variables prefixed with ZE_PUBLIC_ and captures their values
  2. Manifest generation: These variables are stored in a zephyr-manifest.json file (generated automatically, no manual interaction needed)
  3. Runtime override: When your application is served from a specific environment, Zephyr dynamically injects the environment-specific values for these variables

This means you can build your application once and deploy it to multiple environments, with each environment using its own configuration values without requiring a rebuild.

Setting Up Build-Time Variables

To make an environment variable manageable by Zephyr, prefix it with ZE_PUBLIC_ in your local .env file or build environment:

.env
# Regular environment variables (not managed by Zephyr)
DATABASE_URL=postgres://localhost/myapp

# Zephyr-managed environment variables (prefix with ZE_PUBLIC_)
ZE_PUBLIC_API_URL=https://api.development.example.com
ZE_PUBLIC_FEATURE_FLAGS=beta-ui,new-checkout
ZE_PUBLIC_ANALYTICS_KEY=dev_analytics_12345
ZE_PUBLIC_CDN_URL=https://cdn.development.example.com

When Zephyr builds your application, it captures the values of all ZE_PUBLIC_ variables and makes them available for environment-level overrides.

Variable Naming

The ZE_PUBLIC_ prefix is required for Zephyr to identify and manage these variables. In your application code, you'll reference them with the full name including the prefix (e.g., process.env.ZE_PUBLIC_API_URL).

Configuring Environment-Level Overrides

After building your application, you can override the values of ZE_PUBLIC_ variables for each environment through the Zephyr dashboard:

  1. Navigate to the DevOps section in your Zephyr dashboard
  2. Select the environment you want to configure (e.g., staging, production)
  3. Find the Environment Variables section for that environment
  4. For each ZE_PUBLIC_ variable, you can set an environment-specific override value

When your application is served from that environment's URL, it will use the overridden values instead of the build-time values.

Practical Example

Let's say you're building an e-commerce application that needs to connect to different API endpoints in different environments.

Local .env file (build-time configuration):

.env
ZE_PUBLIC_API_URL=https://api.development.example.com
ZE_PUBLIC_STRIPE_KEY=pk_test_51ABC123xyz
ZE_PUBLIC_ANALYTICS_ID=UA-00000000-1

Environment-level overrides:

EnvironmentZE_PUBLIC_API_URLZE_PUBLIC_STRIPE_KEYZE_PUBLIC_ANALYTICS_ID
Developmenthttps://api.dev.example.compk_test_51ABC123xyzUA-00000000-1
Staginghttps://api.staging.example.compk_test_51DEF456xyzUA-11111111-1
Productionhttps://api.example.compk_live_51GHI789xyzUA-22222222-1

In your application code:

Use the environment variables exactly as you normally would - no special imports or configuration needed:

src/config.js
// Use ZE_PUBLIC_ variables just like any other environment variable
export const config = {
  apiUrl: process.env.ZE_PUBLIC_API_URL,
  stripeKey: process.env.ZE_PUBLIC_STRIPE_KEY,
  analyticsId: process.env.ZE_PUBLIC_ANALYTICS_ID,
};

Zephyr's bundler integration handles all the complexity behind the scenes. The implementation varies by bundler (Vite uses import maps, Webpack/Rspack use module resolution, Rollup uses code transformation), but the developer experience is consistent: simply prefix your variables with ZE_PUBLIC_ and access them normally in your code.

What happens:

  • You build once with the development values
  • When served from the development environment URL → uses development configuration
  • When served from the staging environment URL → uses staging configuration
  • When served from the production environment URL → uses production configuration

The same built application adapts its configuration dynamically based on which environment URL serves it. No rebuild required.

Security Considerations

Public vs Secret Variables:

The ZE_PUBLIC_ prefix indicates that these variables are client-side and will be included in your bundled application code. This is important to understand:

  • Safe for ZEPUBLIC: API endpoints, feature flags, CDN URLs, public analytics IDs, client-side configuration
  • Never use ZEPUBLIC for: API secrets, database passwords, authentication tokens, private keys, sensitive credentials
Client-Side Exposure

Variables prefixed with ZE_PUBLIC_ are bundled into your client-side code and are visible to anyone who views your application. Never store sensitive secrets in these variables. Only use ZE_PUBLIC_ for values that are safe to expose publicly.

Working Together: Tags, Environments, and Promotion Workflows

Tags and environments work together to create powerful deployment workflows. A common pattern is:

  1. Development environment watches the "latest" tag, which points to any new version from your feature branches
  2. Staging environment watches the "beta" tag, which you manually update when you're ready to test
  3. Production environment is locked to a specific version that you promote after thorough testing

This setup gives you automatic deployment for development, controlled promotion to staging, and careful management of production releases.

Promoting Between Environments

When you're ready to move a version from one environment to another, Zephyr provides promotion tools. You can select any version from your history and deploy it to any environment. This creates a clear audit trail showing what version was deployed where and when.

For example, after testing a version in staging, you can promote that exact same version to production with one click. Since versions are immutable, you know production will run exactly what you tested.

Environment Ordering and Workflows

You can organize your environments in order to create clear promotion pipelines. New versions flow through your environments in a predictable way, with each stage serving as a checkpoint before the next level.

Teams often set up workflows where successful builds automatically deploy to development, get manually promoted to staging after code review, and then get promoted to production after QA approval.

Practical Examples

Development Team Workflow

A typical team might set up:

  • "dev" tag: Points to latest builds from any branch by any team member

  • "staging" tag: Points to builds from main branch, manually updated

  • "production" tag: Points to specific approved versions

  • Development environment: Uses the dev tag, updates constantly

  • Staging environment: Uses the staging tag, updated for testing

  • Production environment: Uses specific versions, updated carefully

Multi-tenant Application

For applications serving multiple customers:

  • "customer-a" environment: Custom domain "app.customer-a.com", production version
  • "customer-b" environment: Custom domain "app.customer-b.com", same production version
  • "demo" environment: Custom domain "demo.company.com", latest beta version

Each customer sees the application on their own domain, but you manage everything from one codebase.

Feature Flag Testing

For testing new features:

  • "stable" tag: Points to main branch builds without feature flags

  • "experimental" tag: Points to feature branch builds with new features enabled

  • Production environment: Uses stable tag for most users

  • Beta environment: Uses experimental tag for selected testers

This lets you safely test new features with a subset of users while keeping the main application stable.

Managing Tags and Environments

The Zephyr dashboard provides full control over your tags and environments. You can create, update, and delete them, view their history, and see exactly which versions they're currently serving.

For tags, you can see which conditions are active, preview which versions would match, and update the rules as your workflow evolves. For environments, you can manage custom domains, environment variables, and deployment settings all in one place.

Both tags and environments maintain full audit logs, so you can always see who changed what and when. This is essential for debugging issues and maintaining security compliance in production environments.

Integration with CI/CD

Tags and environments integrate seamlessly with your existing CI/CD pipelines. Your build systems can automatically create tags, deploy to environments, or trigger promotions based on your workflow needs.

Many teams configure their CI to automatically update a "latest" tag when tests pass, trigger staging deployments when code merges to main, and provide promotion tools for moving releases to production.

Since everything works through Zephyr's API, you can integrate with any CI/CD system and create custom workflows that match your team's processes exactly. Learn more about automation workflows.