github emdash-cms/emdash @emdash-cms/admin@1.3.0

Minor Changes

  • #3969 01e1f12 Thanks @khoinguyenpham04! - Adds menu renaming and CSS classes to the admin's menu editor. The pencil button next to a menu's title renames the locale version you are editing. A CSS classes field sets an item's classes when you add a custom link or edit any item, and the item list shows each item's classes next to its URL.

  • #4136 83fe26d Thanks @khoinguyenpham04! - Adds readable revision history to the content editor. Selecting a version in the Revisions panel shows it in place, read-only, with added text highlighted and removed text struck through in the color of the person who saved it. The selected version lists its changes in plain words, such as "Changed the title", and selecting one scrolls to it. Restore moves to a bar at the bottom of the editor, and a version that matches an earlier one is marked "Restored from" with that version's date. Save and Publish pause while a version is open. The panel no longer shows raw JSON.

    The revisions list API (GET /_emdash/api/content/{collection}/{id}/revisions) and the MCP revision_list tool include each revision's author as { id, name }, or null when no author was recorded or the account no longer exists, so editors without access to user management can see who saved each version.

    ContentEditor's onRevisionRestored callback can now return a promise. The restore stays pending until it settles, and the restore dialog shows the error if it rejects. When a host passes this callback, the restored version stays on screen until item carries the restored draft, and the writer can't go back to editing before then. The editor still refreshes the entry's content and revisions queries, so a host that reads item from the entry's content query needs no change. Other hosts must reload item from the callback.

  • #3623 49319eb Thanks @swissky! - Adds a Disallow AI training option to Settings > SEO. When it is on, /robots.txt disallows the AI training crawlers and opt-out tokens Amazonbot, Applebot-Extended, Bytespider, CCBot, ClaudeBot, Google-Extended, GPTBot, and meta-externalagent, and adds a Content-Signal: search=yes, ai-train=no line. Search engine access stays as your other rules define it. The rules are added to both the default and a custom robots.txt. The option is also available as seo.disallowAiTraining in the settings API and the MCP settings_update tool. It is off by default, so existing robots.txt output is unchanged.

Patch Changes

  • #4118 6524921 Thanks @khoinguyenpham04! - Fixes admin borders showing gray instead of their intended color, such as on notices and image drop targets.

  • #4086 f9dda4d Thanks @danielmlr! - Fixes keyboard focus rings that were cut off at the edges of the field dialog, and form fields in the field and byline field dialogs that slid out of line beside a hint or error or overlapped on a phone. The Label, Slug and repeater sub-field controls now stay level, and the two-column rows of both dialogs stack on narrow screens.

  • #4148 bda9024 Thanks @khoinguyenpham04! - Fixes replacing an image in the rich text editor when it has a custom display size in the image's own proportions: the new image keeps the display width and takes its height from its own proportions, instead of being cropped to the old image's shape. A custom size in other proportions, such as an imported WordPress thumbnail, still applies to the new image.

  • #4148 bda9024 Thanks @khoinguyenpham04! - Fixes images in the rich text editor getting selected when a swipe that scrolls the page on a touch screen starts on one. Tapping an image still selects it.

  • #4012 e8bd98e Thanks @khoinguyenpham04! - Fixes blocks fields overflowing the content editor on phone-width screens. A long block summary made every block card wider than the screen, which pushed the Add block, Duplicate and Delete buttons out of reach and clipped the block's inputs. Cards now fit the screen. A long summary ends with an ellipsis, and a long one-word block type name wraps. A cut-off summary also shows its first words when its text and the admin language read in different directions, such as English content in the Arabic admin.

  • #3967 5c8ab6b Thanks @khoinguyenpham04! - Fixes the Bylines page form so it's clear what a new byline needs. The slug now fills in from the display name, Create stays available, and submitting shows an error under each missing or invalid field instead of leaving the button disabled with no explanation. Optional fields, including custom byline fields that aren't required, are marked "(optional)".

  • #4114 443ca3b Thanks @khoinguyenpham04! - Fixes the publishing calendar's "Update" tag on scheduled changes to published entries showing as a verb in some languages, such as German ("Aktualisieren") and Spanish ("Actualizar"). The tag shared its message with the taxonomy editor's Update button; it now has its own, so translators can word it as a state. Until a language's catalog translates the new message, the tag shows in English.

  • #4116 ce9e405 Thanks @khoinguyenpham04! - Fixes the language and copy buttons on code blocks in the content editor when the content is right-to-left, such as a post written in Arabic. The divider now sits between the two buttons instead of on the toolbar's outer edge, and hover and focus highlights round the toolbar's outer corners instead of its inner ones.

  • #3970 983c08c Thanks @marcin-misiewicz-pl! - Completes the Polish (pl) admin translation. Polish admins now see localized text across the whole admin, including the publishing calendar, the editor, the Change domain dialog, bylines, relations, site transfer, backups, the plugin registry, and passkey setup. Previously, 2,255 of 3,384 strings fell back to English. Existing Polish strings now use consistent terminology: „witryna” for site, „wersja” for revision, and „klucz dostępu” for passkey, matching the wording Polish users see in Apple, Google, and Windows system prompts. Four strings that displayed a stray msgstr prefix are also fixed.

  • #4006 d4e0af9 Thanks @khoinguyenpham04! - Fixes the content editor sliding up under the admin header after you open an entry by clicking a field on the site in edit mode. The editor's top bar was cut off, a blank strip appeared at the bottom, and scrolling could not bring the bar back.

  • #4035 718c1f2 Thanks @bimsonz! - Fixes opening an entry in the admin saving a draft when nothing was edited. It happened when the content ended in something other than a paragraph and was stored in a shape the editor writes differently, such as with empty markDefs and marks arrays (what markdownToPortableText and the MCP content tools write), a block without a style, or a code block with extra fields. Such entries showed "Pending changes" that nobody made, and opening them could drop fields the editor doesn't map.

  • #4152 19fbdd6 Thanks @khoinguyenpham04! - Fixes clicking a heading in the content editor's Outline panel, which often left the heading out of view. The heading now scrolls to the top of the editor, and on small screens the settings sheet closes so the heading is visible. The outline also highlights the section in view as you scroll, and nests headings by the document's structure.

  • #4015 302e011 Thanks @khoinguyenpham04! - Fixes the Arabic item count shown beside repeater fields and unregistered database tables. Counts such as 0, 1, 2 and 100 crashed the content editor or the Content Types page, and other counts showed raw message text. Also fixes the Turkish field count in the content type editor, which left out the word "alan".

  • #4031 3511069 Thanks @emdashbot! - Fixes clearing an existing taxonomy term description in the admin so the saved value is removed instead of preserved.

    Editing a tag, category, or custom taxonomy term and deleting the optional Description text now sends description: "" in the update request, so the server clears the stored value. Previously the empty field was converted to undefined and dropped from the request body, leaving the previous description in place.

  • #4134 82627fd Thanks @tristanremy! - Completes missing French translations in the admin interface, including content editing, media management, settings, authentication, plugins, and site transfers, so these messages no longer fall back to English.

  • #4084 9d89ded Thanks @danielmlr! - Completes the German admin translations so German-speaking editors see localized text in the video block and video picker, the editor's block menu, formatting toolbar and slash menu, the change-domain dialog, slug and name errors for content types, fields, sub-fields, taxonomies and relations, and the fallback messages shown when an admin request fails. Plugin update checks now say "Update" consistently.

  • #3973 75ef2ab Thanks @CacheMeOwside! - Adds missing Hindi translations for calendar scheduling notices, byline credits, media cropping and uploads, content type and field editing, block editing, table controls, passkey registration, and export/import transfer flows in the admin UI.

  • #3934 58ac71c Thanks @tomislavcf! - Adds Croatian (hr) admin translation. Croatian admins now see localized text across all admin UI areas including the editor, media library, publishing calendar, settings, authentication, plugin registry, and capability consent dialogs. Translation covers ~99% of strings (3,291 of ~3,322) with correct ICU plural forms (one, few, other).

  • #3954 15bbfd7 Thanks @Zahid09987! - Updates Indonesian (id) translations in the admin UI.

  • #3961 e0363c3 Thanks @Zahid09987! - Updates Indonesian (id) translations in the admin UI.

  • #3984 7a3667b Thanks @Zahid09987! - Updates Indonesian (id) translations in the admin UI.

  • #3926 0861e24 Thanks @danielmlr! - Fixes the error message shown when publishing, unpublishing, scheduling, unscheduling, or discarding changes fails without a server message, so it follows the admin language instead of staying in English. Most other admin requests that fail without a server message also no longer append an English HTTP status text such as "Internal Server Error" to their error message.

  • #4081 3195f42 Thanks @emdashbot! - Fixes Media Library drag-and-drop uploads while inside a folder. Files dropped or uploaded from the folder view — in both the main Media Library and the Rich Text / image picker — now land in that folder instead of being rejected.

  • #3791 dd983cd Thanks @DiogoDuart3! - Fixes two problems with number fields in the content editor. Clearing a number field now saves it as empty instead of 0, which previously failed a field's minimum (such as min: 1) or silently stored zero. Decimal values such as 4.50 no longer block the Save button with the browser's "nearest valid values" message, while integer fields keep stepping in whole numbers.

  • #4076 be9378c Thanks @emdashbot! - Fixes optional URL fields so clearing the input saves the value as null instead of an empty string, which previously caused the save to be rejected as an invalid URL.

  • #988 0ce875f Thanks @masonjames! - Fixes MCP tool names for plugins with scoped IDs such as @acme/calendar: their tools are listed as acme__calendar__<tool>, which MCP clients accept. Update saved calls that use the old scoped names. Plugins with plain IDs keep their names, and the admin plugin list displays the generated names before consent.

    A plugin tool whose JSON Schema cannot be read no longer stops other tools from loading. Unreadable input schemas accept object inputs for route validation; unreadable output schemas are omitted. Duplicate generated names keep the first tool and log a warning instead of disabling the MCP endpoint.

  • #4089 624390b Thanks @danielmlr! - Fixes the Plugins page still offering an update for a plugin that was just updated. The "available" badge and the Update button now disappear once the update finishes, without reloading the page.

  • #3690 bf92be8 Thanks @khoinguyenpham04! - Fixes extra quotation marks appearing around blockquotes in the content editor. The editor displays only the quotation marks included in the text, preserving author-entered punctuation and leaving frontend styling unchanged.

  • #4048 5b227af Thanks @ascorbic! - Fixes the document editor toolbar fade sometimes remaining hidden after scrolling or visible after returning to the top.

  • #4112 fae844f Thanks @emdashbot! - Fixes the WordPress import wizard so that a failed analyze request after pasting a migration key now shows the error message and the Back/Retry controls instead of a blank page.

  • #4085 dd216db Thanks @danielmlr! - Fixes the Register button under "Unregistered Content Tables Found" on the Content Types page doing nothing visible when registering fails. The admin now shows an error notification with the server's reason.

  • #3292 649cfae Thanks @itaides! - Formats every date and time in the admin in the admin's own language, and keeps them whole in right-to-left layouts.

    Relative times already follow the admin's language (#3512); in Arabic, Farsi or Hebrew their leading number could still render at the wrong end of the surrounding text, so they are now bidi-isolated like the dates below.

    Dates were formatted with toLocaleDateString() and no locale, which follows the browser's language rather than the one chosen in the admin, so a Hebrew admin in an English browser printed English months. Every call site now passes the admin's locale through a shared formatDate.

    Formatted dates are also bidi-isolated: a date carries digits and punctuation whose direction the bidirectional algorithm takes from the text around it, so "22 בספט׳ 2026, 22:48" rendered with its comma against the wrong number. They are wrapped in <bdi> where they are rendered on their own, and in Unicode isolates (isolate) where they are interpolated into a translated sentence.

    The shared formatDate defaults to the locale's own date format, so no call site changes how it looks. The one exception is the comment detail panel, which showed 9/22/2026 10:48:00 PM and now shows the date and time as one medium/short pair.

  • #4115 dd3121c Thanks @khoinguyenpham04! - Fixes the OG Image field in the content editor's SEO panel showing its Change and × buttons outside the image when the image was narrower than the panel. The preview now fills the field with the 1.91:1 crop that most social sites use for link previews, whatever the image's size or shape, and puts Replace and Remove buttons in its top corner. The buttons appear on hover or keyboard focus, and stay visible on touch screens and when the image can't load. Adding or removing an image with the keyboard no longer loses focus.

  • #4050 db8325a Thanks @khoinguyenpham04! - Updates the post editor to create and edit bylines with the same form as the Bylines page. Choosing Create in a post's byline search opens the full form with the name filled in, so editors can add a website, bio, avatar, linked user, and custom fields before the byline is added to the post. Edit name and slug is now Edit byline and edits every field. The Bylines panel also appears on new posts before their first save.

    Bylines created from the post editor are no longer marked as guests by default. Previously, every byline created there was a guest; it now starts as a regular byline, as on the Bylines page. To credit a guest writer, turn on Guest byline in the form. Sites whose templates read byline.isGuest show new bylines from the post editor as regular bylines unless that switch is on. Existing bylines don't change.

    Custom admins that render ContentEditor now receive every form field, including isGuest, in onQuickCreateByline and onQuickEditByline, not just slug and displayName. Existing callbacks keep working; a callback that marked new bylines as guests before spreading the input now gets the form's isGuest value instead.

  • #4026 7659466 Thanks @MarioCerulo! - Adds a first Italian (it) admin catalog for the setup wizard and sign-in screens. Italian is not selectable in the language picker yet.

  • #3977 d4efb97 Thanks @kegren! - Translates the Swedish admin strings added since 1.1, including the redesigned content editor, video blocks, the publishing calendar, scheduled changes and the domain move flow.

  • #4141 20ed58b Thanks @emdashbot! - Fixes rich-text pastes from Google Docs being rejected entirely when a table contains centred or right-aligned cell paragraphs or a merged cell with a <colgroup>.

    The table-paste safety checks now degrade gracefully instead of blocking the whole paste, so headings, links, and other formatted content outside the table are preserved and the table itself is inserted with alignment or column-width information stripped.

  • #3936 0e8811d Thanks @khoinguyenpham04! - Updates /video, and Video in the add-block menu, to open the video picker first, as /image does. The video block is added once you choose a video, and closing the picker adds nothing. A video block saved without a video, such as one left empty by an earlier version, shows as unplayable, with Replace video to choose one and Delete video to remove it. Blocks chosen from a picker opened by the add-block menu also stay where the menu was if an upload finishes while the picker is open.

  • #4150 f414d0a Thanks @swissky! - Explains why the WordPress exporter import can't connect when Cloudflare's bot protection answers with a challenge page. The URL check and the analyze and import steps now say that bot protection blocked the request and how to let it through, instead of reporting that WordPress couldn't be detected or that the analysis failed. In this case the analyze and execute endpoints return the WP_SITE_CHALLENGE error code with status 502, and probe results include challenged: true.

  • Updated dependencies [af92bf7]:

    • @emdash-cms/registry-client@0.7.1
    • @emdash-cms/blocks@1.3.0

Don't miss a new emdash release

NewReleases is sending notifications on new releases.