Drupalwoo ☉

How to Use Drupal’s Configuration API for Site Settings

Drupal’s Configuration API provides a structured way to store and manage site settings, from the site name and default language to custom module options and editorial preferences. Instead of scattering values through PHP files or editing the database directly, developers can define settings that Drupal can validate, export, version, and deploy between environments.

This approach is especially useful for Australian websites that move between local development, staging, and production. A Drupal site serving visitors in Sydney, Melbourne, Perth, or regional areas may need environment-specific URLs, Australian Eastern or Western time zones, privacy-related controls, and settings that can be reviewed alongside application code.

Understanding Drupal Configuration

Configuration is structured data that controls how a Drupal site behaves. Examples include the site slogan, enabled modules, text formats, image styles, views, user roles, and settings supplied by contributed or custom modules. Drupal stores active configuration in the database and can export it as YAML files for deployment.

Each configuration object has a name, such as system.site or system.performance, and contains one or more values. A configuration name normally uses a dot-separated format: the module or subsystem name followed by the feature name. Custom modules commonly use names such as example.settings.

The Configuration API distinguishes between simple configuration and configuration entities. Simple configuration is suitable for one site-wide set of values, such as an API endpoint or a support email address. Configuration entities represent collections of reusable or administrable items, including views, image styles, roles, and content types.

Configuration should not be confused with content. A landing page, product, or news article belongs in Drupal’s content system. A setting that changes the behaviour of a module belongs in configuration. This distinction makes deployments more predictable and avoids overwriting editorial updates when configuration is synchronised.

Reading And Writing Settings In Code

Drupal services provide the preferred way to access configuration. Inject the config.factory service into a class, then use get() for read-only access or getEditable() when a value must be changed programmatically.

$config = $this->configFactory->get('example.settings');

$api_url = $config->get('api_url');
$enabled = $config->get('enabled');

A write operation should be explicit and limited to an administrative workflow, update hook, or installation process:

$this->configFactory
  ->getEditable('example.settings')
  ->set('enabled', TRUE)
  ->set('api_url', 'https://api.example.com')
  ->save();

In a service class, constructor injection keeps the code testable:

use Drupal\Core\Config\ConfigFactoryInterface;

public function __construct(
  ConfigFactoryInterface $config_factory
) {
  $this->configFactory = $config_factory;
}

For a quick procedural operation, Drupal’s global configuration factory is available through \Drupal::config(), but dependency injection is preferable in controllers, plugins, forms, and services. It makes dependencies visible and avoids tightly coupling application logic to Drupal’s static service locator.

Configuration objects should be treated as immutable when they are read. If a value is changed without calling save(), the active configuration remains unchanged. Developers should also avoid putting passwords, private tokens, or other secrets into exportable configuration. Use environment variables, settings.php, a secrets manager, or a protected hosting configuration for sensitive values.

Defining Custom Module Settings

A custom module usually defines its default settings in a file such as:

example/config/install/example.settings.yml

A simple file might contain:

enabled: true
api_url: 'https://api.example.com'
items_per_page: 20

The module’s configuration schema belongs in:

example/config/schema/example.schema.yml

For the preceding values, a schema can look like this:

example.settings:
  type: config_object
  label: 'Example settings'
  mapping:
    enabled:
      type: boolean
      label: 'Enabled'
    api_url:
      type: uri
      label: 'API URL'
    items_per_page:
      type: integer
      label: 'Items per page'

The schema describes data types and labels. It supports configuration translation, improves validation and inspection, and helps Drupal understand how configuration should be handled. Every custom configuration object should have a schema, even if the values appear simple.

Default configuration in config/install is imported when the module is installed. Editing that file later does not automatically change settings on an existing site. For changes to already-installed sites, use an update hook, a post-update function, or an explicit configuration import. This distinction is important when a module is maintained through Git and deployed to a production site.

The module’s .info.yml file should include the required core version and any dependencies. If the setting is intended for administrators, provide a configuration form rather than asking editors to modify YAML files. A form also gives the site a controlled place to validate URLs, numeric limits, labels, and optional values.

Building A Configuration Form

A configuration form normally extends ConfigFormBase. It declares the configuration names it edits, builds Form API elements, and saves submitted values through the configuration factory.

namespace Drupal\example\Form;

use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;

final class SettingsForm extends ConfigFormBase {

  public function getFormId() {
    return 'example_settings_form';
  }

  protected function getEditableConfigNames() {
    return ['example.settings'];
  }

  public function buildForm(array $form, FormStateInterface $form_state) {
    $config = $this->config('example.settings');

    $form['enabled'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Enable integration'),
      '#default_value' => $config->get('enabled'),
    ];

    $form['api_url'] = [
      '#type' => 'url',
      '#title' => $this->t('API URL'),
      '#default_value' => $config->get('api_url'),
      '#required' => TRUE,
    ];

    return parent::buildForm($form, $form_state);
  }

  public function submitForm(array &$form, FormStateInterface $form_state) {
    $this->configFactory->getEditable('example.settings')
      ->set('enabled', $form_state->getValue('enabled'))
      ->set('api_url', $form_state->getValue('api_url'))
      ->save();

    parent::submitForm($form, $form_state);
  }

}

The route and menu link should restrict access with an appropriate permission. A custom permission such as administer example settings is safer than granting access broadly to every authenticated user. Add the permission in the module’s example.permissions.yml file and reference it from the route definition.

Validation belongs in the form when a value can be checked immediately. For instance, a URL field can reject malformed addresses, while a numeric field can enforce a sensible minimum and maximum. Additional runtime checks are still useful because configuration may be imported from another environment or changed through Drush.

For larger settings forms, group related controls with details elements and provide descriptions that explain operational consequences. An option controlling cache lifetime, for example, should tell administrators whether it affects anonymous visitors, authenticated users, or external reverse proxies. Clear labels reduce accidental changes during busy publishing periods.

Exporting And Deploying Configuration

Drupal’s configuration synchronisation process exports active configuration to YAML and imports that YAML into another environment. Common Drush commands include:

drush config:export
drush config:import
drush config:status

The exact command aliases may vary by Drush version, but the workflow remains the same. Export changes from a development site, review the YAML files, commit them to version control, and import them into staging or production. The active configuration hash helps Drupal identify whether imported configuration matches the database.

Before using this process on a live website, create a database backup and review the proposed changes. An import can alter permissions, fields, views, caching, and enabled modules. It can also remove configuration that exists in the target environment but is absent from the synchronisation directory.

A staging environment is valuable for testing configuration imports, cache rebuilds, and permission changes. The Pantheon staging guide provides relevant background for teams using a hosted Drupal workflow. This is particularly useful when a site has separate development, staging, and production branches.

Keep environment-specific values outside ordinary synchronised configuration where appropriate. A production API endpoint, database connection detail, or private key should not be committed to a public repository. Drupal’s settings.php can override configuration at runtime, although these overrides are read-only from the configuration management interface and should be documented clearly.

Australian teams should also agree on a deployment window that suits the site’s audience. A retailer serving shoppers in Melbourne and Brisbane may prefer low-traffic periods based on Australian Eastern time, while a national organisation should consider Western Australia and the Northern Territory before scheduling maintenance. Configuration deployment should be treated as a release rather than an informal database edit.

Managing Localised And Regulated Site Settings

Drupal’s configuration translation features allow translatable configuration values to vary by language. Site name, menus, form labels, and module settings may require translation where an organisation publishes in multiple languages. The configuration schema is essential because Drupal uses it to identify translatable values correctly.

Regional settings should be deliberate rather than inherited accidentally from the server. Configure the site’s default time zone and date formats for the organisation’s operating region. A national Australian service may use Australia/Sydney for business operations, while a Western Australian organisation may require Australia/Perth. Date displays should remain clear for users who interact with deadlines, bookings, or public notices.

Privacy settings also deserve configuration review. A site collecting contact details, mailing-list subscriptions, or analytics data should align its forms and integrations with the Privacy Act 1988 and the Australian Privacy Principles where those obligations apply. Configuration can control retention periods, consent wording, third-party services, and whether optional tracking is enabled, but legal responsibility still requires a broader privacy review.

Accessibility and communications preferences are similarly practical concerns. Australian government and larger institutional websites often work towards WCAG-based accessibility requirements, so settings for text formats, media handling, captions, and editor permissions should support that objective. Drupal configuration cannot fix inaccessible content by itself, but it can constrain risky formats and give editors safer defaults.

Setting approach Best use Deployment behaviour Main caution
Default YAML in config/install Initial values for a new module installation Imported when the module is installed Later file edits do not update existing sites
Active configuration API Reading or changing site-wide settings Stored in Drupal’s active configuration Avoid writing settings during ordinary page requests
Configuration form Administrator-controlled options Saves validated values to active configuration Protect the route with a specific permission
Configuration synchronisation Moving reviewed settings between environments Exports and imports YAML files Review removals and environment-specific values
settings.php override Secrets and runtime-specific values Applied at runtime, outside normal imports Overrides can confuse administrators if undocumented

Practical Recommendations For Reliable Configuration

A consistent configuration strategy prevents many deployment and maintenance problems. Treat YAML files as code, review changes in version control, and document settings that differ between local, staging, and production environments. Configuration names should be stable and descriptive so that future developers can locate them quickly.

Test configuration forms with empty values, invalid URLs, missing optional keys, and imported data from older versions. When a setting changes shape, provide an update hook or post-update function that migrates existing data. Do not assume that a fresh installation test covers the upgrade path used by a busy Australian production website.

Useful habits for Drupal developers and administrators include:

The Configuration API becomes most effective when it is treated as part of the site’s release process. A setting should have a clear owner, a sensible default, validation appropriate to its purpose, and a known path from development to production. With those controls in place, Drupal site settings remain portable, auditable, and safer to manage as the website grows.