Dynamically set baseUrl in cypress.json
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
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
- Decoupling Configuration: We removed the hardcoded string from
cypress.jsonand moved the logic intocypress.config.js, which is a Node.js file capable of executing JavaScript logic. - Leveraging
process.env: The core mechanism relies on accessingprocess.env. If your Laravel application sets an environment variable likeAPP_URL=https://staging.myapp.comin the environment where Cypress runs, we can read that value directly into our configuration. - 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.