Best practice for splitting your Configuration File

Last modified: November 26th, 2025

It is important to find the right balance between organization and maintainability when splitting your Site configuration across multiple Configuration Files. If you split your configuration too granularly, finding a specific configuration can be as difficult as if it were all in the same file.

When you split your configuration, we recommend starting with a single section (e.g., one Collection under collections_config or your Site-scope Inputs under _inputs) and testing that the configuration behaves as expected before moving on to other sections.

Let's walk through a list of best practices to help you split your configuration. All these examples are optional, but might help you determine the right balance for splitting your Site configuration.

Create a dedicated Configuration File for each Collection#

If you have many Collections on your Site, scrolling through all your configuration to find the right one is not efficient. In this case, it might be easier to create a dedicated Configuration File for each Collection, rather than list each one in your main CloudCannon Configuration File.

In this example, we have two Collections: Pages and Posts.

cloudcannon.config.yaml
copied
collections_config:
  pages:
    path: content
    icon: wysiwyg
  posts:
    path: content/posts
    icon: event
    preview:
      text:
        - key: title
      subtext:
        - key: author
      metadata:
        - icon: event
          text:
            - template: Published on {date|date_long}
cloudcannon.config.json
copied
{
  "collections_config": {
    "pages": {
      "path": "content",
      "icon": "wysiwyg"
    },
    "posts": {
      "path": "content/posts",
      "icon": "event",
      "preview": {
        "text": [
          {
            "key": "title"
          }
        ],
        "subtext": [
          {
            "key": "author"
          }
        ],
        "metadata": [
          {
            "icon": "event",
            "text": [
              {
                "template": "Published on {date|date_long}"
              }
            ]
          }
        ]
      }
    }
  }
}

We can move all the content under each Collection key into the dedicated files, pages.cloudcannon.collections.yml and posts.cloudcannon.collections.yml, in a new folder, .cloudcannon/collections/. Then, we can reference all Collection Configuration Files in the new folder using the collections_config_from_glob key in our main CloudCannon Configuration File.

cloudcannon.config.yaml
copied
collections_config_from_glob:
  - /.cloudcannon/collections/*.cloudcannon.collections.yml
cloudcannon.config.json
copied
{
  "collections_config_from_glob": [
    "/.cloudcannon/collections/*.cloudcannon.collections.yml"
  ]
}
pages.cloudcannon.collections.yaml
copied
pages:
  path: content
  icon: wysiwyg
pages.cloudcannon.collections.json
copied
{
  "pages": {
    "path": "content",
    "icon": "wysiwyg"
  }
}
posts.cloudcannon.collections.yaml
copied
posts:
  path: content/posts
  icon: event
  preview:
    text:
      - key: title
    subtext:
      - key: author
    metadata:
      - icon: event
        text:
          - template: Published on {date|date_long}
posts.cloudcannon.collections.json
copied
{
  "posts": {
    "path": "content/posts",
    "icon": "event",
    "preview": {
      "text": [
        {
          "key": "title"
        }
      ],
      "subtext": [
        {
          "key": "author"
        }
      ],
      "metadata": [
        {
          "icon": "event",
          "text": [
            {
              "template": "Published on {date|date_long}"
            }
          ]
        }
      ]
    }
  }
}

Create chains of Configuration Files#

When you split your Site configuration across multiple Configuration Files, your main Configuration File will point to other Configuration Files on your Site using *_from_glob keys.

However, you can also use *_from_glob key in any other Configuration File, allowing you to create chains of configuration across several files. As long as every Configuration File ultimately connects back to your main Configuration File, CloudCannon will be able to merge your configuration.

cloudcannon.config.yaml
copied
collections_config_from_glob:
  - /.cloudcannon/collections/*.cloudcannon.collections.yml
cloudcannon.config.json
copied
{
  "collections_config_from_glob": [
    "/.cloudcannon/collections/*.cloudcannon.collections.yml"
  ]
}
/.cloudcannon/collections/posts.cloudcannon.collections.yaml
copied
posts:
  path: content/posts
  icon: event
  schemas_from_glob:
    - /.cloudcannon/schemas/blogPost.cloudcannon.schemas.yml
    - /.cloudcannon/schemas/companyAnnouncement.cloudcannon.schemas.yml
    - /.cloudcannon/schemas/caseStudy.cloudcannon.schemas.yml
/.cloudcannon/collections/posts.cloudcannon.collections.json
copied
{
  "posts": {
    "path": "content/posts",
    "icon": "event",
    "schemas_from_glob": [
      "/.cloudcannon/schemas/blogPost.cloudcannon.schemas.yml",
      "/.cloudcannon/schemas/companyAnnouncement.cloudcannon.schemas.yml",
      "/.cloudcannon/schemas/caseStudy.cloudcannon.schemas.yml"
    ]
  }
}

Use negative globs for finer control#

The value of each *_from_glob key is an array of strings, where each string is a glob pattern matching specific files on your Site. You can use the array to specify multiple files. However, if you want to match all files with a few exceptions, it is more efficient to use a negative glob.

In this example, we have several Schema Configuration Files in the .cloudcannon/schemas/ folder (e.g., Announcement, Customer Story, Blog, Pages). We want to use most, but not all, of these Schemas in our Posts Collection.

/.cloudcannon/collections/posts.cloudcannon.collections.yaml
copied
posts:
  path: content/posts
  icon: event
  schemas_from_glob:
    - /.cloudcannon/schemas/*.cloudcannon.schemas.yml
    - '!/.cloudcannon/schemas/pages.cloudcannon.schemas.yml'
/.cloudcannon/collections/posts.cloudcannon.collections.json
copied
{
  "posts": {
    "path": "content/posts",
    "icon": "event",
    "schemas_from_glob": [
      "/.cloudcannon/schemas/*.cloudcannon.schemas.yml",
      "!/.cloudcannon/schemas/pages.cloudcannon.schemas.yml"
    ]
  }
}

We can tell CloudCannon to use all Schema Configuration Files in this folder using the *.cloudcannon.schemas.yml glob, but exclude pages.cloudcannon.schemas.yml by prefixing the string with an ! character to create a negative glob.

Your Configuration Files can contain multiple entries for object configuration keys, allowing you to store related configuration together in the same file.

cloudcannon.config.yaml
copied
collections_config:
  posts:
    path: content/posts
    icon: event
    inputs_from_glob:
      - /.cloudcannon/inputs/seo.cloudcannon.inputs.yml
      - /.cloudcannon/inputs/blog-details.cloudcannon.inputs.yml
cloudcannon.config.json
copied
{
  "collections_config": {
    "posts": {
      "path": "content/posts",
      "icon": "event",
      "inputs_from_glob": [
        "/.cloudcannon/inputs/seo.cloudcannon.inputs.yml",
        "/.cloudcannon/inputs/blog-details.cloudcannon.inputs.yml"
      ]
    }
  }
}
/.cloudcannon/inputs/seo.cloudcannon.inputs.yaml
copied
seo_title:
  type: text
  options:
    required: true
    max_length: 50
seo_description:
  type: textarea
  options:
    show_count: true
    required: true
    max_length: 125
seo_image:
  type: image
  options:
    path:
      uploads: images
    accepts_mime_types:
      - image/png
      - image/jpeg
    required: true
    pattern: (?i)\.(jpe?g|png)$
    pattern_message: Please select a JPG or PNG image file
/.cloudcannon/inputs/seo.cloudcannon.inputs.json
copied
{
  "seo_title": {
    "type": "text",
    "options": {
      "required": true,
      "max_length": 50
    }
  },
  "seo_description": {
    "type": "textarea",
    "options": {
      "show_count": true,
      "required": true,
      "max_length": 125
    }
  },
  "seo_image": {
    "type": "image",
    "options": {
      "path": {
        "uploads": "images"
      },
      "accepts_mime_types": [
        "image/png",
        "image/jpeg"
      ],
      "required": true,
      "pattern": "(?i)\\.(jpe?g|png)$",
      "pattern_message": "Please select a JPG or PNG image file"
    }
  }
}

Use split and inline configuration in the same file#

You don't have to split all your configuration into separate files. Instead, you can use inline configuration and reference other Configuration Files using *_from_glob keys simultaneously.

cloudcannon.config.yaml
copied
_inputs_from_glob:
  - /.cloudcannon/inputs/seo.cloudcannon.inputs.yml
  - /.cloudcannon/inputs/blog-details.cloudcannon.inputs.yml
_inputs:
  authors:
    type: multiselect
    options:
      values: collections.authors
cloudcannon.config.json
copied
{
  "_inputs_from_glob": [
    "/.cloudcannon/inputs/seo.cloudcannon.inputs.yml",
    "/.cloudcannon/inputs/blog-details.cloudcannon.inputs.yml"
  ],
  "_inputs": {
    "authors": {
      "type": "multiselect",
      "options": {
        "values": "collections.authors"
      }
    }
  }
}

Configuring Structures inside Inputs#

It is important to note the correct places to use _structures_from_glob and values_from_glob. CloudCannon expects .cloudcannon.structures.yml Configuration Files need to have the Structure key at the root of the file, while .cloudcannon.structure-value.yml Configuration Files only contain the keys for a single array item.

The following configuration is incorrect, as the _structures key is not the same as the _inputs.*.options.structures key:

cloudcannon.config.yaml
copied
_inputs:
  staff:
    type: array
    options:
      _structures_from_glob:
        - /.cloudcannon/structures/staffTypes.cloudcannon.structure.yml
cloudcannon.config.json
copied
{
  "_inputs": {
    "staff": {
      "type": "array",
      "options": {
        "_structures_from_glob": [
          "/.cloudcannon/structures/staffTypes.cloudcannon.structure.yml"
        ]
      }
    }
  }
}

Instead, use one of the following configurations:

cloudcannon.config.yaml
copied
_structures:
  staffTypes:
    style: modal
    values:
      - label: Employee
        value:
          name: 
          job_description: 
          profile_picture: 
_inputs:
  staff:
    type: array
    options:
      structures: _structures.staffTypes
cloudcannon.config.json
copied
{
  "_structures": {
    "staffTypes": {
      "style": "modal",
      "values": [
        {
          "label": "Employee",
          "value": {
            "name": null,
            "job_description": null,
            "profile_picture": null
          }
        }
      ]
    }
  },
  "_inputs": {
    "staff": {
      "type": "array",
      "options": {
        "structures": "_structures.staffTypes"
      }
    }
  }
}
cloudcannon.config.yaml
copied
_structures_from_glob:
  - /.cloudcannon/structures/staffTypes.cloudcannon.structure.yml
_inputs:
  staff:
    type: array
    options:
      structures: _structures.staffTypes
cloudcannon.config.json
copied
{
  "_structures_from_glob": [
    "/.cloudcannon/structures/staffTypes.cloudcannon.structure.yml"
  ],
  "_inputs": {
    "staff": {
      "type": "array",
      "options": {
        "structures": "_structures.staffTypes"
      }
    }
  }
}
cloudcannon.config.yaml
copied
_inputs:
  staff:
    type: array
    options:
      structures:
        values_from_glob: /.cloudcannon/structures/staffTypes.cloudcannon.structure-value.yml
cloudcannon.config.json
copied
{
  "_inputs": {
    "staff": {
      "type": "array",
      "options": {
        "structures": {
          "values_from_glob": "/.cloudcannon/structures/staffTypes.cloudcannon.structure-value.yml"
        }
      }
    }
  }
}

Open in a new tab