Dynamically set baseUrl in cypress.json

Stefan Bogdanescu

Founder & Senior Architect · 2026-06-29

Laravel Company

Dynamically Setting baseUrl in Cypress: Bridging Laravel Environment with Testing Configuration

As developers working with modern PHP frameworks like Laravel, we often manage application configurations through environment variables defined in .env files. When integrating end-to-end testing tools like Cypress, a common friction point arises: how do we ensure our tests run against the correct environment (local, staging, production) without manually editing configuration files for every deployment?

You are right to focus on the baseUrl setting in cypress.json. Hardcoding a specific URL, such as http://127.0.0.1:8000, is brittle. It breaks immediately when you deploy your application to a staging server or run tests in a Continuous Integration/Continuous Deployment (CI/CD) pipeline where the hostname changes.

This post will dive into how to dynamically set the baseUrl in Cypress by reading environment variables, leveraging the same principles that govern configuration management in Laravel.


The Challenge of Static Configuration

Your current setup looks like this:

// cypress.json (Static)
{
  "baseUrl": "http://127.0.0.1:8000", // This is static and environment-dependent.
  "chromeWebSecurity": false
}

The issue is that the Cypress runner executes independently of your PHP application's environment setup. If you rely on localhost, tests run fine locally, but they fail when executed by a CI server which uses a different domain or IP address.

To solve this, we need to shift the responsibility of defining the base URL from the static JSON file into the dynamic runtime environment where Cypress executes its commands.

The Dynamic Solution: Reading Environment Variables

The most robust way to achieve dynamic configuration is to read the necessary environment variables directly within your Cypress setup file, typically cypress.config.js. This approach mirrors how Laravel manages configuration—by separating deployment-specific settings from core application logic.

Step 1: Ensure Environment Variables are Accessible

In a standard Laravel setup, your APP_URL or other base paths are defined in the .env file and exposed to PHP via env(). For Cypress (which runs on Node.js), we need to ensure these environment variables are available to the Node process.

When running tests within a framework like Laravel, you often need a small wrapper script or setup step that injects these values into the execution context.

Step 2: Implementing Dynamic baseUrl in Cypress

Instead of setting baseUrl directly in cypress.json, we will read the base URL from the environment variables inside our configuration file.

Here is how you can modify your cypress.config.js:

// cypress.config.js
const { defineConfig } = require('cypress');

// 1. Read the base URL from process.env
// We default to a safe local value if the variable isn't set, 
// allowing local development to still function correctly.
const baseUrl = process.env.APP_URL || 'http://localhost:8000'; 

module.exports = defineConfig({
  e2e: {
    setupNodeEvents(on, config) {
      // This ensures the environment variable is correctly passed down if needed
      on('before:run', () => {
        // Optionally, you can log the loaded URL for debugging in CI
        console.log(`Cypress running against base URL: ${baseUrl}`);
      });
      return config;
    },
  },
  baseUrl: baseUrl, // 2. Use the dynamically determined variable here
  chromeWebSecurity: false,
});

Explanation of the Approach

  1. Decoupling Configuration: We removed the hardcoded string from cypress.json and moved the logic into cypress.config.js, which is a Node.js file capable of executing JavaScript logic.
  2. Leveraging process.env: The core mechanism relies on accessing process.env. If your Laravel application sets an environment variable like APP_URL=https://staging.myapp.com in the environment where Cypress runs, we can read that value directly into our configuration.
  3. Fallback Mechanism: Including a fallback (|| 'http://localhost:8000') is crucial for local development. If the environment variable is missing (e.g., when running tests locally without setting up complex CI variables), Cypress will still default to working against your local machine, preventing immediate test failures.

Conclusion and Best Practices

By adopting this pattern—reading dynamic configuration from the execution environment rather than hardcoding it—you create a testing layer that is inherently portable and scalable. This aligns perfectly with modern DevOps principles where configuration should be externalized and environment-aware.

When working with Laravel and Cypress, remember that both systems thrive when configuration is separated: Laravel handles application state via .env files, and Cypress handles test execution by reading the runtime environment provided to it. Keep investigating how you can leverage these environment variables across your entire stack, perhaps exploring tools that bridge PHP environment data directly into Node environments for advanced setup tasks on platforms like https://laravelcompany.com.

This dynamic approach ensures your tests are reliable, regardless of whether they are running on your local machine or a remote staging server.