Heidelberg AICurriculum
Track 11 · Advanced
11.2

CMS - Content Management Systems - Directus

Own your content — a headless CMS behind your site

8 lessons 2026-08-13 AI-generated

1Overview

In this chapter you’ll explore Directus, a headless content management system that lets you own and structure your data while keeping it separate from the presentation layer of your site. You’ll see how Directus stores content in a database, provides an intuitive API for retrieving that content, and offers a flexible admin interface for non‑technical editors. By the end you’ll understand the core concepts behind headless CMS architecture, how Directus fits into modern web workflows, and what steps are needed to set up and start using it as the backbone of your digital projects.

1.1How does Directus manage content?

It stores your content in a database and provides a flexible, user‑friendly interface plus API endpoints so you can retrieve and update data without coupling to a front‑end framework.

1.2Why choose a headless CMS like Directus?

A headless approach separates content storage from presentation, giving you freedom to deliver the same data across multiple platforms while keeping full control over your content architecture.

2Lessons 8

2.1 Describe how a headless CMS separates content from presentation

The API Docs button reveals the generated endpoint URL for a collection.

Show that separating content from presentation lets multiple front‑ends share the same data through one API

  1. Open the Directus admin interface in a browser
  2. Select the Collections tab and click the Articles collection
  3. Press the API Docs button to view the generated endpoint for that collection
  4. Copy the displayed GET /items/articles URL and run it with curl in a terminal
  • You'll see A static site build and a curl request both receive identical JSON for the same record from the Directus API
  • Takeaway Separating content from presentation enables any number of consumers – website, app or AI pipeline – to use the same structured data without changing the editorial workflow
  • Check What does the identical JSON received from both the static site build and the curl request demonstrate about how content is delivered?
  • Cost No cost to understand this — it is a mental model, not a tool. The real cost shows up later: a headless CMS needs something to render its content, which a coupled CMS gives you for free.

2.2 Update static site content by publishing changes from Directus

The Save action stores edits in Directus before they are exported and committed to the content repository.

Export edited content from Directus and commit it to the content repository so the next static build includes the change

  1. Open Directus admin UI in your browser
  2. Navigate to the relevant collection and edit the desired field
  3. Click Save to store the change in Directus
  • You'll see The live site remains unchanged until the publish step finishes, then a new commit appears in the content repo showing the field modification
  • Takeaway Separate export step decouples CMS edits from site availability and requires an explicit publish to make changes live
  • Check How does committing edited content to the repository after saving it in Directus affect when the live site shows the change?
  • Cost No new tool to install for this lesson — it is architecture, read from a system you can already inspect. The cost this pattern buys you is an editor's wait between "saved" and "live," in exchange for a site that cannot be taken down by the CMS.

2.3 Run Directus locally with Docker Compose

A docker-compose.yml file defines the services, environment variables and persistent storage needed to launch Directus locally.

Get a Directus instance running locally with Docker Compose, using persistent storage, so you have a real instance for the rest of this chapter instead of reading about one.

  1. Create a file named docker-compose.yml containing the required environment variables.
  2. Start the containers by executing docker compose up in the terminal.
  3. Open a web browser to http://localhost:8055 to load the Directus admin UI.
  4. Complete the initial setup wizard and record the admin password securely.
  5. Verify that the Content and Settings sections are empty.
  • You'll see A running container, the Directus admin UI reachable in a browser at port 8055, and an empty project with no collections yet — just the system menus (Content, User Directory, File Library, Settings).
  • Takeaway docker compose up with a SECRET, a DB_CLIENT/DB_FILENAME pair and a PUBLIC_URL gets a real, persistent Directus instance running on port 8055 — no license key needed for self‑hosted Core‑tier use
  • Check What indicates that the Directus instance is correctly initialized after running docker compose up and completing the setup wizard?
  • Cost Free — Directus self-hosts at no cost on its Core tier for organizations under $5M annual revenue and 50 employees (Directus's Open Innovation Grant, verified against directus.com 2026-08-08); above that threshold the Core tier is still usable within its feature limits. The only real cost here is the compute the container runs on.

2.4 Create a safe editing form for colleagues

A Select (Dropdown) field provides a closed list of allowed values for a collection attribute.

Create a collection with fields typed and constrained tightly enough that a colleague who has never seen a database can edit an entry without breaking anything downstream.

  1. Click Create Collection and name it article.
  2. Add a Select (Dropdown) field named “status” and define the allowed choices.
  3. Enable the required toggle on the “title” field so it cannot be empty.
  4. Add a Relational field to link to another collection instead of typing an ID.
  5. Open the Create Item form for the new collection and attempt to save with an empty required field or an invalid status to verify validation.
  • You'll see A creation form where the status field is a closed dropdown instead of free text, a required title field that visibly blocks saving when left empty, and a relation field that shows a picker of real records instead of an open text box.
  • Takeaway The fields you choose are the safety rail — a Select with a closed list, a Required toggle, and a real relation field prevent more editing mistakes than any amount of written instructions to "please be careful"
  • Check Which field configurations stop an item from being saved when the title is empty or an invalid status is chosen?
  • Cost Free — field typing and validation are core Directus features, not a paid tier. The cost is time spent modeling before you type any content, which is exactly the time that prevents cleanup later.

2.5 Configure a role that limits an editor to only needed actions

The Roles & Permissions editor lets you assign Create/Read/Update/Delete rights per collection and field for a specific role.

Create a role scoped to only the collections and actions one type of user actually needs, so a content editor cannot accidentally reach Settings, Users, or a collection outside their job.

  1. Open Settings then select Roles & Permissions.
  2. Click Create Role and enter a name such as Editor.
  3. In the role editor, enable Create, Read, Update for the article collection and leave Delete disabled.
  4. Leave all system collections (Users, Roles, Webhooks) with no permissions granted.
  5. Add a field‑level restriction by disabling the slug field for this role.
  6. Save the role and use Impersonate Role to log in as the new Editor role.
  7. Confirm that Settings, User Directory, and the Delete action are absent.
  • You'll see The same admin UI, logged in as the Editor role, with the Settings and User Directory menu items gone entirely and the Delete action missing from the article collection's item menu.
  • Takeaway A role is Create/Read/Update/Delete permissions scoped per collection, per field, and even per row — build the narrowest one that lets an editor do their actual job, and verify the restriction by logging in as it, not by reading the config
  • Check After impersonating the Editor role, which UI elements and actions are no longer visible, confirming the permission limits you set?
  • Cost Free — role-based permissions are core to Directus, not a paid add-on. The cost is the up-front modeling time to define roles deliberately instead of reusing Administrator out of convenience.

2.6 Retrieve content via Directus APIs

The /items/ REST endpoint returns JSON data, while the /graphql endpoint accepts GraphQL queries to retrieve the same content.

Pull real content out of your Directus instance over both the REST and GraphQL APIs so you can see exactly what a consumer receives.

  1. Send a GET request to /items/article?fields=title,status and observe the JSON array of articles containing only those fields.
  2. Run a GraphQL query against /graphql that selects the same fields from the article collection and verify the response matches the REST output.
  3. Compare the two responses to confirm both endpoints deliver the same underlying content.
  • You'll see A REST response – clean JSON with only the fields you requested – and, from the same collection, a GraphQL query returning identically‑shaped data through /graphql.
  • Takeaway Every collection is exposed as REST (/items/) and GraphQL (/graphql, plus /graphql/system for system data) out of the box, with fields on REST letting you limit public exposure
  • Check How does limiting fields in the REST request and using an equivalent GraphQL query prove that both endpoints deliver identical content structures?
  • Cost Free — both the REST and GraphQL APIs are core Directus features available on every tier, including self-hosted Core. The cost is deciding, per consumer, which shape of API actually fits how that consumer reads data.

2.7 Determine Directus licensing and cost for your organisation

The Monospace Sustainable Core License (MSCL‑1.0‑GPL) governs Directus’s free usage terms and upgrade conditions.

State the exact licence Directus uses, what “free” entails, and how revenue or headcount thresholds affect pricing

  1. Read the licence file in Directus’s GitHub repository to confirm the current Monospace Sustainable Core License (MSCL‑1.0‑GPL)
  2. Review Directus’s official licence‑change announcement dated 2026‑08‑08 for version 12 details
  3. Check the Open Innovation Grant documentation for the $5M revenue and 50 employee thresholds that decide if a LICENSE_KEY is needed
  • You'll see The licence information, the Open Innovation Grant thresholds, and whether a LICENSE_KEY is required for your team
  • Takeaway Directus runs under MSCL‑1.0‑GPL, free for small teams but becomes GPLv3 after four years and requires payment above the grant limits
  • Check Which revenue and employee thresholds determine whether your organisation needs a Directus LICENSE_KEY?
  • Cost Free for self-hosting under the Open Innovation Grant thresholds (under $5M revenue, under 50 employees) as of 2026-08-08. Above those thresholds, production Core-tier use requires a paid license key — check current pricing directly before committing, since thresholds and tiers are exactly the kind of detail that moves.

2.8 Decide if a headless CMS is required

A decision matrix evaluates editor count, API consumption, and permission granularity to justify a headless CMS.

Determine whether the project’s content workflow justifies adding Directus instead of using markdown files.

  1. Assess how many non‑technical people need to edit content without developer assistance.
  2. Identify whether the content must be delivered via an API to more than one consumer such as a website, app, or AI pipeline.
  3. Determine if distinct editing permissions are required for different contributors.
  • You'll see A clear decision on whether to set up a Directus instance or keep content as plain markdown in the repository.
  • Takeaway A headless CMS is justified only when multiple non‑technical editors, structured multi‑surface content, or scoped role requirements exist
  • Check What combination of non‑technical editors, multi‑consumer API delivery, and distinct permission needs indicates that a headless CMS like Directus is required?
  • Cost Choosing markdown-in-repo instead of a CMS costs nothing today. The cost of standing up a CMS too early is everything named in this lesson's first step, carried for editors and consumers that do not exist yet.

3You’ll know it worked 16 checkable outcomes in this chapter

  • Run SELECT queries to confirm roles filter correctly and author IDs reference valid users.
  • Attempt to access an admin endpoint with a standard editor JWT token and confirm it returns a 403 Forbidden response.
  • Verify the new post appears in Directus with the correct category and SEO fields populated
  • Attempting to create, update, or delete data via the public API endpoint returns a permission error.
  • A user logs in and attempts to edit a post authored by someone else; the system blocks the action with a permission error.
  • A user creates a new item and finds the preset fields already populated with the correct values.
  • The editor shows your configured UI elements like a slugify toggle, half-width fields, and a formatted text toolbar when creating or editing items.
  • The API response JSON contains only the specified fields and nested relational objects without extra data.

16 outcomes in all — one per recipe below.

4FAQ, Tips & How-to 16

one problem, one solution, one action
How-to Everyone

Want a simple CMS backend DB

A CMS database relies on two core tables: users (storing ID, username, email, and role) and content (storing ID, title, body, status, and author ID). Linking them via a foreign key ensures every piece of content is tied to a specific creator, while the role and status fields enable editorial workflows and permission checks without complex joins. This normalized structure keeps data consistent and scales cleanly as you add more content types.

CodeLucky ↗ Lesson → AI-generated
How-to Everyone

Need front‑end apps to add, edit or delete site content and images

A headless or traditional CMS backend communicates through standardized HTTP methods mapped to specific endpoints. Using /api/content for listing, creating, updating, and deleting content, plus /api/media/upload for assets, creates a predictable interface that frontends or mobile apps can consume. This separation of concerns allows the presentation layer to change independently while the data layer remains stable.

CodeLucky ↗ Lesson → AI-generated
How-to Everyone

Editors can’t access admin functions

Content platforms are frequent targets for injection and unauthorized access, so security must be baked into the application layer. Implementing role-based access control (RBAC) with JSON Web Tokens (JWT) ensures only authorized users can modify content, while strict input validation and sanitization block SQL injection and cross-site scripting (XSS). Coupled with HTTPS and activity logging, this creates a defense-in-depth posture that protects both data and infrastructure.

CodeLucky ↗ Lesson → AI-generated
How-to Everyone

Move your Webflow blog to a new CMS

The Directus MCP server exposes CMS operations as standardized tool calls that an AI agent can execute. By connecting Cursor to both the Webflow and Directus MCP servers, the agent can read legacy posts, map them to a Directus template, and push them into the correct collection with category metadata. This works because MCP abstracts the API complexity, allowing the LLM to handle extraction, transformation, and publishing autonomously.

YouTube ↗ Lesson → AI-generated
How-to Everyone

Paste a URL or draft in your editor

Instead of manually writing and uploading content, you can drop URLs or paste draft text directly into Cursor and ask the AI agent to draft a post. The agent uses the Directus MCP to publish the content to the CMS, automatically attaching category tags and SEO metadata. This works because the MCP acts as a bridge between the IDE and the CMS, letting the LLM handle formatting, categorization, and API submission in one workflow.

YouTube ↗ Lesson → AI-generated
How-to Everyone

Need a full CMS set up from an empty instance

The Directus Template CLI automates the tedious setup of schemas, permissions, and example data by pushing a pre-configured project structure directly into a fresh Directus instance. Instead of manually creating collections, dashboards, and flows, developers can instantly load a production-ready baseline to study, deconstruct, and build upon. The tool works by authenticating via a static admin token and executing a series of API calls to populate the database and UI configuration.

Directus ↗ Lesson → AI-generated
How-to Everyone

Public API requests should never modify data

The public role dictates what data is exposed without login, defaulting to no access for all collections. Keeping it restricted prevents unauthorized data modification, as unauthenticated requests should only retrieve safe, read-only content. By explicitly locking Create, Update, and Delete operations, you eliminate accidental data corruption from anonymous API calls.

Directus ↗ Lesson → AI-generated
How-to Everyone

Need to hide draft content from a role

Directus allows granular rules at the item level, letting you control exactly which records a role can access. By applying a rule like status equals published, you ensure that draft or review-stage content remains invisible to that role, even if they have general read access to the collection. This keeps the API response lean and prevents internal workflow states from leaking.

Directus ↗ Lesson → AI-generated
How-to Everyone

Trying to edit someone else’s post

Directus supports dynamic variables like current.user.id that reference the logged-in user session. By applying this variable to a custom rule (e.g., author.id equals current.user.id), you enforce row-level security where users can only modify records they personally created. This eliminates the need for manual access lists and scales automatically as your team grows.

Directus ↗ Lesson → AI-generated
How-to Everyone

Confidential columns hidden from non‑admin roles

Beyond controlling which records a role sees, Directus lets you hide individual fields at the permission level. This strips identifiers, internal notes, or metadata from both the app UI and API responses for non-admin roles, reducing data exposure without altering the underlying database schema.

Directus ↗ Lesson → AI-generated
How-to Everyone

Need to manually set creator ID or status on new items

Presets let you define default values that automatically apply when a role creates or updates an item. This enforces data consistency by automatically tagging new records with the creator's ID or setting a default status, removing manual input steps and preventing human error during content entry.

Directus ↗ Lesson → AI-generated
How-to Everyone

Need a UI for existing SQL tables without altering the schema

Directus does not migrate or alter your existing SQL schema. Instead, it introspects the database architecture and mirrors it into its Data Studio interface. This lets non-technical users manage data through a UI while developers retain full control over the underlying tables and can bypass the middleware with direct SQL queries.

Directus ↗ Lesson → AI-generated
How-to Everyone

Want a tailored input form without coding

Directus separates data structure from user interface. You can define fields in the data model, then independently configure how they appear in the editor using the interface, display, and validation tabs. This allows you to create tailored input forms like auto-slug generators or WYSIWYG editors without writing code.

Directus ↗ Lesson → AI-generated
How-to Everyone

When a new article gets published

Directus Flows acts as an internal automation engine similar to Zapier. You define a trigger like an item creation event, chain operations like sending an email, and inject dynamic variables from the trigger into the operation payloads. This runs server-side without external dependencies.

Directus ↗ Lesson → AI-generated
How-to Everyone

Only need a few columns plus their related records

Directus auto-generates REST and GraphQL APIs for every collection. You can optimize API payloads by using the fields query parameter to request only needed columns, and use dot notation or wildcards to fetch nested relational data in a single request, avoiding multiple round trips.

Directus ↗ Lesson → AI-generated
How-to Everyone

Public endpoints hide draft pages

Directus uses a role-based access control system where permissions are granular per collection and operation. By creating a static token for an admin user, you can bypass public restrictions and access draft or unpublished data programmatically, while keeping public endpoints locked down by default.

Directus ↗ Lesson → AI-generated

The same set on /recipes, filtered by tool and role.

5See also

💬 Discuss this chapter

Ask, share, or report — over on the Heidelberg AI community forum.