# Directus: what changed from 11 to 12 - Product: Directus (https://whatsnew.fyi/product/directus) - Vendor: Directus - Range: changelog entries numbered after v11.17.4 up to and including v12.3.1, stable releases only - Entries below: 8 releases (newest first) - Resolved: 11 is v11.17.4 and 12 is v12.3.1, the newest stable release of each major we track - Carrying security changes: 1 · CVEs mentioned: 0 · Mentioning breaking changes: 4 · Removing or deprecating something: 3 - Page: https://whatsnew.fyi/product/directus/compare/11...12 What's New is an index, not a publisher: every entry below links to the vendor's own release notes, which are the authoritative source. Entries are labelled where they are hand-curated sample data, pre-releases, or drawn from a secondary source such as a developer blog. Reuse: the summaries, labels and curation here are © What's New. Quote freely with attribution and a link back; wholesale republication of the corpus is not permitted — terms: https://whatsnew.fyi/terms. The vendors' own release notes remain their publishers'. ## What changed (89 changes, grouped by kind) ### Added #### v12.3.1 (2026-08-25) - Add `countFilterListeners`, `countActionListeners`, and `countInitListeners` methods to the `emitter` to expose the number of registered handlers for each event #### v12.3.0 (2026-08-18) - Added search-first AI tool discovery for chat and MCP tools with schema pinned as a root chat tool - Added a caption field to the WYSIWYG image drawer, which wraps the image in a figure with a figcaption - Added the collection name appended to display template in item and drawer headers - Introduced @directus/cli (d6s / directus-cli) — a client-side CLI that syncs schema and configuration between Directus instances through committed JSON files #### v12.2.0 (2026-07-29) - Added support for multi-collection flat data imports - Import file size is now capped by default with IMPORT_MAX_FILE_SIZE environment variable set to 50mb - Added a mode parameter and partial snapshot support to the schema diff endpoint - Added support for restricting image transformation output size via ASSETS_TRANSFORM_IMAGE_MAX_OUTPUT_DIMENSION - Image transformations that project an output larger than ASSETS_TRANSFORM_IMAGE_MAX_OUTPUT_DIMENSION default 3000 px on either axis are now rejected - Added JSON path filtering to Studio filters - Added search to the collection selection in relationship configuration - Added global setting for default save action - Added LICENSE_KEY_MANAGEMENT_ENABLED to control license key management - Added support for partial schema snapshot via new includeCollections and excludeCollections parameters #### v12.1.0 (2026-07-01) - Publish a distroless Docker Hardened Image (DHI) variant under a -dhi tag suffix - Add PROJECT_OWNER_ENABLED env var to allow disabling owner info collection and sync - Add v-kbd component and support { text, kbd } syntax in tooltip - Replace tooltip with Reka UI one - Add validation to restrict geometry types to known types #### v12.0.2 (2026-06-12) - Added support for non-interactive mode in create-directus-extension #### v12.0.1 (2026-06-11) - Added keyboard-editable date entry directly in the datetime field with formatted value display at rest and editable date segments on focus - Added inline editing support to the JSON repeater interface #### v12.0.0 (2026-06-10) - Introduce active license enforcement for Directus 12, with Core tier as default for self-hosted instances - Add VERSION_KEY_* constants and support ?version=published query parameter for resolving versions of main items - Add header action button to edit draft versions in versioned collections - Share health check results across multi-instance deployments with caching ### Changed #### v12.3.1 (2026-08-25) - Remove `user_created` and `date_created` for `update` from recommended permissions for `directus_shares` - Update storage driver dependencies #### v12.3.0 (2026-08-18) - exists() now throws when the lookup itself fails, for example on a timeout, a connection error or rejected credentials, instead of reporting false - Update Items and Delete Items operations now return null instead of affecting every item in a collection when given an empty or missing key or query - Update Items and Delete Items operations now throw an error when both key and query are defined - Update Items operation now throws an error when key or query is combined with a batch payload - Updated ASSETS_TRANSFORM_IMAGE_MAX_OUTPUT_DIMENSION to 6000 px to match ASSETS_TRANSFORM_IMAGE_MAX_DIMENSION - Docker images now boot via CMD ["node", "docker-entrypoint.cjs"] and use the pm2 bundled with @directus/api instead of installing a separate copy - Updated outdated type definitions for directus_files, directus_collections, directus_deployments, directus_settings, and directus_users #### v12.2.0 (2026-07-29) - Restricted the settings fields readable with minimal app access to only those actually needed by non-admin users, no longer exposing admin-only and sensitive AI configuration fields - Replaced the TinyMCE editor powering the WYSIWYG with Tiptap - The DeploymentProjectsService.readByExternalId method now takes the deployment ID as its first argument - The background query flag now treats a valueless indicator as true - The SDK schemaDiff command now takes its options as an object #### v12.1.1 (2026-07-01) - Updated vite dependency to 8.1.2 in @directus/app - Updated vite dependency to 8.1.2 in @directus/api #### v12.1.0 (2026-07-01) - Limit sensitive system mutations defined by GRAPHQL_SINGLE_USE_MUTATIONS to single use - Update GraphQL WebSocket restrictions to match the HTTP endpoint and hide validation hints when introspection is disabled - Harden the published Docker image and drop npm/npx from the runtime - Update bundled esbuild to 0.28.1 #### v12.0.0 (2026-06-10) - Relicense from BUSL-1.1 to MSCL-1.0-GPL - Change IP_TRUST_PROXY default from true to false to harden against IP spoofing - Replace status field with archived boolean in collection settings for newly created collections - Replace cache, rateLimiter, and rateLimiterGlobal health checks with generic redis check using redis: prefix - Lock published items in versioned collections from editing - Remove rounded prop from v-button component - Remove headerShadow and sidebarShadow from LayoutConfig interface for theme extensions - Remove boxShadow from header theme rules schema for theme extensions - Remove sidebarShadow from layout wrapper state exposure for theme extensions - Remove navigation.project.borderColor, navigation.project.borderWidth, and navigation.project.background from theming - Merge header and navigation bar theme properties into new shell scope with shell.background, shell.backgroundAccent, shell.borderWidth, and shell.borderColor ### Fixed #### v12.3.1 (2026-08-25) - Fix MCP OAuth clients settings pages concatenating breadcrumbs into the page title - Fix WebSocket heartbeat leaking a `websocket.message` listener on each ping when a client failed to respond in time - Fix GraphQL query fragments returning null fields - Fix public registration verification using the provided email instead of the stored one - Strip `project_id` when pulling settings so a sync no longer copies one instance's identity onto another - Fix `unsubscribe()` not removing subscriptions, causing them to persist across reconnects and accumulate for the lifetime of the client #### v12.3.0 (2026-08-18) - Fixed storage connections leaking when asset requests were cancelled or a transformation failed, which eventually made every asset request return a permission error until Directus was restarted #### v12.2.0 (2026-07-29) - Fixed deployment webhooks resolving a project from the wrong provider when external IDs collide - Fixed incomplete json filter paths errors #### v12.1.0 (2026-07-01) - Restore pre-v12 back button behavior to return to previously visited item/page when navigating via a relation - Fix public page foreground image rendering to overlay shader background instead of rendering side-by-side - Fix array indexing in display and preview URL templates so templates like {{ categories[0].name }} resolve to the indexed value - Fix internal server error when validating out-of-range integer values - Fix Postgres value too long errors being misattributed to an unrelated field - Fix accountability overrides in the graphql websocket #### v12.0.2 (2026-06-12) - Fixed user count for users with conflicting direct policy and role #### v12.0.1 (2026-06-11) - Fixed license badge spacing issue - Fixed license modals being impossible to dismiss when shown above a route drawer by keeping dialog focus traps stacked in visual order and scoping license dismissal cookies to the whole app - Fixed revision snapshots being assigned to the wrong items during batch updates when read order differs ### Removed #### v12.2.0 (2026-07-29) - tinymceOverrides no longer has any effect in the WYSIWYG editor - TinyMCE is no longer bundled with the app #### v12.1.0 (2026-07-01) - Remove /utils/hash/generate and /utils/hash/verify endpoints #### v12.0.0 (2026-06-10) - Disable SSO login without a valid license - Disable custom permission rules without a valid license - Disable custom or self-hosted LLM connections without a valid license - Restrict /server/health endpoint to authenticated users; use /server/ping for liveness checks instead ### Deprecated #### v12.0.0 (2026-06-10) - Deprecate VResizeable component for extension authors in favor of @directus/vue-split-panel ### Security #### v12.1.0 (2026-07-01) - Harden upload path validation to prevent writes to extension and temporary storage directories - Add CORS_ORIGIN checks for websocket connections - Fix stored XSS vulnerability where the project color could break out of the generated favicon's SVG markup - Fix Local File Inclusion vulnerability in MailService.renderTemplate ## Release notes ### v12.3.1 - Date: 2026-08-25 - Version: v12.3.1 - Original notes: https://github.com/directus/directus/releases/tag/v12.3.1 - Permalink: https://whatsnew.fyi/product/directus/releases/v12.3.1 - **added** — Add `countFilterListeners`, `countActionListeners`, and `countInitListeners` methods to the `emitter` to expose the number of registered handlers for each event - **fixed** — Fix MCP OAuth clients settings pages concatenating breadcrumbs into the page title - **fixed** — Fix WebSocket heartbeat leaking a `websocket.message` listener on each ping when a client failed to respond in time - **fixed** — Fix GraphQL query fragments returning null fields - **fixed** — Fix public registration verification using the provided email instead of the stored one - **changed** — Remove `user_created` and `date_created` for `update` from recommended permissions for `directus_shares` - **changed** — Update storage driver dependencies - **fixed** — Strip `project_id` when pulling settings so a sync no longer copies one instance's identity onto another - **fixed** — Fix `unsubscribe()` not removing subscriptions, causing them to persist across reconnects and accumulate for the lifetime of the client ###### ✨ New Features & Improvements - **@directus/api** - Added `countFilterListeners`, `countActionListeners`, and `countInitListeners` methods to the `emitter`, exposing the number of registered handlers for each event ([#28117](https://github.com/directus/directus/pull/28117) by @ComfortablyCoding) ###### 🐛 Bug Fixes & Optimizations - **@directus/app** - Fixed MCP OAuth clients settings pages concatenating breadcrumbs into the page title ([#28115](https://github.com/directus/directus/pull/28115) by @MHJahanbakhsh) - **@directus/api** - Fixed the WebSocket heartbeat leaking a `websocket.message` listener on each ping when a client failed to respond in time ([#28117](https://github.com/directus/directus/pull/28117) by @ComfortablyCoding) - Fixed GraphQL query fragments returning null fields ([#28128](https://github.com/directus/directus/pull/28128) by @ComfortablyCoding) - Fixed public registration verification using the provided email instead of the stored one ([#28144](https://github.com/directus/directus/pull/28144) by @br41nslug) - Removed `user_created` and `date_created` for `update` from recommended permissions for `directus_shares` ([#28145](https://github.com/directus/directus/pull/28145) by @br41nslug) - Updated storage driver dependencies ([#28119](https://github.com/directus/directus/pull/28119) by @ComfortablyCoding) - **@directus/cli** - Stripped `project_id` when pulling settings, so a sync no longer copies one instance's identity onto another ([#28132](https://github.com/directus/directus/pull/28132) by @lazerg) - **@directus/sdk** - Fixed `unsubscribe()` not removing subscriptions, causing them to persist across reconnects and accumulate for the lifetime of the client ([#28117](https://github.com/directus/directus/pull/28117) by @ComfortablyCoding) - **@directus/system-data** - Removed `user_created` and `date_created` for `update` from recommended permissions for `directus_shares` ([#28145](https://github.com/directus/directus/pull/28145) by @br41nslug) - **@directus/storage-driver-s3** - Updated storage driver dependencies ([#28119](https://github.com/directus/directus/pull/28119) by @ComfortablyCoding) - **@directus/storage-driver-gcs** - Updated storage driver dependencies ([#28119](https://github.com/directus/directus/pull/28119) by @ComfortablyCoding) - **@directus/storage-driver-azure** - Updated storage driver dependencies ([#28119](https://github.com/directus/directus/pull/28119) by @ComfortablyCoding) - **@directus/storage-driver-supabase** - Updated storage driver dependencies ([#28119](https://github.com/directus/directus/pull/28119) by @ComfortablyCoding) ###### 📦 Published Versions - `@directus/app@17.1.1` - `@directus/api@39.1.0` - `@directus/cli@12.2.1` - `@directus/composables@11.6.2` - `create-directus-extension@12.1.4` - `@directus/env@6.2.2` - `@directus/extensions@4.0.4` - `@directus/extensions-sdk@18.0.4` - `@directus/memory@4.0.4` - `@directus/pressure@4.0.4` - `@directus/storage-driver-azure@13.0.4` - `@directus/storage-driver-cloudinary@14.0.1` - `@directus/storage-driver-gcs@13.0.4` - `@directus/storage-driver-s3@14.0.1` - `@directus/storage-driver-supabase@5.0.1` - `@directus/system-data@4.6.1` - `@directus/themes@2.0.4` - `@directus/utils@13.5.4` - `@directus/validation@3.0.4` - `@directus/sdk@25.0.1` ### v12.3.0 - Date: 2026-08-18 - Version: v12.3.0 - Original notes: https://github.com/directus/directus/releases/tag/v12.3.0 - Permalink: https://whatsnew.fyi/product/directus/releases/v12.3.0 - **fixed** — Fixed storage connections leaking when asset requests were cancelled or a transformation failed, which eventually made every asset request return a permission error until Directus was restarted - **changed** — exists() now throws when the lookup itself fails, for example on a timeout, a connection error or rejected credentials, instead of reporting false - **changed** — Update Items and Delete Items operations now return null instead of affecting every item in a collection when given an empty or missing key or query - **changed** — Update Items and Delete Items operations now throw an error when both key and query are defined - **changed** — Update Items operation now throws an error when key or query is combined with a batch payload - **changed** — Updated ASSETS_TRANSFORM_IMAGE_MAX_OUTPUT_DIMENSION to 6000 px to match ASSETS_TRANSFORM_IMAGE_MAX_DIMENSION - **changed** — Docker images now boot via CMD ["node", "docker-entrypoint.cjs"] and use the pm2 bundled with @directus/api instead of installing a separate copy - **added** — Added search-first AI tool discovery for chat and MCP tools with schema pinned as a root chat tool - **added** — Added a caption field to the WYSIWYG image drawer, which wraps the image in a figure with a figcaption - **added** — Added the collection name appended to display template in item and drawer headers - **added** — Introduced @directus/cli (d6s / directus-cli) — a client-side CLI that syncs schema and configuration between Directus instances through committed JSON files - **changed** — Updated outdated type definitions for directus_files, directus_collections, directus_deployments, directus_settings, and directus_users ###### ⚠️ Potential Breaking Changes **Fixed storage connections leaking when asset requests were cancelled or a transformation failed, which eventually made every asset request return a permission error until Directus was restarted ([#28076](https://github.com/directus/directus/pull/28076))** `exists()` now throws when the lookup itself fails, for example on a timeout, a connection error or rejected credentials, instead of also reporting `false`. Callers that relied on a `false` result for any failure need to handle the error. Note that S3 answers 403 rather than 404 for a missing object when the credentials cannot list the bucket, so granting `s3:ListBucket` is needed to keep getting a clean "missing" answer. **Fixed "Update Items" and "Delete Items" operations affecting every item in a collection when given an empty or missing key or query ([#27759](https://github.com/directus/directus/pull/27759))** **Nothing to target is a no-op** "Update Items" and "Delete Items" operations now return `null` instead of falling back to every item whenever the configuration doesn't target anything — that is, when `key` is empty or missing (e.g. `[]`, `""`) and `query` is empty or missing (e.g. `{}`). "Update Items" additionally returns `null` when there is nothing to write, i.e. an empty or missing `payload` (e.g. `{}`, or `[]` for a batch payload). Flows that relied on the previous fallback to every item can use `{"limit": -1}`. **Contradictory options error** "Update Items" and "Delete Items" operations now throw an error when both `key` and `query` are defined. "Update Items" also throws when `key` or `query` is combined with a batch payload. **Updated `ASSETS_TRANSFORM_IMAGE_MAX_OUTPUT_DIMENSION` to match `ASSETS_TRANSFORM_IMAGE_MAX_DIMENSION` (`6000` px) ([#28111](https://github.com/directus/directus/pull/28111))** The default maximum output dimension is now `6000` px. Users who rely on the previous limit of `3000` px can explicitly configure `ASSETS_TRANSFORM_IMAGE_MAX_OUTPUT_DIMENSION`. **Used the `pm2` bundled with `@directus/api` in the Docker images instead of installing a separate copy, so its dependencies follow the versions pinned by the workspace ([#28120](https://github.com/directus/directus/pull/28120))** If you extend the Docker image: it now boots via `CMD ["node", "docker-entrypoint.cjs"]`, which runs the same `bootstrap` then `pm2-runtime` sequence as before. `pm2-runtime` is no longer on the `PATH`, so a custom `CMD` that called it directly should hand off to `docker-entrypoint.cjs` instead. `pm2` itself remains on the `PATH` for `docker exec` diagnostics. - **@directus/api** - Fixed "Update Items" and "Delete Items" operations affecting every item in a collection when given an empty or missing key or query ([#27759](https://github.com/directus/directus/pull/27759) by @ComfortablyCoding) - **@directus/storage-driver-cloudinary** - Fixed storage connections leaking when asset requests were cancelled or a transformation failed, which eventually made every asset request return a permission error until Directus was restarted ([#28076](https://github.com/directus/directus/pull/28076) by @dstockton) - **@directus/storage-driver-s3** - Fixed storage connections leaking when asset requests were cancelled or a transformation failed, which eventually made every asset request return a permission error until Directus was restarted ([#28076](https://github.com/directus/directus/pull/28076) by @dstockton) - **@directus/storage-driver-local** - Fixed storage connections leaking when asset requests were cancelled or a transformation failed, which eventually made every asset request return a permission error until Directus was restarted ([#28076](https://github.com/directus/directus/pull/28076) by @dstockton) - **@directus/storage-driver-supabase** - Fixed storage connections leaking when asset requests were cancelled or a transformation failed, which eventually made every asset request re _[Truncated at 4000 characters — full notes: https://github.com/directus/directus/releases/tag/v12.3.0]_ ### v12.2.0 - Date: 2026-07-29 - Version: v12.2.0 - Original notes: https://github.com/directus/directus/releases/tag/v12.2.0 - Permalink: https://whatsnew.fyi/product/directus/releases/v12.2.0 - **changed** — Restricted the settings fields readable with minimal app access to only those actually needed by non-admin users, no longer exposing admin-only and sensitive AI configuration fields - **changed** — Replaced the TinyMCE editor powering the WYSIWYG with Tiptap - **removed** — tinymceOverrides no longer has any effect in the WYSIWYG editor - **removed** — TinyMCE is no longer bundled with the app - **changed** — The DeploymentProjectsService.readByExternalId method now takes the deployment ID as its first argument - **fixed** — Fixed deployment webhooks resolving a project from the wrong provider when external IDs collide - **added** — Added support for multi-collection flat data imports - **added** — Import file size is now capped by default with IMPORT_MAX_FILE_SIZE environment variable set to 50mb - **changed** — The background query flag now treats a valueless indicator as true - **changed** — The SDK schemaDiff command now takes its options as an object - **added** — Added a mode parameter and partial snapshot support to the schema diff endpoint - **added** — Added support for restricting image transformation output size via ASSETS_TRANSFORM_IMAGE_MAX_OUTPUT_DIMENSION - **added** — Image transformations that project an output larger than ASSETS_TRANSFORM_IMAGE_MAX_OUTPUT_DIMENSION default 3000 px on either axis are now rejected - **added** — Added JSON path filtering to Studio filters - **added** — Added search to the collection selection in relationship configuration - **added** — Added global setting for default save action - **added** — Added LICENSE_KEY_MANAGEMENT_ENABLED to control license key management - **fixed** — Fixed incomplete json filter paths errors - **added** — Added support for partial schema snapshot via new includeCollections and excludeCollections parameters ###### ⚠️ Potential Breaking Changes **Restricted the settings fields readable with minimal app access to those actually needed by non-admin users, no longer exposing admin-only and sensitive AI configuration fields ([#27996](https://github.com/directus/directus/pull/27996))** The minimal app permissions now grant read access to only a subset of `directus_settings` fields. This applies to new policies, existing policies are untouched. **Replaced the TinyMCE editor powering the WYSIWYG with Tiptap... ([#27754](https://github.com/directus/directus/pull/27754))** **The WYSIWYG interface now runs on Tiptap instead of TinyMCE** - `tinymceOverrides` no longer has any effect. Stored values are kept and a console warning is logged, but the editor ignores them. Use the `fontsize`/`fontfamily` toolbar menus and `customFormats` instead. - TinyMCE is no longer bundled with the app, so anything depending on it (custom plugins, skins, content CSS, the global `tinymce` object) no longer applies. - Existing content that contains markup the editor would normalize now locks the field read-only until the warning dialog is confirmed. Editing and autosave are blocked while locked, including raw-value editing. **Fixed deployment webhooks resolving a project from the wrong provider when external IDs collide ([#27816](https://github.com/directus/directus/pull/27816))** The `DeploymentProjectsService.readByExternalId` method now takes the deployment ID as its first argument (i.e. `readByExternalId(deploymentId, externalId)`) **Added support for multi-collection flat data imports ([#27984](https://github.com/directus/directus/pull/27984))** **Import file size is now capped by default** A new `IMPORT_MAX_FILE_SIZE` environment variable (default: `50mb`) limits the size of uploaded import files and schema snapshots. Previously, imports were effectively unrestricted, allowing files larger than `50mb` to be processed. With this change, imports exceeding the configured limit will be rejected. Increase `IMPORT_MAX_FILE_SIZE` to restore the previous behavior. **Updated `background` query flag handling for `POST /utils/import/:collection`** The `background` query flag now treats a valueless indicator (i.e. `?background`) as true. If you previously relied on a valueless background flag being interpreted as false, pass an explicit value instead (i.e. `?background=false`). **Added a `mode` parameter and partial snapshot support to the schema diff endpoint ([#27984](https://github.com/directus/directus/pull/27984))** The SDK `schemaDiff` command now takes its options as an object (`schemaDiff(snapshot, { force, mode })`) **Added support for restricting image transformation output size via `ASSETS_TRANSFORM_IMAGE_MAX_OUTPUT_DIMENSION` ([#27995](https://github.com/directus/directus/pull/27995))** **Image transformation output is now restricted** Image transformations that project an output larger than `ASSETS_TRANSFORM_IMAGE_MAX_OUTPUT_DIMENSION` (default `3000` px) on either axis are now rejected with an `IllegalAssetTransformationError`. - **@directus/app** - Replaced the TinyMCE editor powering the WYSIWYG with Tiptap ([#27754](https://github.com/directus/directus/pull/27754) by @alvarosabu) To avoid data loss, the editor preserves attributes (`class`, `id`, `title`, `role`, `lang`, `dir`, `data-*`, `aria-*`) and non-schema semantic tags. If stored HTML still contains markup the editor would normalize, the field is locked read-only with a warning dialog, so no edit or autosave can rewrite it before you confirm; raw-value editing is disabled while locked so the warning can't be bypassed. - **@directus/api** - Restricted the settings fields readable with minimal app access to those actually needed by non-admin users, no longer exposing admin-only and sensitive AI configuration fields ([#27996](https://github.com/directus/directus/pull/27996) by @br41nslug) - Fixed deployment webhooks resolving a project fro _[Truncated at 4000 characters — full notes: https://github.com/directus/directus/releases/tag/v12.2.0]_ ### v12.1.1 - Date: 2026-07-01 - Version: v12.1.1 - Original notes: https://github.com/directus/directus/releases/tag/v12.1.1 - Permalink: https://whatsnew.fyi/product/directus/releases/v12.1.1 - **changed** — Updated vite dependency to 8.1.2 in @directus/app - **changed** — Updated vite dependency to 8.1.2 in @directus/api > [!NOTE] > Directus is free for individuals and organizations under $5M annual revenue and 50 employees.\ > Get your free license key at [directus.com/oig](http://directus.com/oig) ###### 🐛 Bug Fixes & Optimizations - **@directus/app** - Updated vite dependency to 8.1.2 ([#27826](https://github.com/directus/directus/pull/27826) by @ComfortablyCoding) - **@directus/api** - Updated vite dependency to 8.1.2 ([#27826](https://github.com/directus/directus/pull/27826) by @ComfortablyCoding) ###### 📦 Published Versions - `@directus/app@16.2.1` - `@directus/api@37.0.1` ### v12.1.0 - Date: 2026-07-01 - Version: v12.1.0 - Original notes: https://github.com/directus/directus/releases/tag/v12.1.0 - Permalink: https://whatsnew.fyi/product/directus/releases/v12.1.0 - **removed** — Remove /utils/hash/generate and /utils/hash/verify endpoints - **security** — Harden upload path validation to prevent writes to extension and temporary storage directories - **security** — Add CORS_ORIGIN checks for websocket connections - **changed** — Limit sensitive system mutations defined by GRAPHQL_SINGLE_USE_MUTATIONS to single use - **changed** — Update GraphQL WebSocket restrictions to match the HTTP endpoint and hide validation hints when introspection is disabled - **changed** — Harden the published Docker image and drop npm/npx from the runtime - **added** — Publish a distroless Docker Hardened Image (DHI) variant under a -dhi tag suffix - **added** — Add PROJECT_OWNER_ENABLED env var to allow disabling owner info collection and sync - **added** — Add v-kbd component and support { text, kbd } syntax in tooltip - **added** — Replace tooltip with Reka UI one - **changed** — Update bundled esbuild to 0.28.1 - **fixed** — Restore pre-v12 back button behavior to return to previously visited item/page when navigating via a relation - **fixed** — Fix public page foreground image rendering to overlay shader background instead of rendering side-by-side - **fixed** — Fix array indexing in display and preview URL templates so templates like {{ categories[0].name }} resolve to the indexed value - **security** — Fix stored XSS vulnerability where the project color could break out of the generated favicon's SVG markup - **fixed** — Fix internal server error when validating out-of-range integer values - **security** — Fix Local File Inclusion vulnerability in MailService.renderTemplate - **fixed** — Fix Postgres value too long errors being misattributed to an unrelated field - **added** — Add validation to restrict geometry types to known types - **fixed** — Fix accountability overrides in the graphql websocket > [!NOTE] > Directus is free for individuals and organizations under $5M annual revenue and 50 employees.\ > Get your free license key at [directus.com/oig](http://directus.com/oig) ###### ⚠️ Potential Breaking Changes - **@directus/api** - Limited sensitive system mutations defined by GRAPHQL_SINGLE_USE_MUTATIONS to single use ([#27801](https://github.com/directus/directus/pull/27801) by @br41nslug) - Removed `/utils/hash/generate` and `/utils/hash/verify` endpoints ([#27774](https://github.com/directus/directus/pull/27774) by @br41nslug) - Fixed failed TUS file replacements leaving orphaned file records. Hardened upload path validation to prevent writes to extension and temporary storage directories ([#27803](https://github.com/directus/directus/pull/27803) by @br41nslug) - Updated GraphQL WebSocket restrictions to match the HTTP endpoint and hid validation hints when introspection is disabled ([#27801](https://github.com/directus/directus/pull/27801) by @br41nslug) - Added CORS_ORIGIN checks for websocket connections ([#27812](https://github.com/directus/directus/pull/27812) by @br41nslug) - **@directus/specs** - Removed `/utils/hash/generate` and `/utils/hash/verify` endpoints ([#27774](https://github.com/directus/directus/pull/27774) by @br41nslug) - **@directus/sdk** - Removed `/utils/hash/generate` and `/utils/hash/verify` endpoints ([#27774](https://github.com/directus/directus/pull/27774) by @br41nslug) - Hardened the published Docker image and added a distroless Docker Hardened Image (DHI) variant alongside it. The standard image now applies outstanding OS-level patches at build time and drops `npm`/`npx` from the runtime; the new DHI variant is published under a `-dhi` tag suffix ([#27670](https://github.com/directus/directus/pull/27670) by @br41nslug) ###### ✨ New Features & Improvements - **@directus/app** - Added `PROJECT_OWNER_ENABLED` env var to allow disabling owner info collection and sync ([#27802](https://github.com/directus/directus/pull/27802) by @ComfortablyCoding) - Replaced tooltip with Reka UI one ([#27029](https://github.com/directus/directus/pull/27029) by @HZooly) - Added `v-kbd` component and support `{ text, kbd }` syntax in tooltip ([#27029](https://github.com/directus/directus/pull/27029) by @HZooly) - Updated bundled `esbuild` to `0.28.1` (resolves GHSA-gv7w-rqvm-qjhr) ([#27738](https://github.com/directus/directus/pull/27738) by @br41nslug) - **@directus/api** - Added `PROJECT_OWNER_ENABLED` env var to allow disabling owner info collection and sync ([#27802](https://github.com/directus/directus/pull/27802) by @ComfortablyCoding) - **@directus/env** - Added `PROJECT_OWNER_ENABLED` env var to allow disabling owner info collection and sync ([#27802](https://github.com/directus/directus/pull/27802) by @ComfortablyCoding) ###### 🐛 Bug Fixes & Optimizations - **@directus/app** - Restored pre-v12 back button behavior: returns to the previously visited item/page when navigating via a relation, and to the collection listing when landing on an item directly ([#27799](https://github.com/directus/directus/pull/27799) by @robluton) - Fixed the public page foreground image rendering side-by-side with the shader background instead of overlaying it ([#27782](https://github.com/directus/directus/pull/27782) by @alvarosabu) - Added clearable indicator to input hash field ([#27729](https://github.com/directus/directus/pull/27729) by @robluton) - Added lazy loading of social icons on v-button ([#27724](https://github.com/directus/directus/pull/27724) by @alvarosabu) - Bumped version of @directus/license package ([#27785](https://github.com/directus/directus/pull/27785) by @AlexGaillard) - Fixed array indexing (e.g. `field[0]` or `field.0`) in display and preview URL templates, so a template like `{{ categories[0].name }}` now resolves to the indexed value instead of rendering empty ([#27773](https://github.com/directus/directus/pu _[Truncated at 4000 characters — full notes: https://github.com/directus/directus/releases/tag/v12.1.0]_ ### v12.0.2 - Date: 2026-06-12 - Version: v12.0.2 - Original notes: https://github.com/directus/directus/releases/tag/v12.0.2 - Permalink: https://whatsnew.fyi/product/directus/releases/v12.0.2 - **added** — Added support for non-interactive mode in create-directus-extension - **fixed** — Fixed user count for users with conflicting direct policy and role > [!NOTE] > Directus is free for individuals and organizations under $5M annual revenue and 50 employees.\ > Get your free license key at [directus.com/oig](http://directus.com/oig) ###### ✨ New Features & Improvements - **create-directus-extension** - Added support for non-interactive mode ([#27577](https://github.com/directus/directus/pull/27577) by @pklenovic) ###### 🐛 Bug Fixes & Optimizations - **@directus/api** - Fixed user count for users with conflicting direct policy and role ([#27720](https://github.com/directus/directus/pull/27720) by @ComfortablyCoding) ###### 📦 Published Versions - `@directus/app@16.1.1` - `@directus/api@36.0.2` - `create-directus-extension@12.1.0` ### v12.0.1 - Date: 2026-06-11 - Version: v12.0.1 - Original notes: https://github.com/directus/directus/releases/tag/v12.0.1 - Permalink: https://whatsnew.fyi/product/directus/releases/v12.0.1 - **added** — Added keyboard-editable date entry directly in the datetime field with formatted value display at rest and editable date segments on focus - **added** — Added inline editing support to the JSON repeater interface - **fixed** — Fixed license badge spacing issue - **fixed** — Fixed license modals being impossible to dismiss when shown above a route drawer by keeping dialog focus traps stacked in visual order and scoping license dismissal cookies to the whole app - **fixed** — Fixed revision snapshots being assigned to the wrong items during batch updates when read order differs > [!NOTE] > Directus is free for individuals and organizations under $5M annual revenue and 50 employees.\ > Get your free license key at [directus.com/oig](http://directus.com/oig) ###### ✨ New Features & Improvements - **@directus/app** - Added keyboard-editable date entry directly in the datetime field. The field shows its formatted value at rest and swaps to editable date segments on focus, while a calendar button still opens the picker popup. ([#27693](https://github.com/directus/directus/pull/27693) by @robluton) - Added inline editing support to the JSON repeater interface. ([#26863](https://github.com/directus/directus/pull/26863) by @bryantgillespie) ###### 🐛 Bug Fixes & Optimizations - **@directus/app** - Fixed license badge spacing issue ([#27713](https://github.com/directus/directus/pull/27713) by @robluton) - Fixed license modals being impossible to dismiss when shown above a route drawer (e.g. field detail pages) by keeping dialog focus traps stacked in visual order, and scoped license dismissal cookies to the whole app so dismissals persist across navigation ([#27714](https://github.com/directus/directus/pull/27714) by @dstockton) - **@directus/api** - Fixed revision snapshots being assigned to the wrong items during batch updates when read order differs ([#27407](https://github.com/directus/directus/pull/27407) by @luciemdx) ###### 📦 Published Versions - `@directus/app@16.1.0` - `@directus/api@36.0.1` ### v12.0.0 - Date: 2026-06-10 - Version: v12.0.0 - Original notes: https://github.com/directus/directus/releases/tag/v12.0.0 - Permalink: https://whatsnew.fyi/product/directus/releases/v12.0.0 - **added** — Introduce active license enforcement for Directus 12, with Core tier as default for self-hosted instances - **added** — Add VERSION_KEY_* constants and support ?version=published query parameter for resolving versions of main items - **added** — Add header action button to edit draft versions in versioned collections - **added** — Share health check results across multi-instance deployments with caching - **changed** — Relicense from BUSL-1.1 to MSCL-1.0-GPL - **changed** — Change IP_TRUST_PROXY default from true to false to harden against IP spoofing - **changed** — Replace status field with archived boolean in collection settings for newly created collections - **changed** — Replace cache, rateLimiter, and rateLimiterGlobal health checks with generic redis check using redis: prefix - **changed** — Lock published items in versioned collections from editing - **changed** — Remove rounded prop from v-button component - **changed** — Remove headerShadow and sidebarShadow from LayoutConfig interface for theme extensions - **changed** — Remove boxShadow from header theme rules schema for theme extensions - **changed** — Remove sidebarShadow from layout wrapper state exposure for theme extensions - **changed** — Remove navigation.project.borderColor, navigation.project.borderWidth, and navigation.project.background from theming - **changed** — Merge header and navigation bar theme properties into new shell scope with shell.background, shell.backgroundAccent, shell.borderWidth, and shell.borderColor - **removed** — Disable SSO login without a valid license - **removed** — Disable custom permission rules without a valid license - **removed** — Disable custom or self-hosted LLM connections without a valid license - **removed** — Restrict /server/health endpoint to authenticated users; use /server/ping for liveness checks instead - **deprecated** — Deprecate VResizeable component for extension authors in favor of @directus/vue-split-panel **License Enforcement** > [!NOTE] > Directus is free for individuals and organizations under $5M annual revenue and 50 employees.\ > Get your free license key at [directus.com/oig](http://directus.com/oig) Directus 12 introduces active license enforcement. Self-hosted instances run on the **Core tier** by default. Higher limits and additional features require a valid license. See [Licensing](https://directus.com/docs/licensing/overview) for a complete overview. This change affects instances previously using features that now require a license, including: - **SSO** — SSO login will no longer work. Users who authenticate through SSO will be unable to log in and must be converted to email and password users to regain access. - **Custom permission rules** — custom rules on access policies will be ignored. - **Custom or self-hosted LLMs** — connections to custom LLMs will no longer work. - **AI Translations** — AI-powered translations are not available. Enforcement is immediate on new instances. Instances upgrading to Directus 12 get a 30-day [grace period](https://directus.com/docs/releases/breaking-changes/version-12#post-upgrade-grace-period) from the time of upgrade, after which these are enforced unless a license that enables them is configured. If your instance uses any of these features, add a license that includes them to continue to do so. If your instance uses only Core tier features, no action is required. **Changed license to MSCL-1.0-GPL ([#27417](https://github.com/directus/directus/pull/27417))** - Breaking Change: Relicensed from BUSL-1.1 to MSCL-1.0-GPL (Monospace Sustainable Core License, Version 1.0). **Changed the default of `IP_TRUST_PROXY` from `true` to `false` to harden the default deployment against IP spoofing. ([#27607](https://github.com/directus/directus/pull/27607))** - The `IP_TRUST_PROXY` default was changed from `true` to `false`. If you run Directus behind a reverse proxy and rely on `X-Forwarded-For` (or similar) headers for client IP resolution, you must now explicitly set `IP_TRUST_PROXY` to `true` or a more specific trust configuration. **Fixed health check results not being shared in multi-instance settings. Restricted `/server/health` to authenticated users ([#27160](https://github.com/directus/directus/pull/27160))** - Health checks are cached by default and shared across multi-instance deployments - `/server/health` will return 404 for unauthenticated requests, use `/server/ping` for liveness checks - `cache`, `rateLimiter` and `rateLimiterGlobal` health checks have been replaced by a generic `redis` check using the `redis:` prefix **Introduced VERSION_KEY_* constants and renamed main to published @alvarosabu ([#27397](https://github.com/directus/directus/pull/27397))** - Backward Compatibility: You can now use `?version=published` to resolve versions of the main item(s) via the version query parameter. For backward compatibility, `?version=main` will continue to work. **Replaced status field with archived boolean in collection settings @alvarosabu ([#27397](https://github.com/directus/directus/pull/27397))** - Backward Compatibility: Existing collections with string-based status fields continue to work unchanged; newly created collections now default to a boolean "Archived" field instead of the string "Status" field **Deprecated the `VResizeable` component @formfcw ([#27437](https://github.com/directus/directus/pull/27437))** - Deprecation for extensions: The globally registered `VResizeable` component has been deprecated. Extension authors using `` should migrate to `@directus/vue-split-panel` or their own implementation. **Updated type system, borders, and theme variables @formfcw ([#27437](https://github.com/directus/directus/pull/27437))** - Potential breaking change for theme extensions: headerShadow and sidebarShadow removed from LayoutConfig interface - Potential breaking change for theme extensions: boxShadow _[Truncated at 4000 characters — full notes: https://github.com/directus/directus/releases/tag/v12.0.0]_