---
title: "Environment Variables"
description: "Load a .env file and read its values in config.php, templates, and plugins, with booleans and null parsed from their spelling."
canonical_url: "https://kirby.tools/docs/helpers/environment-variables"
---

# Environment Variables

> Load a .env file and read its values in config.php, templates, and plugins, with booleans and null parsed from their spelling.

Kirby Helpers loads `.env` files with [phpdotenv](https://github.com/vlucas/phpdotenv), so the file follows its syntax:

```bash [.env]
KIRBY_DEBUG=true
MAIL_FROM=noreply@example.com
```

## Load the File in `config.php`

Load the file at the top of `config.php`, so the options below it can read its values. `Env::load()` takes the directory that holds the file. A second argument names a file other than `.env`.

`Env::load()` throws when the file is missing; where production sets its variables in the server environment, load it only when it exists:

```php [site/config/config.php]
use JohannSchopplich\Helpers\Env;

$root = dirname(__DIR__, 2);

if (is_file($root . '/.env')) {
    Env::load($root);
}

return [
    'debug' => env('KIRBY_DEBUG', false)
];
```

With the Composer install, `Env` and `env()` are autoloaded before Kirby reads `config.php`. A ZIP install loads with the plugins, after `config.php` – read values with [`$site->env()`](#load-the-file-on-first-use) instead.

## Read Values

`env()` reads a variable anywhere once the file is loaded – in `config.php`, templates, snippets, and plugins:

```php [site/templates/default.php]
<?php $mailFrom = env('MAIL_FROM', 'hello@example.com') ?>
```

A missing variable returns the default, which can be a closure that runs only then. A variable set to an empty value returns `''`, not the default.

A variable already set in the server environment wins over the same name in the file. Loaded values are written to `$_ENV` and `$_SERVER`, not to `getenv()`, so a library that reads `getenv()` does not see them.

### Value Parsing

Four spellings are parsed, in any letter case:

<table>
<thead>
  <tr>
    <th>
      Value
    </th>
    
    <th>
      Returns
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        true
      </code>
      
       or <code>
        (true)
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        false
      </code>
      
       or <code>
        (false)
      </code>
    </td>
    
    <td>
      <code>
        false
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        null
      </code>
      
       or <code>
        (null)
      </code>
    </td>
    
    <td>
      <code>
        null
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        empty
      </code>
      
       or <code>
        (empty)
      </code>
    </td>
    
    <td>
      <code>
        ''
      </code>
    </td>
  </tr>
</tbody>
</table>

Numbers stay strings – `PORT=8080` returns `'8080'`, so cast it where you need an integer.

## Load the File on First Use

Without `Env::load()` – as with a ZIP install – `$site->env()` loads the file on its first call, then reads like `env()`:

```php [site/templates/default.php]
<?php $mailFrom = $site->env('MAIL_FROM', 'hello@example.com') ?>
```

When the file is missing, it skips loading and returns the default, unless the server environment sets the variable.

`env.path` sets the directory – Kirby's `base` root when your site defines one, else the folder that holds `site` – and `env.filename` the file name, `.env` by default:

```php [site/config/config.php]
return [
    'johannschopplich.helpers' => [
        'env' => [
            'filename' => '.env.local'
        ]
    ]
];
```

---

Every page of this site as Markdown: <https://kirby.tools/sitemap.md>
