- [Minor Changes](#minor-changes)
- [Patch Changes](#patch-changes)#7477 fd6aaaf Thanks @joshbermanssw! - Add accept to the image field, restricting which file types the field will take. It takes an extension, a category (image, video, audio, document), or an array of either. The field's own dropzone and the media picker's both refuse a file outside it, the picker narrows the library to matching files, and a selection outside it raises an alert instead of being written. jpg and jpeg are treated as the same type. Existing values are left alone.
#7423 7c21906 Thanks @Aibono1225! - Add TinaCloud media rename support to the Media Manager.
Repo-backed media can now be renamed directly from the Media Manager. Renames on unprotected branches are applied directly, while renames on protected branches use the editorial workflow and create a pull request from a new workflow branch.
Local media rename behavior is unchanged, and static or self-hosted repo media stores still do not expose the Rename action.
Renaming does not update existing content references to the old media path. Rename failures from the assets API are surfaced in the UI with their specific error messages.
#7494 37f2e6a Thanks @lastenvoy30! - Render semantic <thead>/<th> for markdown tables in TinaMarkdown
Markdown (GFM) tables previously rendered every row as <tbody><td>, with
no <thead> or <th>. That diverges from standard GFM output and breaks
accessibility (assistive tech relies on <th> to associate headers with
data cells) as well as the th component override.
The first row of a markdown table is now rendered as <thead><th>,
matching the existing behavior for editor-authored MDX tables. Remaining
rows render as <tbody><td> as before. Column alignment is preserved on
both <th> and <td>.
Breaking change: sites that styled table headers via td or
tbody tr:first-child selectors will need to update those selectors to
target th/thead instead.
Breaking change: the default inline border: 1px solid #EDECF3 on
<table> and the border/padding: 0.25rem on cells are no longer
applied, and align is no longer leaked onto the DOM as a raw attribute.
Tables now inherit your stylesheet instead of the inline styles that used
to beat it on specificity, so a table that rendered as a boxed grid will
look different until you style it yourself.
#7495 57707bf Thanks @Aibono1225! - Show the configured Git author in the editorial workflow save dialog.
When saving to a new branch, the dialog now shows whether commits will be made as the TinaCloud bot or as you, with a link to change the setting.
#7467 2264a16 Thanks @wicksipedia! - Download the mermaid diagram library only when a document actually contains a mermaid code block. The rich-text editor imported mermaid at the top of its code-block component, so the admin shipped the whole library to every editor session even when no project file used a diagram. The import now happens inside the code that parses and renders a diagram, which lets the bundler split mermaid into its own chunk. In the kitchen-sink admin build the entry chunk drops from 6,339,116 to 5,698,025 bytes (1,974,875 to 1,823,566 gzipped), and the 635,594-byte mermaid chunk (150,677 gzipped) is fetched on demand instead. A diagram preview shows a placeholder while the chunk loads, and a chunk that fails to load is reported in the same place the editor already reports diagram syntax errors.
#7477 fd6aaaf Thanks @joshbermanssw! - Make the image field's accept work on list: true fields, and filter by extension server-side everywhere. The list variant built each item input from a bare {component: 'image'}, so a gallery got no dropzone restriction and no insert guard. The local dev server now accepts an ext param on /media/list, filtering before it paginates, so the media manager's type filter no longer narrows a page after the fact. A staticMedia store reports no extension filtering and hides the control rather than showing one that would leave a near-empty grid.
#7486 d340dab Thanks @kulesy! - A session that expires mid-edit now returns the user to the login modal on every path. The content API client dispatches cms:session-expired and throws a typed SessionExpiredError when a GraphQL request comes back 401, and the REST transport (fetchWithToken, used by branch listing, billing, editorial-workflow polling, search indexing and the media store) notifies the same flow when a tokened request 401s, so saves, deletes, renames, folder creation and every panel land on the login modal instead of generic error dialogs, misleading unauthorized panels, or a success toast for a save that never ran. The auth wall suppresses new alerts between expiry and re-login so nothing paints over the login modal, session expiries are no longer recorded as save failures in analytics, a transient identity-API failure no longer reads as a logged-out session (one retry, then it surfaces as an error), and custom content APIs keep a console diagnostic for 401 loops caused by backend misconfiguration.
Also fixes the registerApi event bridge this rides on: api.events was forwarded to the global bus with an unbound dispatch, so the api-to-cms direction documented on Client.events has never delivered an event. Both directions now forward, with guards scoped to the in-flight event so nested dispatches still bridge.
#7452 aa686c6 Thanks @isaaclombardssw! - Make shift+Enter produce a line break that survives a save. Plate inserted a literal \n, which markdown re-flowed into a space, so the break vanished everywhere except blockquotes. Code blocks and table cells are unchanged. Fixes #6555 and #7408.
Updated dependencies [d340dab, d0593a3, dbd9234, f48009e, fd6aaaf, fd6aaaf, 16b9ca1]:
Last Edited: September 7, 2026