How to modify the behavior of Qgoda.

The Qgoda configuration is straightforward and has sane defaults. In fact, Qgoda runs without any configuration and you only have to configure Qgoda, when you want to change a certain behavior.

Configuration Files

Qgoda has two optional configuration files, _qgoda.yaml and _localqgoda.yaml. If you prefer, you can also use the file extension .yml or .json, if you write the configuration in JSON format.

Qgoda Configuration Layers
The different configuration layers of Qgoda

The configuration found in _qgoda.yaml overrides the built-in defaults, and the configuration found in _localqgoda.yaml overrides both _qgoda.yaml and the the built-in defaults.

More precisely, each layer of configuration is merged with the previous one and overrides only those parts that differ.

You can always check the actual configuration used with the command qgoda config which dumps the resulting configuration to the console.

Why _localconfig.yaml?

Qgoda, like most static site generators, works very well with git and you may want to publish the site sources to a public git repository.

But what if you have to put API keys, secrets, private information, local hostnames or local debugging settings into the configuration? In all these cases you can use _localconfig.yaml. You will normally not commit that file to the public repository but use it for local use only.

Accessing Configuration Variables From Templates

The entire configuration of the site is accessible in the template variable config:

    <title>[% config.title | html %]
    <h1>[% config.title | html %]</h1>
    <div>[% asset.content %]</div>

This is how you would access the configuration variable title from a template.

JSON Schema

In order to protect you against incorrect configurations, your settings are validated against a JSON schema. You can even see that schema with the command qgoda schema. Try qgoda schema --help for information about different output formats of the schema.

While writing a schema is not that trivial, reading it is relatively easy.


Reading the configuration and validating it against the schema is done in JavaScript with Ajv, an advanced and fast validator. The Qgoda configuration schema complies to draft 07 of the JSON schema specification.


The defaults for all configuration options are part of the schema.

Type Coercion

JSON schema is strict about data types. If an array is expected for a certain configuration variable it would normally be a mistake to give a string. But Qgoda uses type coercion and will automatically convert a single value into an array for you.

Likewise, a boolean option actually requires either true or false. With type coercion you can use 0, an empty string or null as an alias for false, and pretty much everything else is interpreted as true. See the complete table at for the complete story.

Program Paths

It is very often necessary to configure a path to a program in _qgoda.yaml for example in helpers or po.xgettext or others. This is a special case where type coercion helps you to simplify the configuration.

Without Arguments

If the program does not take any arguments, you can pass it as a single string, for example:

  assets: webpack

With Arguments

If the program should be invoked with arguments, use an array instead:

  - webpack
  - --progress
  - --colors
  - --watch

Or use this equivalent syntax for arrays:

  assets: ['webpack', '--progress', '--colors', '--watch']

Adding Your Own Configuration Variables

Your own configuration variables have to start either with site or private.

All other possible configuration variables are reserved by Qgoda, and those support have a fixed syntax and you must adhere to it. This is a meant as a protection against typos. As a consquence, you cannot add a configuration variable paths.home because the "slot" or namespace paths is already taken by Qgoda.

This, however, would be safe:

    images: _assets/images
  author: Yours truly <>
    api-key: eC0GFio3Tz==
This website uses cookies and similar technologies to provide certain features, enhance the user experience and deliver content that is relevant to your interests. Depending on their purpose, analysis and marketing cookies may be used in addition to technically necessary cookies. By clicking on "Agree and continue", you declare your consent to the use of the aforementioned cookies. Here you can make detailed settings or revoke your consent (in part if necessary) with effect for the future. For further information, please refer to our Privacy Policy.