What's new with TinaCMS
Version 3.12.1
Released on 8/24/2026
Patch Changes
- @joshbermanssw-
Bump the final-form family to the TypeScript releases
- @kulesy-
Fix `Button` and `IconButton` not passing `disabled` to the DOM. Both components used the prop only to pick styling (`pointer-events-none`), which blocks the pointer but not the keyboard, so every disabled button in the CMS stayed focusable and could still be activated with Enter or Space. `busy` is now treated as disabled too, closing a double-submit path on in-flight buttons. `disabled` is omitted when `Button` renders as a tag that does not support it (`as='a'`).
- @joshbermanssw-
Drop the deprecated `crypto-js` dependency
- @joshbermanssw-
Declare the field props that `react-final-form`'s index signature used to cover
- @kulesy-
Fix "Save to new branch" failing with "Branch operation failed" when the derived branch name is not a valid Git ref, e.g. when a collection's `path` has a trailing slash, producing `content/articles//foo.mdx` and the invalid ref `tina/articles//foo`. The default branch name derived from the file path, and any user-typed name, are now normalised to a valid ref: repeated and leading/trailing slashes collapse, characters Git forbids in refs (whitespace, control characters, `~ ^ : ? * [ \` and the `@{` sequence) become hyphens, `..` runs collapse, and leading dots and trailing `.` / `.lock` are stripped per path component. Saving is disabled while the name normalises to an empty string. The same normalisation now runs when creating a branch from the branch switcher and from the deleted-branch recovery modal, and the duplicated `formatBranchName` helpers are unified into a single util (the legacy branch switcher previously deleted invalid characters; it now replaces them with hyphens like the main switcher).
- @joshbermanssw-
Add `data-test` hooks to group-list and blocks field controls
- @kulesy-
Fix two admin regressions that appear once the TinaCloud session check starts failing. Making the collection list settle instead of spinning left the previously fetched data in place, so switching collections rendered the last collection's documents under the new collection's heading; on a fresh mount it left `collection` undefined with no error set, so `GetCollection` ran its auto-open effect against it and threw, which the top-level error boundary caught and replaced the admin with a raw TypeError card. A failed session check now sends the user straight back to the login modal with a "Your session has ended" message, and signing back in returns them to the page they were on. `GetCollection` and `GetDocument` also stop handing `undefined` to their children, showing an "Unable to load" popup for non-auth load failures, and `GetCollection`'s auto-open effect bails out early, which clears the same crash on a failed `fetchCollection`.
- @kulesy-
Skip TinaCloud identity requests when no auth token is stored. Logged-out admin loads no longer produce misleading 401/CORS console errors; a clear console message now points at the login popup console instead. Also fixes an unawaited auth guard in GetDocument, stops the document view from loading forever when that guard rejects the request, and fixes an unhandled promise rejection when the project settings request fails.
- @joshbermanssw-
Add `data-test` hooks to list field controls
- @kulesy-
Fix the collection list and collection search hanging on the loading screen when the session check says the user is not signed in. Both now settle and render instead of spinning until the page is reloaded.
Version 3.12.0
Released on 8/17/2026
Minor Changes
- @Aibono1225-
Add a Rename action to the Media Manager, backed by the local dev server.
- @joshbermanssw-
Add media-manager search and a folder/file filter, and refresh the grid.
- @brookjeynes-ssw-
feat: add tina-markdown web component
Patch Changes
- @brookjeynes-ssw-
refactor: facilitate token refresh through tinacloud
- @dependabot-
Bump `mermaid` to 11.16.1, picking up an upstream security fix (GHSA-c4c3-pg64-4m4v)
- @brookjeynes-ssw-
feat: add announcements banner
- @wicksipedia-
Collapse three icon libraries into `lucide-react` (~85 MB).
- @brookjeynes-ssw-
feat: when WorkOS is enabled, use a redirect-based workflow for authentication
- @wicksipedia-
Drop `@headlessui/react` (~50 MB).
- @wicksipedia-
Stop shipping the `monaco-editor` package (~73 MB).
- @JackDevAU-
Fix the preview iframe going unresponsive after resizing the sidebar.
- @wicksipedia-
Add a dedicated `@tinacms/mdx/sanitize-url` subpath export containing just the URL-scheme sanitizer, and point `tinacms`'s rich-text renderer (`TinaMarkdown` / `StaticTinaMarkdown`) at it instead of the root `@tinacms/mdx` entry. Previously, importing `sanitizeUrl` pulled in `@tinacms/mdx`'s full remark/mdast/micromark markdown-parsing bundle (~2MB) into every site's client bundle, even though rich-text rendering only needs the ~15-line sanitizer. The root `@tinacms/mdx` export of `sanitizeUrl` is unchanged and still works.
- @joshbermanssw-
The media manager now lists assets from the v2 assets-api endpoint. Uploads and deletes are unchanged and stay on v1. Listing behaviour is identical — this is a transport-only move that sets up media search.
- @wicksipedia-
Remove dead code left over from the `monaco-editor` removal in the mdx field plugin.
- @wicksipedia-
Give the exported Plate plugin arrays (`plugins`, `viewPlugins`, `createEditorPlugins`) an explicit type, so their emitted declarations no longer carry a `.pnpm/` store path.
Version 3.11.0
Released on 7/16/2026
Minor Changes
- @joshbermanssw-
Editorial-workflow saves (Save draft / Save to a new branch, and the media create-branch flow) now run a single branch-list lookup instead of two sequential ones, roughly halving the delay before the progress modal appears.
Patch Changes
- @kulesy-
`Button` now renders the shared loading-dots indicator automatically when `busy`, so every busy button gets a consistent spinner instead of each call site wiring its own (and some, like the account password form, were missing it entirely). The dots inherit the button text color so they stay visible across variants.
- @ahfoysal-
Keep folder collection views open when they only contain one document.
- @kulesy-
Fix the rich-text link popover not appearing when adding or editing a link.
- @joshbermanssw-
Show a clear error when repo-based media is used with a self-hosted site, instead of a misleading "Bad Route" message.
- @wicksipedia-
Publish internal package references as ranges instead of exact versions.
Version 3.10.1
Released on 7/12/2026
Version 3.10.0
Released on 7/6/2026
Minor Changes
- @joshbermanssw-
editorial workflow - add toggle to switch PRs created between draft and ready to review mode
Patch Changes
- @joshbermanssw-
Update `@radix-ui/*` dependencies to their latest patch/minor releases and remove the unused `@radix-ui/react-checkbox` dependency
- @joshbermanssw-
Add a PostHog `editorial-workflow-save` event that records which save option was used in the "Save changes to new branch" modal (draft, ready for review, or publish), whether the save succeeded, and the failure reason when it didn't.
- @joshbermanssw-
Editorial workflow: replace the draft / ready-for-review toggle in the "Save changes to new branch" modal with a save-options dropdown (Save draft, Save (ready for review), Save and publish). The split button's main action reflects the editor's last choice (default Save draft, remembered via localStorage), and Save and publish is disabled with a tooltip on protected branches.
- @joshbermanssw-
move floatingtoolbar for links to a react portal
- @joshbermanssw-
refactor: replace hardcoded error-message string checks with shared error-identifier constants in `@tinacms/schema-tools`, so producers and consumers reference one source of truth instead of fragile `error.message.includes('...')` matching (#6777)
- @kulesy-
Unify folder-name validation with the document-filename and backend `relativePath` allowlist. The Create Folder modal now rejects names with disallowed characters (e.g. spaces) inline instead of letting the request fail on the backend, and a project-level `folderNameRegex` is layered on top of that baseline. The allowlist lives in a single shared constant in `@tinacms/schema-tools`.
- @Aibono1225-
Harden message handling in the `useEditState` hook so it validates the sender of incoming `message` events, matching the `isFromAdmin(event, trustedAdminOrigins)` check already used by `useTina`. The hook now also removes its `message` listener on unmount. Legitimate admin→preview behavior is unchanged.
Version 3.9.4
Released on 7/1/2026
Patch Changes
- @isaaclombardssw-
feat(tinacms): add a back-to-collection breadcrumb on the admin editor/create pages and in the visual editor sidebar, switch the breadcrumb separator from a chevron to a slash, show only the filename (not the full folder path) in the root breadcrumb across both editors, and truncate long crumbs so the trail no longer overflows
- @isaaclombardssw-
Improve global collection UX: global collections now appear once in the sidebar "Site" section (globe icon) instead of being duplicated under Collections, open directly in the form instead of a popup modal, and single-document global collections skip the document list and go straight to the form. Global collections with zero or multiple documents fall through to the normal list view.
- @Aibono1225-
Fix Local Mode banner for absolute contentApiUrlOverride
- @wicksipedia-
Move `moment-timezone` to devDependencies so its timezone database no longer ships in the admin bundle. It was loaded via a non-tree-shakeable side-effect import, but production code never used the `moment.tz` API (only a unit test did). Removes ~39 KB gzip (~732 KB uncompressed) from the first admin load. No behavior change.
- @wicksipedia-
Remove the dead `mdx-field-plugin/plate/plugins/ui/icons.tsx` module (398 lines of unused inline-SVG icons). Its single consumed export (`EllipsisIcon`) now resolves from the shared `plate-ui/icons` module. No behavior change.
- @18-th-
Remove unused `add` dependency
- @Aibono1225-
Fix media upload/delete paths to prevent access to storage keys outside mediaRoot.
- @wicksipedia-
Standardize date handling on date-fns and remove the moment stack. `@tinacms/graphql` moves to date-fns v4 (collapsing the previous v2/v4 split), and `tinacms` drops `moment`, `moment-timezone`, and `react-datetime`. The date-field display label now formats with date-fns via a non-breaking moment→date-fns token converter, so existing `dateFormat`/`timeFormat` schemas (moment token syntax) keep working unchanged. Also removes the orphaned vendored react-datetime views. Net effect: the admin bundle no longer ships moment (~18.6 KB gzip smaller first load).
Version 3.9.3
Released on 6/15/2026
Patch Changes
- @Aibono1225-
Fix crash when reopening Global Configuration after navigating to a collection in the admin
- @Aibono1225-
Harden cross-window message handling and rich-text URL sanitization.
Version 3.9.2
Released on 6/15/2026
Updated Dependencies
@tinacms/search@1.2.18
Version 3.9.1
Released on 6/5/2026
Patch Changes
- @JackDevAU-
Skip the filesystem-backed response cache on edge runtimes (Cloudflare Workers, Vercel Edge) where Node's `fs` API is present but unusable, which could otherwise hang concurrent identical queries. Adds a `cache` option to `createClient` to force-disable the cache.
Version 3.9.0
Released on 6/3/2026
Minor Changes
- @JackDevAU-
chore: remove deprecated code
- @18-th-
Support Tina media uploads and deletes in the editorial workflow on protected branches. Media changes now prompt for a branch, write to that branch, switch the editor to it after the media operation succeeds, and continue through indexing and pull request creation with the same workflow progress UI as content edits.
Patch Changes
- @JackDevAU-
Remove deprecated GitClient.onSubmit alias