Product Updates

DatoCMS changelog for new features and general improvements
CLI Content Management API API Clients New

CLI and CMA Improvements: cma:script, Stricter Types, and Dastdown

May 18th, 2026

The last couple of weeks brought a set of converging improvements across the CLI, the JS CMA client, and the structured-text packages.

datocms schema:generate now exposes runtime ID and REF constants

The schema types generator now emits Schema.Article.ID and Schema.Article.REF alongside the existing TypeScript types. No more hardcoded item-type ID strings drifting out of sync across environments!

// type position: the model's TS shape, as before
const article = await client.items.find<Schema.Article>(id);
// value position: the model's id and ref, generated from your project
await client.items.create({
item_type: Schema.Article.REF,
// …
});
if (item.relationships.item_type.data.id === Schema.Article.ID) {
// …
}

New FieldValue<T, K> helpers

Three new helpers let you derive a field's type directly from an existing record or block for the full read/write cycle:

  • FieldValue<T, K> — standard response shape

  • FieldValueInNestedResponse<T, K> — what you get when reading with nested: true

  • FieldValueInRequest<T, K> — what client.items.create / update expects

T accepts anything item-shaped like a fetched record, a nested block, or an ItemTypeDefinition directly. The typical flow this unlocks: read a record with nested: true, iterate and mutate its nested blocks, and write the result back. Typing the accumulator takes one line:

const page = await client.items.find<LandingPage>(id, { nested: true });
const sections: FieldValueInRequest<typeof page, 'sections'> = [];

New isBlockWithItemOfType predicate

isBlockWithItemOfType (and its isInlineBlockWithItemOfType counterpart) from datocms-structured-text-utils narrows a block node to a specific model shape using its item type ID. Works in findFirstNode, mapNodes, or standard conditionals, giving you typed access to .item.attributes directly without extra casting.

// inline guard
if (isBlockWithItemOfType(Schema.CtaBlock.ID, node)) {
// node.item.attributes is now typed as CtaBlock
}
// curried predicate
const firstCta = findFirstNode(content, isBlockWithItemOfType(Schema.CtaBlock.ID));

Edit Structured Text as plain text with datocms-structured-text-dastdown

The new datocms-structured-text-dastdown package gives you a lossless, markdown-flavored serialization for DatoCMS Structured Text documents. Serialize to plain text, edit it however you like (string manipulation, regex, LLM rewrite), and parse back instead of walking the AST.

Best fit: text-heavy content like articles, docs, and chapters where edits are textual and may cross node boundaries. Not for landing pages made of opaque blocks — referenced blocks stay opaque in the serialized form, so you can move or remove them but not edit their internals at this layer.

A typical round-trip would look like:

import { parse, serialize } from 'datocms-structured-text-dastdown';
const cur = await client.items.find<Schema.Article>('article-id', { nested: true });
const text = serialize(cur.body);
const edited = text.replace(/Acme Corp/g, '**Acme Inc.**');
const body = parse(edited, cur.body);
await client.items.update<Schema.Article>('article-id', { body });

mapNodes now supports full tree rewrites

mapNodes and mapNodesAsync from datocms-structured-text-utils now support structural transforms, not just 1:1 node mapping. The return value controls what happens:

  • Return a single node: direct replacement

  • Return an array: splat into the parent's children

  • Return null or undefined: remove the node entirely

New agent-targeted commands

We've also shipped datocms cma:script, datocms schema:inspect, and enhanced datocms cma:docs - commands designed to be used by your agents directly. These are documented in the CLI repo and will evolve as agent tooling matures.


To update: npm i -g datocms for CLI changes, npm i @datocms/cma-client-node@latest for client changes, npm i datocms-structured-text-dastdown for the new package.

CLI New

CLI: `npx datocms` now Just Works

April 29th, 2026

The DatoCMS CLI is now published on npm as datocms — an unscoped package with the same name as its binary. The scoped @datocms/cli package is still around as a thin alias, so existing setups keep working unchanged.

The main win: npx datocms now "Just Works" in every context — whether the package is installed locally, globally, or not installed at all.

Why this matters

Until now, running npx datocms projects:list inside a project that had @datocms/cli installed could result in a confusing error:

Terminal window
$ npx datocms projects:list
npm error Missing script: "datocms"

This is an npm/npx quirk: when the package name and binary name differ, it can't always find the CLI and bails out. pnpm, yarn, and bun all handled this case correctly — it's only npm users who got bitten. Now that the package and binary share the same name, the most natural command just works. As a bonus, we now own the unscoped datocms name on npm, so it can't get squatted.

What changes for you

  • New users: run npx datocms ... or npm i -g datocms. That's it.

  • Existing users on @datocms/cli: nothing to do. Your setup keeps working, and you'll transparently pick up the new datocms package as a dependency. Migrating is a one-line change in package.json whenever you feel like it.

  • Existing migration files importing from @datocms/cli/lib/cma-client-node: still work, no changes needed. New migration files use datocms/lib/cma-client-node.

Head over to the docs on configuring the CLI for installation details.

Content Management API

CMA limit raised for Developer Plan

April 20th, 2026

We have raised the CMA limit of the developer plan from 10K to 25K monthly API calls, to make it easier to get started with projects on the free plan.

CLI New

CLI: Easier (and safer) project linking with OAuth

April 14th, 2026

Setting up the DatoCMS CLI used to involve a clunky ritual of creating an API token in project settings, copying it, pasting it into an environment variable, and hoping you got it right. Repeat for every project. And since teams shared the same token, there was no way to tell who actually performed a given action in audit logs.

OAuth login is now the recommended way to authenticate. The new setup is fully guided: datocms login opens your browser, datocms link lets you search and select a project interactively with no tokens to copy, and no environment variables to configure. Every API call is tied to your personal identity, giving teams clear visibility over who made which changes.

During the authorization step, you can choose to grant the CLI access to all your projects or limit it to only the ones you select, so you stay in control of exactly which projects are exposed.

New commands

  • datocms login authenticates your DatoCMS account via OAuth. It opens your browser for a secure login flow. If the browser can't be opened, it falls back to a manual URL flow.

  • datocms link connects the current directory to a specific DatoCMS project. The interactive flow walks you through choosing a workspace, searching for a project, and configuring migration settings. Once linked, every CLI command in that directory automatically resolves an API token using your OAuth credentials. No environment variables needed.

  • datocms logout to remove credentials.

  • datocms whoami to check which account you're logged in as.

  • datocms unlink to disconnect a directory from a project.

What changes for existing users

Nothing breaks. The old profile:set and profile:remove commands still work, they just redirect to link and unlink under the hood. Existing scripts and CI/CD pipelines using DATOCMS_API_TOKEN or the --api-token flag are completely unaffected.

When a command needs an API token, the CLI now resolves it in this order: --api-token flag first, then environment variable, then linked project via OAuth. So your current setup always takes precedence.

Getting started

You can upgrade the CLI to the latest version with:

Terminal window
npm install -g @datocms/cli@latest

For teams that want user-level audit trails, the migration is straightforward: each team member runs datocms login once, then datocms link in each project directory. From that point on, all commands use personal credentials automatically.

You can still use DATOCMS_API_TOKEN in CI/CD or anywhere OAuth login isn't practical. If you prefer a custom environment variable name, you can configure it during datocms link.

OAuth authorizations can be reviewed and revoked at any time from your account settings, under "Authorized applications":

Explore the docs to get up to speed on Configuring the CLI.

Docs, Guides and Demos Plugins

Starter kits now ship with a plugin scaffold

April 9th, 2026

The Astro and Next.js starter kits now come with a private DatoCMS plugin already wired up, giving you a ready-made foundation to start building custom editor experiences from day one, with no separate repo, and no manual installation.

Because the Plugin SDK and datocms-react-ui component library are built on React, this feature is available in the React-based starters (Astro and Next.js) but not in the SvelteKit or Nuxt starters.

Build custom plugins right inside your project

The plugin lives alongside your site code and is served as a regular page (/private-datocms-plugin). On your first deploy it installs itself automatically via the post-deploy hook — zero manual setup in the dashboard. The source mirrors the structure of official DatoCMS plugins.

The included config screen links straight to the docs to help you get started:

Astro starter upgraded to Astro 6

The Astro starter has also been upgraded to Astro 6 along with all official integrations (@astrojs/node, @astrojs/react, @astrojs/check) and @datocms/cli v4. The minimum Node version is now 22.

Images API Content Management API New

Automatic antivirus scanning for all Media Area uploads

April 7th, 2026

Every file uploaded to the DatoCMS Media Area is now automatically scanned for viruses and malware. No configuration, no opt-in or workflow changes required from your side.

How it works

The moment a file is uploaded, a background scan is queued automatically. Editors can continue working since there's no blocking step or wait time. Within seconds, each file is assigned one of four statuses:

  • Clean: no threats detected and file is served normally

  • Infected: a threat was detected and the file is automatically quarantined

  • Skipped: the file exceeds the scanner's size or type limits and could not be assessed. Treat these files with appropriate caution

  • Failed: an error occurred during scanning, and will be retried automatically up to 6 times with exponential backoff. If it still cannot be scanned, then the file remains in a failed state

ℹ️ If an asset is replaced with a new version, the antivirus scan runs again automatically on the new file.

Quarantined files

When a threat is detected, infected files are automatically quarantined and DatoCMS will:

  1. Remove the file from public storage

  2. Purge it from the CDN cache, and

  3. Keep the upload record visible in the Media Area so editors can see it was flagged, but the file URL will no longer serve any content

Editors should replace the asset to restore functionality.

For projects using a custom storage bucket, DatoCMS does not have permission to delete or move files from your storage. In this case, the file will still be accessible from your own bucket even after being flagged, and the upload record will be marked as infected, and editors will see the file path so they can remove it manually. The warning UI in the Media Area will reflect this.

Dashboard Changes

Infected files are surfaced throughout the Media Area:

A "Threat detected" badge appears on the upload card in grid, masonry, and table views. On smaller cards, this collapses to an icon with a tooltip

Opening an infected file replaces the normal preview with a warning screen that explains the situation, shows the specific threat name (useful for investigation), and prompts the editor to replace the asset

For custom storage projects, the warning is adjusted to show the file path and advise manual removal from the bucket

Editors can filter uploads by antivirus status (clean, infected, skipped, failed, pending) directly in the Media Area search. This filter is not available in the Content Delivery API.

Scan results are delivered in real time with the antivirus status in the dashboard updating live without requiring a page refresh, and Webhooks are fired on status changes, so you can build integrations that react to scan results, for example, getting a Slack alert when an infected file is detected in your project.

API Access

The antivirus status is also available on every upload object via the CMA, under a new meta.antivirus field:

"meta": {
"antivirus": {
"status": "infected",
"scanned_at": "2026-03-27T18:51:00Z",
"threat_name": "Trojan.GenericKD.12345"
}
}

The object includes the scan status, the timestamp of the last scan, and the threat name when applicable. It's worth knowing that antivirus scan results are preserved when forking environments, with no rescanning needed, and when duplicating a project, infected files are automatically excluded from the copy to prevent propagation.

Refer to the docs for more information on how this works.

Plugins New

Configurable `hue` property on Visual Editing

March 23rd, 2026

When using the Visual Editing feature, the overlay color used to highlight editable areas can now be customized via a hue property (accepts values 0–359) in the configuration.

Previously, editable regions were always indicated with an orange highlight, which could create a usability problem for sites with orange-heavy designs, where the overlay could blend into the page.

All the SDKs now have a configurable hue property to allow the highlight to stand out regardless of your brand palette.

Get started with Visual Editing from the docs.

Security Images API

Introducing Permissions for Asset Collections

March 10th, 2026

Building up on our earlier release for Asset Collections, you can now assign specific permissions for users to assets within Collections, including read, write, and a new dedicated move permission that controls whether users can move assets from one collection to another.

Permissions assigned to a collection are automatically inherited by its sub-collections, with inheritance rules clearly displayed in the UI.

To enable or change access for collections, go to settings and select Asset Permissions > Collections when editing User Roles.

UI Improvement

Pre-filter linked records with saved filters

February 18th, 2026

If you've ever had editors accidentally linking the wrong records because the list was too broad, this one's for you. When linking records, the list of available items can get overwhelming, especially when it includes outdated or irrelevant records that editors shouldn't pick (like records still in drafts).

To address this, we've introduced a way to pre-filter linked records with saved filters, letting you control exactly which records appear when editors browse items to link.

What's new?

The standard editors for Single and Multiple Link fields (compact and expanded) now include a new settings section. Here, you can pair each linked model with one of your saved shared filters, so editors only see the records that they should.

How do I enable it?

Head to the Presentation tab in your Link field settings. You'll see the new Applied Filters section right away: just pick a model, choose a filter, and you're done. If you need more filters, create more saved filters in the Content Area to configure another.

The only prerequisite is that you need at least one shared saved filter for the models you want to filter. Private filters aren't available here.

Images API Video API New

New media editor for images AND videos

February 13th, 2026

We've rolled out considerable changes and updates to the media editor inside the CMS's Media Area. The new update brings changes to editing images, and introduces in-CMS video editing.

If you need to edit an uploaded image, you can use the built-in editor to crop, rotate, apply predefined color filters, tweak colors, and resize images:

Similarly, if you need to edit an uploaded video, you can also do this in the CMS now, with options to trim, add filters, and other similar edits.

After you're done editing your asset, you can choose to save it as a duplicate (available under a new URL), or replace the original asset and retain the URL.

Start using DatoCMS today
According to Gartner 89% of companies plan to compete primarily on the basis of customer experience this year. Don't get caught unprepared.
  • No credit card
  • Easy setup
Subscribe to our newsletter! 📥
One update per month. All the latest news and sneak peeks directly in your inbox.
support@datocms.com ©2026 Dato srl, all rights reserved P.IVA 06969620480