# Universal Environment Configuration

From soya-next-scripts\@0.3.0 and later, environment configuration is embedded during runtime. Therefore, every changes made in the configuration will take effect immediately after restarting the server. It's the opposite of the earlier version which is embedded during compile time and need to be rebuilt before the changes took effect.

## Creating Configuration Files

Environtment configuration in Soya Next is configured using [node-config](https://github.com/lorenwest/node-config). To create one, you need to understand how it works first. By default, node-config will read all your configuration files defined in `config` directory relative to your Soya Next project root. It will read your configuration files with the following order:

```
default.EXT
default-{instance}.EXT
{deployment}.EXT
{deployment}-{instance}.EXT
{short_hostname}.EXT
{short_hostname}-{instance}.EXT
{short_hostname}-{deployment}.EXT
{short_hostname}-{deployment}-{instance}.EXT
{full_hostname}.EXT
{full_hostname}-{instance}.EXT
{full_hostname}-{deployment}.EXT
{full_hostname}-{deployment}-{instance}.EXT
local.EXT
local-{instance}.EXT
local-{deployment}.EXT
local-{deployment}-{instance}.EXT
(Finally, custom environment variables can override all files)
```

Where

* `EXT` can be `yml`, `yaml`, `xml`, `coffee`, `cson`, `properties`, `json`, `json5`, `hjson` or `js` depending on the format you prefer,
* `{instance}` is an optional instance name string for [Multi-Instance Deployments](https://github.com/lorenwest/node-config/wiki/Configuration-Files#multi-instance-deployments).
* `{short_hostname}` is your server name up to the first dot, from the `HOST` or `HOSTNAME` environment variable or `os.hostname()` (in that order). For example if your hostname is `www.example.com` then it would load `www.EXT`.
* `{full_hostname}` is your whole server name, you may use this when `{short_hostname}` collides with other machines.
* `{deployment}` is the deployment name, from the `NODE_ENV` environment variable.

Please refer to this [wiki](https://github.com/lorenwest/node-config/wiki/Configuration-Files) for the full documentation.

## Using Configuration Values

Suppose you have the following configuration at `config/default.json`:

```javascript
{
  "key": "value"
}
```

You can access the configuration values by looking at the example below.

```javascript
import config from "config";

// preferred method, because it make the configuration object immutable
console.log(config.get("key")); // "value"

console.log(config.key); // "value"
```

Please refer to this [wiki](https://github.com/lorenwest/node-config/wiki/Common-Usage) for the full documentation.

## Reserved Configuration Keys

The following are the configurations keys which are reserved:

### `assetPrefix`

* Type: `string`

Prefix added to assets. It will fallback to `basePath` or `basePath.test`.

### `basePath`

* Type: `string` or `{ test: string, exclude: string|Array.<string> }`

Base URL to which the app paths (assets, pages, static) are prefixed.

### `defaultLocale`

* Type: `string`

The default locale used when no locale segment found in the url.

#### Examples

```javascript
{
  "defaultLocale": "id-id",
  "siteLocales": ["id-id", "en-id"]
}
```

### `routes`

* Type: `Object.<Object>`

Define custom routes.

#### Examples

```javascript
{
  "routes": {
    "/p/:id": {
      "page": "/post"
    }
  }
}
```

### `redirects`

* Type: `Object.<Object>`

Redirect obsolete pages.

#### Examples

* Redirect static routes

  ```javascript
  {
    "redirects": {
      "/tentang": {
        "to": "/about"
      }
    }
  }
  ```
* Redirect custom routes

  ```javascript
  {
    "redirects": {
      "/post/:id": {
        "to": "/p/:id"
      }
    },
    "routes": {
      "/p/:id": {
        "page": "/post"
      }
    }
  }
  ```

### `siteLocales`

* Type: `Array.<string>`

All locales which is supported by your app.

#### Examples

```javascript
{
  "defaultLocale": "id-id",
  "siteLocales": ["id-id", "en-id"]
}
```

### `server`

* Type: `Object`
* Default: `{ "host": "0.0.0.0", "port": 3000 }`

For security reasons, the configuration within `server` won't get exposed/hydrated to the client. It **should not** be consumed by the client as well. So if you wanted to consume a secret, it'd be best to store it within `server` and ensure it only got consumed by the server.

#### Examples

```javascript
{
  "server": {
    "secret1": "FIRST_SECRET_KEY",
    "secret2": "SECOND_SECRET_KEY",
    "secret3": "THIRD_SECRET_KEY"
  }
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://traveloka.gitbook.io/soya-next/user-guide/universal-environment-configuration.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
