Environment Detector, one reliable answer to where your site is running
The question a site answers before anything else: which environment is this?
A surprising amount of what a website does depends on knowing where it is running:
- debug output belongs on a developer's machine and nowhere near the public site
- caching should be aggressive in production and out of the way while someone is working
- sample content and test users are useful in a throwaway preview build and unwelcome anywhere else
- emails should only reach real customers from the real site
So every project asks the same question early in its startup: what kind of environment is this?
The awkward part is that each hosting platform answers it differently, with its own signals and its own vocabulary for its tiers, so the environment a team integrates in goes by a different name on each one.
The result is familiar. Each project grows its own small block of detection code, written fresh, a little different from the last one.
It holds up until a platform adds a tier or a project gains an environment that block was never told about. Then the site behaves as though it were somewhere else, in the one place where being wrong is expensive.
One call, nothing to configure: 6 environment types
environment-detector(Opens in a new tab/window) answers the question in a single call, with no setup. It resolves the environment to one of 6 types:
- local
- CI (an automated build)
- development
- preview
- stage
- production
Everything else in the codebase simply branches on the answer.
It recognises where that code is running:
- the hosting platforms teams actually run on: Acquia, Lagoon, Pantheon, Platform.sh, Skpr and Tugboat
- the automated build systems where the same code also runs: GitHub Actions, GitLab CI and CircleCI
- what it is sitting in underneath: a plain machine, a container, or a local development tool such as DDEV or Lando
Telling a preview apart from development is worth more than it sounds. A short-lived environment built for a single change is not the shared space a team integrates in, and once the difference is visible in code, the settings that follow can finally be right.
For a client, that reads as a preview link that behaves like a preview, and a production site that behaves like production.
Built so a wrong answer is loud: it stops instead of guessing
A detector is only worth having if you can trust it, so the design prefers certainty over cleverness.
A single hosting platform can be active at a time. If 2 announce themselves at once, that is a genuine misconfiguration rather than a riddle to solve, so the library stops instead of guessing.
When a platform is active but cannot place an environment in a tier it recognises, the fallback leans the safe way, towards a shared development environment, and it does not downgrade a platform already known to be production.
There are 2 failures worth engineering against: local settings reaching the live site, and production settings reaching a laptop. The design guards against both rather than relying on everyone remembering.
For a client, that reads as one less way for a site to misbehave after a deploy: debug output, caching and test data follow the environment the code landed in.
One line in a Drupal settings file, and a plain call anywhere in PHP
For Drupal(Opens in a new tab/window) the integration is a single line in the site's settings file. That line works out the environment and applies the settings that belong with it, so trusted hosts, file paths and caching are correct wherever the code has landed, with no per-project block to maintain.
Outside Drupal it works through a plain call in any PHP application. It is also built to be extended, with the same pieces the built-in platforms and frameworks use.
Drupal is the framework integration that ships today, and the model underneath it was designed to be framework-agnostic from the start.
Why we keep it public: shipped in Vortex, free to adopt
Solving this once is the entire argument. It ships as part of Vortex(Opens in a new tab/window), our open-source Drupal project template, so every project we start already knows where it is running, and supporting a new host becomes a package update rather than an edit in every codebase.
One call, 6 environment types, and the same answer on every supported host.
It is open source and free to use, published on GitHub(Opens in a new tab/window), so any team can adopt it without ever speaking to us. That is deliberate.
This is unglamorous plumbing, it is the same in every project, and no budget should be paying to write it a second time.
When we take on a platform, that habit comes with us: the generic parts are already solved, so the effort goes where your platform is actually different.
For teams whose environment logic is hand-written in every project
Everything on this page is 2 of our services pointed at our own tooling: the development of the library itself, and the ongoing support and maintenance that keeps it current as hosting platforms change. The same standard applies to our AI-assisted delivery: whatever writes the change, the environment it lands in is decided by one tested library rather than by a block of code copied between projects.
If you run a Drupal or PHP platform whose settings file carries its own environment logic, or a team working across several hosts that each name their tiers differently, this is the shape the engagement takes. The detection moves into one tested library, the per-environment settings follow from it, and adding a host later is a version bump instead of an edit in every repository.
If nobody on your team can say for certain what your production site would do on the day it decided it was staging, send us your settings file.