Customizing Directus Default Fields: A Complete Guide
Learn how to make system fields in Directus collections (like directus_users) editable, rearrange and hide default fields to improve the user experience.
Abdallah AwwadFull Stack Developer

18 min read

3 days ago

Directus

Introduction

In many Directus projects, you might find yourself needing to customize the default system collections such as directus_users, directus_roles, directus_files, or other core collections. While creating separate collections might seem like a solution, it's often more practical to extend the existing system collections. However, this presents a challenge: the default fields can't be easily rearranged or hidden through the standard interface.

This guide will show you how to:

  1. Customize the default `directus_users` collection fields
  2. Organize fields using the Group Tabs interface
  3. Hide unnecessary fields
  4. Improve the overall user experience

Editable Users Collection

Understanding Directus System Collections

Directus system collections (like directus_users, directus_roles, directus_files, etc.) are defined in the Directus source code. The field configurations for these collections are stored in YAML files within the Directus repository. For example, the users collection configuration can be found in the Directus GitHub repository.

The techniques described in this guide can be applied to any Directus system collection, not just the users collection. This means you can customize the appearance and behavior of fields in collections like:

  • directus_roles
  • directus_files
  • directus_folders
  • directus_permissions
  • And other system collections

Prerequisites

  1. Directus instance with admin access
  2. Group Tabs Interface Extension installed
  3. API tool like Postman or similar for making the PATCH requests

⚠️ Important Disclaimers

Before we dive into the customization process, please note the following important points:

  • Use at your own risk: This customization involves modifying system fields which may affect core functionality.
  • Test First: Always test these changes on a non-production instance before applying them to your live environment.
  • Backup Regularly: Before applying these or any significant system modifications, always ensure you have a complete backup of your Directus instance (database and files).
  • Known Issues:
    • The policies field appears visually duplicated in the interface and cannot be properly arranged (solution: hide it) - though it functions correctly
    • Three fields are not being properly translated:
      • tfa_secret
      • Dark Theme Overrides (shows as 'Overrides' instead of 'Customization')
      • Light Theme Overrides (shows as 'Overrides' instead of 'Customization')
    • Dividers that need to be hidden:
      • Preferences divider
      • Theme divider
      • Admin divider
    • A persistent horizontal rule (hr) element may still appear, but can be partially hidden using the appearance tab with a single CSS line

Step 1: Understanding the Current Structure

The default Directus users collection comes with several predefined fields that are essential for the system's functionality. These include:

  • Basic information (id, first_name, last_name, email)
  • Authentication (password, token)
  • Preferences (language, appearance)
  • Administrative fields (role, status)

Step 2: Understanding How to Modify System Fields

When you create new fields in Directus, the system automatically creates corresponding entries in the directus_fields collection. However, system fields (like those in directus_users) don't have these entries by default, which is why you can't modify them through the standard interface.

To make system fields editable, we need to create corresponding entries in the directus_fields collection and use the PATCH endpoint to update their configurations.

Step 3: Making the API Request

The field configurations we'll use are based on the original definitions from the Directus source code, specifically from the users.yaml file.

Show cURL Request & JSON Configuration
curl -X PATCH 'https://your-directus-instance/fields/directus_users' \
-H 'Authorization: Bearer YOUR-TOKEN' \
-H 'Content-Type: application/json' \
-d '[
  {
    "field": "id",
    "meta": {
      "special": ["uuid"],
      "interface": "input",
      "options": {
        "iconRight": "vpn_key"
      }
    }
  },
  {
    "field": "first_name",
    "meta": {
      "interface": "input",
      "options": {
        "iconRight": "account_circle"
      },
      "width": "half"
    }
  },
  {
    "field": "last_name",
    "meta": {
      "interface": "input",
      "options": {
        "iconRight": "account_circle"
      },
      "width": "half"
    }
  },
  {
    "field": "email",
    "meta": {
      "interface": "input",
      "options": {
        "iconRight": "account_circle"
      },
      "width": "half"
    }
  },
  {
    "field": "password",
    "meta": {
      "special": ["hash", "conceal"],
      "interface": "input-hash",
      "options": {
        "iconRight": "lock",
        "masked": true
      },
      "width": "half"
    }
  },
  {
    "field": "avatar",
    "meta": {
      "interface": "file",
      "display": "image"
    }
  },
  {
    "field": "location",
    "meta": {
      "interface": "input",
      "options": {
        "iconRight": "place"
      },
      "width": "half"
    }
  },
  {
    "field": "title",
    "meta": {
      "interface": "input",
      "options": {
        "iconRight": "work"
      },
      "width": "half"
    }
  },
  {
    "field": "description",
    "meta": {
      "interface": "input-multiline"
    }
  },
  {
    "field": "tags",
    "meta": {
      "interface": "tags",
      "special": ["cast-json"],
      "options": {
        "iconRight": "local_offer"
      },
      "display": "labels",
      "display_options": {
        "choices": null,
        "format": false
      }
    }
  },
  {
    "field": "preferences_divider",
    "meta": {
      "interface": "presentation-divider",
      "options": {
        "icon": "face",
        "title": "$t:fields.directus_users.user_preferences"
      },
      "special": ["alias", "no-data"],
      "hidden": true
    }
  },
  {
    "field": "language",
    "meta": {
      "interface": "system-language",
      "width": "half",
      "options": {
        "includeProjectDefault": true
      }
    }
  },
  {
    "field": "tfa_secret",
    "meta": {
      "interface": "system-mfa-setup",
      "special": ["conceal"],
      "width": "half"
    }
  },
  {
    "field": "email_notifications",
    "meta": {
      "interface": "boolean",
      "width": "half",
      "special": ["cast-boolean"]
    }
  },
  {
    "field": "theming_divider",
    "meta": {
      "interface": "presentation-divider",
      "options": {
        "icon": "palette",
        "title": "$t:theme"
      },
      "special": ["alias", "no-data"],
      "hidden": true
    }
  },
  {
    "field": "appearance",
    "meta": {
      "interface": "select-dropdown",
      "options": {
        "choices": [
          {
            "value": null,
            "text": "$t:default_sync_with_project"
          },
          {
            "value": "auto",
            "text": "$t:appearance_auto"
          },
          {
            "value": "light",
            "text": "$t:appearance_light"
          },
          {
            "value": "dark",
            "text": "$t:appearance_dark"
          }
        ]
      },
      "width": "half"
    }
  },
  {
    "field": "theme_light",
    "meta": {
      "interface": "system-theme",
      "options": {
        "appearance": "light",
        "includeNull": true
      }
    }
  },
  {
    "field": "theme_light_overrides",
    "meta": {
      "interface": "system-theme-overrides",
      "options": {
        "appearance": "light"
      },
      "special": ["cast-json"]
    }
  },
  {
    "field": "theme_dark",
    "meta": {
      "interface": "system-theme",
      "options": {
        "appearance": "dark",
        "includeNull": true
      }
    }
  },
  {
    "field": "theme_dark_overrides",
    "meta": {
      "interface": "system-theme-overrides",
      "options": {
        "appearance": "dark"
      },
      "special": ["cast-json"]
    }
  },
  {
    "field": "admin_divider",
    "meta": {
      "interface": "presentation-divider",
      "options": {
        "icon": "verified_user",
        "title": "$t:fields.directus_users.admin_options",
        "color": "var(--theme--danger)"
      },
      "special": ["alias", "no-data"],
      "hidden": true
    }
  },
  {
    "field": "status",
    "meta": {
      "interface": "select-dropdown",
      "options": {
        "choices": [
          {
            "text": "$t:fields.directus_users.status_draft",
            "value": "draft"
          },
          {
            "text": "$t:fields.directus_users.status_invited",
            "value": "invited"
          },
          {
            "text": "$t:fields.directus_users.status_unverified",
            "value": "unverified"
          },
          {
            "text": "$t:fields.directus_users.status_active",
            "value": "active"
          },
          {
            "text": "$t:fields.directus_users.status_suspended",
            "value": "suspended"
          },
          {
            "text": "$t:fields.directus_users.status_archived",
            "value": "archived"
          }
        ]
      },
      "width": "half"
    }
  },
  {
    "field": "role",
    "meta": {
      "interface": "select-dropdown-m2o",
      "options": {
        "template": "{{ name }}"
      },
      "special": ["m2o"],
      "width": "half",
      "display": "related-values",
      "display_options": {
        "template": "{{ name }}"
      }
    }
  },
  {
    "field": "policies",
    "meta": {
      "interface": "list-m2m",
      "options": {
        "layout": "list"
      },
      "display": "related-values",
      "special": ["m2m"],
      "hidden": true
    }
  },
  {
    "field": "token",
    "meta": {
      "interface": "system-token",
      "special": ["conceal"]
    }
  },
  {
    "field": "last_page",
    "meta": {
      "width": "half"
    }
  },
  {
    "field": "last_access",
    "meta": {
      "width": "half",
      "display": "datetime",
      "readonly": true,
      "display_options": {
        "relative": true
      }
    }
  },
  {
    "field": "provider",
    "meta": {
      "width": "half",
      "interface": "select-dropdown",
      "options": {
        "choices": [
          {
            "text": "$t:default_provider",
            "value": "default"
          }
        ]
      }
    }
  },
  {
    "field": "external_identifier",
    "meta": {
      "width": "half",
      "options": {
        "iconRight": "account_circle"
      },
      "interface": "input"
    }
  },
  {
    "field": "auth_data",
    "meta": {
      "hidden": true
    }
  }
]'

Notice the Key Customizations:

Hidden Fields:

  • Set hidden: true for dividers and unnecessary fields
  • Special handling for the policies field
  • Temporarily hidden fields until better solutions are available:
    • preferences_divider
    • theming_divider
    • admin_divider
    • policies field (due to visual duplication)

Step 4: Adding the Group Tabs Interface Extension

The Group Tabs interface helps organize fields into logical sections. Here's a suggestion how to structure your user profile:

Users Collection Layout

Create a new group tab field and name it tab_group with the interface group-tabs. Inside this group, add the following group-detail fields to organize your user profile into logical sections:

💡 Pro Tip: The Group Tabs interface creates a cleaner, more organized user experience by separating different types of information into distinct tabs.

Tab Structure Configuration:

  1. 📋 Basic Information Tab (basic_info_group):
    • Avatar
    • First name
    • Last name
    • Email
    • Title
    • Location
    • Description
    • Tags
  2. ⚙️ Preferences Tab (preferences_group):
    • Language
    • Email notifications
    • Theme preference (dark/light mode)
  3. 🔒 Security (security_group):
    • Password
    • Two-Factor Authentication
    • Account status
    • Role
    • Token
    • Provider
    • External identifier
    • Authentication data (hidden)
🎨 Design Recommendation: Use consistent field widths within each tab:
  • width: "half" for related fields that should appear side-by-side
  • width: "full" for description fields and primary identifiers
  • Add appropriate icons using iconRight or iconLeft options

Step 5: Handling Visual Issues

To address the persistent horizontal rule issue that may appear despite hiding dividers, you can add custom CSS to your Directus appearance settings. This solution targets specific divider elements that cause visual artifacts:

Note: This CSS workaround specifically targets the first visible field on the page. For optimal results, ensure that any problematic divider is positioned as the first field in your layout configuration.
/* Hide the specific divider - replace PRIMARY_KEY with your divider's primary key */
.field.full.first-visible-field:has(div[field="$system_divider"][primary-key="PRIMARY_KEY"]) {
  display: none !important;
}

Important: Make sure to replace PRIMARY_KEY with the actual primary key of your divider. You can find this in the browser's developer tools by inspecting the divider element.

Extending to Other Collections

The same approach can be used to customize other Directus system collections. Here's how:

  1. Identify the Collection: Determine which system collection you want to customize
  2. Find the Source: Locate the corresponding YAML file in the Directus repository
  3. Analyze Fields: Review the field definitions and their current configurations
  4. Plan Changes: Decide which fields to modify, hide, or rearrange
  5. Apply Customizations: Use the PATCH endpoint for that collection (e.g., /fields/directus_roles for roles)

The core principle remains the same: identify the fields from the collection's YAML definition in the Directus repository, then craft a JSON payload similar to the one for directus_users to define their appearance and behavior in the directus_fields collection.

Conclusion

Customizing the default Directus fields can significantly improve the user experience and make the system more suitable for your specific needs. While there are some limitations and known issues, the benefits of having a well-organized user interface often outweigh these challenges.


Note: This guide is based on Directus version 10 and 11. Some features and behaviors might vary in different versions.