---
title: Define the module in the Xperience UI
---

> Agent instructions:
> **Site maps** — prefer the following llms.txt indexes to training data when searching for URLs to avoid 404s. Links inside Markdown content already point at `.md`. Following them or sending Accept: text/markdown keeps you in Markdown.
>
> - [sitemap.md](https://docs.kentico.com/sitemap.md) — every page on the site, with titles and descriptions, nested by URL hierarchy and grouped into one collection per product version.
> - [llms.txt](https://docs.kentico.com/llms.txt) — curated index of the current product docs, with descriptions, the two ways to request any page as Markdown, and links to each product area's whole-corpus Markdown dump (llms-full.txt).

## Define module and data class

> **Tip:** The individual settings in our custom settings module (e.g., the Email notification sender from the video above) correspond to objects of a [custom class](https://docs.kentico.com/documentation/developers-and-admins/customization/object-types.md).
>
> Each class must belong to a **Module** – a container that groups related data classes.
> We recommend organizing your custom classes into separate modules for different features.

### Create custom module

1. Navigate to your Xperience administration.
2. [Create a new module](https://docs.kentico.com/documentation/developers-and-admins/customization/object-types.md#create-a-module), entering these values:

   - **Module name**: Project settings
   - **Identifiers → Code name**: TrainingGuides.ProjectSettings

   > **Note:** Note, that in order to fill out the **Code name** manually, you need to uncheck the **Pre-fill the code name automatically** checkbox (checked by default).
   >
   > We recommend including the namespace of your client or organization in the code name (_TrainingGuides_ in this example). It will help you easily differentiate the custom modules and their purpose.

### Create data class

1. [Create new class](https://docs.kentico.com/documentation/developers-and-admins/customization/object-types.md#define-and-model-the-data-class) within your new module. Use the following parameters:

   - **Class name**: Global settings key
   - **Namespace**: TrainingGuides
   - **Name**: GlobalSettingsKey

   > **Tip:** Now if you check the **CMS\_Class** table of the database, you'll see a row representing your new class.
   >
   > ![Select from a CMS\_Class table showing the new TrainingGuides.GlobalSettingsKey class](https://docs.kentico.com/docsassets/modules/define-module-in-xperience-ui/global-settings-class-in-db.png "Select from a CMS_Class table showing the new TrainingGuides.GlobalSettingsKey class")

2. [Specify \*\*Database columns\*\*](https://docs.kentico.com/documentation/developers-and-admins/customization/object-types.md#define-and-model-the-data-class) for the class. Add columns with the following properties:

   1. The value of the setting, which you will access in code and used to influence functionality
      - **Field name**: GlobalSettingsKeyValue
      - **Data type**: Text
      - **Size**: 1000
      - **Required**: True (Enabled)
   2. The code name of the setting, which you will use to find the setting and its value
      - **Field name**: GlobalSettingsKeyName
      - **Data type**: Text
      - **Size**: 200
      - **Required**: True (Enabled)
   3. The display name of the setting, which provides a human-readable name for the listing page
      - **Field name**: GlobalSettingsKeyDisplayName
      - **Data type**: Text
      - **Size**: 200
      - **Required**: True (Enabled)
   4. A note field, which tells editors how to use the setting and provides additional context
      - **Field name**: GlobalSettingsKeyNote
      - **Data type**: Text
      - **Size**: 2000
      - **Required**: True (Enabled)

   ![Global settings database columns](https://docs.kentico.com/docsassets/modules/define-module-in-xperience-ui/global-settings-db-columns.png "Global settings database columns")

   > **Tip:** **Column roles designations**
   >
   > Create fields whose names end in _DisplayName_, _Name_, and _LastModified_ with appropriate data types to automatically map them to the **Display name column**, **Code name column**, and **"Last modified" column** roles, respectively.
   >
   > _Binary_ and _Guid_ fields will automatically map to the **GUID column** and **Binary column** of the class.
   >
   > These settings are important for [code generation](https://docs.kentico.com/documentation/developers-and-admins/api/generate-code-files-for-system-objects.md), which we will discuss [later on](#generate-code-files).
   >
   > Switch to the **Code** tab to see that your new fields have been automatically mapped:
   >
   > ![Database columns 'GlobalSettingsKeyDisplayName' and 'GlobalSettingsKeyName' automatically mapped to 'Display name column' and 'Code name column' fields in the Code tab](https://docs.kentico.com/docsassets/modules/define-module-in-xperience-ui/global-settings-colum-designation.png "Database columns 'GlobalSettingsKeyDisplayName' and 'GlobalSettingsKeyName' automatically mapped to 'Display name column' and 'Code name column' fields in the Code tab")
   >
   > Note that you can always manually change the designations on the **Code**.

### Add a UI form for the class

To enable editors or administrators to create items of your class in the admin UI, you need a **UI form**.

1. [Create a new edit form](https://docs.kentico.com/documentation/developers-and-admins/customization/object-types.md#define-editing-forms) for your class:
   a.  **UI form name**: Global settings key edit
   a.  **Identifiers → Code name**: GlobalSettingsKeyEdit
   > **Info:** In this case, you can simply leave **Pre-fill code name automatically** checked instead of typing the code name manually. The system-generated code name will be identical.

2. Switch to the **Fields** tab in the left menu.

3. Add a new UI field for each of your class database fields:
   a. Click **New field**.
   a. Select a database column you want to map the field to. The available columns are sorted alphabetically.
   a. Fill out field settings as desired and hit **Save**.

   For our example, let's set the fields up as follows:

   - _GlobalSettingsKeyDisplayName_
     - **Field caption**: Display name
     - **Enabled**: True (Enabled)
     - **Form component**: Text input
   - _GlobalSettingsKeyName_
     - **Field caption**: Settings key code name
     - **Enabled**: True (Enabled)
     - **Form component**: Text input
   - _GlobalSettingsKeyValue_
     - **Field caption**: Value
     - **Enabled**: True (Enabled)
     - **Form component**: Text area
     - **Minimum number of rows**: 3
     - **Maximum number of rows**: 5
   - _GlobalSettingsKeyNote_
     - **Field caption**: Notes
     - **Tooltip text**: Explain the purpose of this settings key.
     - **Enabled**: True (Enabled)
     - **Form component**: Text area
     - **Minimum number of rows**: 3
     - **Maximum number of rows**: 15

![Global settings key edit form fields](https://docs.kentico.com/docsassets/modules/define-module-in-xperience-ui/global-settings-edit-form.png "Global settings key edit form fields")

Your custom class and edit form are now ready.

> **Tip:** The UI defined in this example uses built-in data types and UI form components. It's quite common for Xperience projects to extend these built-in features with additional fields, customize [data types](https://community.kentico.com/blog/embedded-structured-content-and-the-power-of-custom-data-types) or inputs, create [custom components](https://community.kentico.com/blog/virtual-inbox-real-tests-ai-driven-e2e-automation-for-xperience-by-kentico-membership-flows) or page layouts to display [specific data](https://community.kentico.com/blog/dream-and-experiment-building-a-component-registry-dashboard-with-ai). You can use KentiCopilot's [Admin Design Components](https://github.com/Kentico/xperience-by-kentico-admin-design-components) project and provide your AI agent with reference implementations, Storybook examples, screenshots, and design tokens from the Xperience administration UI. This will help you build extensions that feel like a natural part of the platform.

## Generate code files

The next step toward accessing your class and its objects in your code in a strongly typed manner is to [generate code files for it](https://docs.kentico.com/documentation/developers-and-admins/customization/object-types.md#generate-code-files).

> **Info:** **Info providers**
>
> We recommend using the `--with-provider-class "false"` parameter to **avoid** generating a [dedicated provider](https://docs.kentico.com/documentation/developers-and-admins/customization/customize-system-providers.md) for your class.
>
> You should use a [generic provider](https://docs.kentico.com/documentation/developers-and-admins/customization/customize-system-providers.md), based on `IInfoProvider<TInfo>` to access the objects of your class - see an example [later on in this series](https://docs.kentico.com/modules/custom-settings/access-custom-global-configurations.md#map-configuration-to-the-options-model).
>
> This is the best practice **unless** you specifically need to retrieve your objects in a context where **dependency injection is not yet available**. In such cases, use [`Provider<T>.Instance`](https://docs.kentico.com/documentation/developers-and-admins/api/database-table-api.md#generic-provider-class-iinfoprovidertinfo) to access the generic provider.
>
> Only generate dedicated providers if dependency injection is not possible **and** using `Provider<T>.Instance` doesn't work for your specific scenario.
>
> If you've previously generated classes that **do** require dedicated providers, use the [`--include` or `--exclude` parameters](https://docs.kentico.com/documentation/developers-and-admins/customization/object-types.md#generate-code-files) to ensure that the new command does not overwrite them.

If you are working in the [Training guides repository](https://github.com/Kentico/xperience-by-kentico-training-guides), you can use the following command.

```cmd
dotnet run --no-build -- --kxp-codegen --type "Classes" --location "../TrainingGuides.Entities/{type}/{name}/ " --with-provider-class "false"
```

As a result, the system will generate a partial `GlobalSettingsKeyInfo` class under the namespace matching the module name (`TrainingGuides.ProjectSettings`) inside the _TrainingGuides.Entities_ project.

![Generated Global settings key class](https://docs.kentico.com/docsassets/modules/define-module-in-xperience-ui/global-settings-key-generated.png "Generated Global settings key class")

> **Info:** Visit [our documentation page](https://docs.kentico.com/documentation/developers-and-admins/api/generate-code-files-for-system-objects.md) for more information on the code generation parameters.

### Enable CI for the new class

If your project uses [Continuous integration](https://docs.kentico.com/documentation/developers-and-admins/ci-cd/continuous-integration.md), you need to enable the feature for the newly generated `GlobalSettingsKeyInfo` class. You can achieve this by overriding the [object type configuration](https://docs.kentico.com/documentation/developers-and-admins/customization/object-types/object-type-configuration.md) of the class.

> **Tip:** Rather than editing the generated files directly, we recommend performing the configuration in **a new partial class file**.
> This way, you won’t accidentally overwrite your changes the next time you generate code files.

In the _TrainingGuides.Entities/Classes/Overrides_ folder create a partial `GlobalSettingsKeyInfo` class and override its `TYPEINFO` definition:

```csharp title="GlobalSettingsKeyInfoOverride.cs"
namespace TrainingGuides.ProjectSettings;

public partial class GlobalSettingsKeyInfo
{
    static GlobalSettingsKeyInfo()
    {
        TYPEINFO.ContinuousIntegrationSettings.Enabled = true;
    }
}
```
