- [Minor Changes](#minor-changes)
- [Patch Changes](#patch-changes)#7391 ece366b Thanks @Aibono1225! - Add a Rename action to the Media Manager, backed by the local dev server.
Selecting a file in the media preview now offers Rename alongside Insert and Delete. The modal edits the basename, keeps the extension, previews the sanitised result using the same rules uploads apply, and reports collisions and missing files specifically instead of a generic failure. Every open media picker refreshes afterwards, and pickers previewing the renamed file follow it to its new path.
Renaming does not update content that already references the old path — the modal says so explicitly.
The action only appears when the media store implements rename. TinaMediaStore implements it for local development via a new POST /media/rename route on the CLI dev server; TinaCloud, static and self-hosted repo-media stores do not advertise it, so the action stays hidden there rather than failing on click. Third-party stores (S3, Cloudinary, DigitalOcean Spaces, Azure) can opt in by implementing MediaStore.rename.
MediaManager.rename() dispatches media:rename:start, media:rename:success and media:rename:failure.
#7323 4a19d66 Thanks @joshbermanssw! - Add media-manager search and a folder/file filter, and refresh the grid.
Search filters the library by file path (debounced, recursive across folders); the All | Folders | Files toggle narrows the view. Folders and files render in labelled sections, files show a type badge (JPEG/PNG/MP4…), and videos show a play overlay.
Search works against both TinaCloud media and local dev media. The local dev-server media endpoint (@tinacms/cli) now honours a search query param, matching paths recursively within the requested folder (case-insensitive) and staying within the media root. Matching is on the folder-relative path, so a folder name matches the files beneath it, and matching folders surface as their own folder results (local dev media; TinaCloud parity to follow). Results are paginated with the same limit/cursor contract as an unfiltered listing.
The search box is opt-in per media store via a new searchable flag on the MediaStore interface. The default (TinaCloud/local) store sets it; a custom or self-hosted store shows the box only once it sets searchable and reads options.search in its list(), so stores that don't support search don't get a box that returns unfiltered results.
Also fixes the breadcrumb rendering a duplicate root crumb — and Back not returning to the root — for folder names that carry a trailing slash.
#7392 4b7d9b9 Thanks @brookjeynes-ssw! - feat: add tina-markdown web component
feat: add visual-editing library for web components
#7304 d7a1641 Thanks @brookjeynes-ssw! - refactor: facilitate token refresh through tinacloud
#7422 f014558 Thanks @dependabot! - Bump mermaid to 11.16.1, picking up an upstream security fix (GHSA-c4c3-pg64-4m4v)
#7388 17931b7 Thanks @brookjeynes-ssw! - feat: add announcements banner
#7216 cf75e5b Thanks @wicksipedia! - Collapse three icon libraries into lucide-react (~85 MB).
tinacms declared react-icons (84 MB), lucide-react (32 MB) and @heroicons/react as production dependencies, so every user installed all three. Icon usage is entirely internal admin chrome — there is no icon-picker, no icon schema field type, and no dynamic whole-set import — so react-icons and @heroicons/react have been removed in favour of lucide-react, which was already the de-facto house set.
Not a breaking change for user content, schemas, or plugins: ScreenPlugin.Icon is typed any, and CloudConfigOptions is not publicly exported. The internal IconType prop type is now lucide's LucideIcon.
Six icons have no exact lucide counterpart and were substituted: BsCheckCircleFill/BsExclamationOctagonFill → CircleCheck/OctagonAlert (lucide is outline-only), MdSyncProblem → RefreshCwOff, TbLogs → ScrollText, BiRename → SquarePen, MdOutlineDataSaverOff → Info.
#7327 5050709 Thanks @brookjeynes-ssw! - feat: when WorkOS is enabled, use a redirect-based workflow for authentication
#7216 cf75e5b Thanks @wicksipedia! - Drop @headlessui/react (~50 MB).
Headless UI v2 pulls in the entire React Aria stack (react-aria 34.8 MB, react-stately 9.4 MB, @internationalized/*) — about 50 MB installed — to provide components Radix already covers. tinacms was shipping three headless component libraries at once (@radix-ui/* in 22 files, @headlessui/react in 11, @ariakit/react in 1).
The 11 Headless UI files now use Radix (Popover, DropdownMenu) and local state, consolidating on the library that was already the majority. No new dependencies were added.
Transition/TransitionChild are replaced by a small local equivalent with the same prop API (show, appear, enter*/leave*). It uses element.getAnimations({ subtree: true }) so a parent transition with no classes of its own still waits for its children to finish leaving before unmounting.
#7214 bd4df92 Thanks @wicksipedia! - Stop shipping the monaco-editor package (~73 MB).
Every import of monaco-editor in shipped source was types-only. The editor itself has always been fetched from a CDN at runtime by @monaco-editor/loader, so the 73 MB installed on every user's disk was never executed — and was a different version (0.31.0) from the one that actually runs (0.55.1, the loader's default).
monaco-editor is a required peer dependency of @monaco-editor/react, and npm 7+ auto-installs required peers, so removing it from our dependencies was not enough on its own. @tinacms/app now uses @monaco-editor/loader directly — the same loader @monaco-editor/react wraps, so the CDN and editor version are unchanged — and monaco-editor is kept as a devDependency for its types.
The copy of the raw editor in packages/tinacms was dead code: nothing imported it, it was not exported, and its parseMDX/stringifyMDX were stubs returning empty values. The live raw editor lives in @tinacms/app and is injected into tinacms as the rawEditor prop. It has been deleted, letting tinacms drop both monaco packages entirely.
No behaviour change: raw MDX mode still loads the same editor from the same CDN.
#6403 566f977 Thanks @JackDevAU! - Fix the preview iframe going unresponsive after resizing the sidebar.
Dragging the resize handle used to disable pointer events on the entire app so the drag would survive the cursor crossing into the preview. Releasing the drag over the preview left it dead to clicks and scrolling until you clicked the sidebar again. The handle now uses pointer capture, which keeps the drag targeting the handle without touching the rest of the page, so the preview stays interactive throughout.
Also corrects the handle's fullscreen guard, which read a fullscreen key the sidebar context has never provided and so never fired. No behaviour change today, since nothing currently puts the sidebar into the fullscreen display state.
#7233 5f14d96 Thanks @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.
#7322 b6199da Thanks @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.
#7231 5112e60 Thanks @wicksipedia! - Remove dead code left over from the monaco-editor removal in the mdx field plugin.
#7428 8c8e297 Thanks @wicksipedia! - Give the exported Plate plugin arrays (plugins, viewPlugins, createEditorPlugins) an explicit type, so their emitted declarations no longer carry a .pnpm/ store path.
The Plate satellite packages take @udecode/plate as a peer and never depend on @udecode/plate-core directly, so pnpm resolves it through the hoisted store. Once @tinacms/rich-text brought in a React 19 copy, the hoisted pick could land on a variant that nothing in tinacms is able to name, and tsc then failed with TS2742 rather than emit a declaration. Which copy wins varies per install, so the failure came and went.
Updated dependencies [d7a1641, 5050709, 064b78e, a0e0d2e, 2860f56, 5f14d96, 4b7d9b9]:
Last Edited: August 17, 2026