Minor Changes
-
#1890
82827d3Thanks @swissky! - Adds a Backups page to admin settings: download a complete content backup (all content including drafts and trash, schema, taxonomies, menus, widgets, media metadata, and site settings — never user accounts or secrets) with one click, and optionally enable daily automatic backups to the site's storage bucket with configurable retention. A newbackups:managepermission gates the feature to admins. -
#2122
6bbf93aThanks @bimsonz! - Expose the host Astro project'strailingSlashconfig to plugins viactx.site.trailingSlash, so plugins that build absolute URLs (sitemaps, canonical, hreflang) can match the site's routing policy. Available to in-process and sandboxed plugins alike. -
#1954
23a740aThanks @swissky! - Adds amedia_uploadMCP tool that uploads a file from base64-encoded data or a public URL and registers it in the media library, so agent workflows can create media without dropping to the CLI or raw API. Uploads are deduplicated by content hash and respect the global MIME allowlist and maximum upload size. -
#2007
6fb52b0Thanks @khoinguyenpham04! - Addsemdash media repair-usageand themedia_usage_repairMCP tool for repairing content media usage indexes by collection or across all collections; automation should inspect the structured repair status because non-complete results can still be successful invocations. -
#2092
a27a5ccThanks @khoinguyenpham04! - Adds coverage-aware media usage counts and read-only Used in details to the REST API and core client. -
#1868
4c57ee2Thanks @afonsojramos! - Invited users can now accept their invite by signing in with Google or GitHub, instead of only creating a passkey. -
#2002
e52dea9Thanks @jcheese1! - Adds explicitly declared, administrator-enabled plugin MCP tools with per-route permissions, plugin-scoped token access, install and update consent, structured output schemas, and invocation auditing. -
#1985
3f8b778Thanks @swissky! - Adds acacheControloption for public plugin routes: successful GET responses carry the configuredCache-Controlheader, enabling CDN and browser caching for public plugin endpoints. Works for native, standard, and marketplace plugin formats. Private routes and errors keep theprivate, no-storedefault. -
#1893
d4c565eThanks @swissky! - Adds the auto-generated admin settings form for plugins that declareadmin.settingsSchema. A gear icon on the plugin's card in Plugins opens a form generated from the schema (string, number, boolean, select, secret, url, and email fields), persisted to the plugin's KV store undersettings:keys. Secret fields are write-only: the admin shows whether a value is set but never returns it. Editing plugin settings requires theplugins:managepermission. -
#1957
65be947Thanks @swissky! - AddsdefaultTitleanddefaultDescriptionoptions togetSeoMetaso pages with computed titles or descriptions can pass their own fallbacks while values set in the admin SEO panel still take precedence. Previously such pages had to drop down togetContentSeoand merge panel values by hand. -
#1961
e649af8Thanks @swissky! - AddswithEmDashRuntime()toemdash/middlewareso request-free handlers (Cloudflare Queue consumers, customscheduled()handlers) can access the EmDash runtime and invoke plugin routes directly — previously the runtime was only reachable throughlocals.emdashon an HTTP request.
Patch Changes
-
#1505
fbb04abThanks @swissky! - The admin shell now falls back to the Site Icon configured in Settings → General for its favicon, so the EmDash backend is branded like the public site. An explicit build-timeadmin.faviconstill takes precedence, and the default EmDash mark is used when neither is set. -
#1901
07c2b0fThanks @scottbuscemi! - Fixes same-page anchor links (e.g.#section) in Portable Text content opening in a new tab. On-page jumps now always stay in the same tab, even when the link's "open in new window" option is set. -
#2098
460efe6Thanks @rhaegalll! - Fixes API responses to include thesuccessfield documented in the REST API reference: successful responses are now{ success: true, data }and error responses{ success: false, error }. The existingdataanderrorfields are unchanged, so existing clients keep working. -
#1992
7b9e558Thanks @swissky! - Fixes a circular redirect loop when a slug rename is reverted. Renaming a slug back to a previous value now removes the stale redirect that shadowed the restored URL, so the page stays reachable. -
#2137
aa7ef09Thanks @khoinguyenpham04! - Fixes the admin boot screen so it respects the saved light or dark theme before the dashboard loads. -
#1955
c180240Thanks @logelog! - Fixesemdash plugin bundleandemdash plugin validateon Windows by importing generated plugin artifacts through portable file URLs. -
#1979
039c5dcThanks @masonjames! - Fixes browser uploads for custom S3-compatible storage adapters by allowing their runtime upload origin in the admin Content Security Policy. -
#2037
b66d8a0Thanks @swissky! - Fixes oversized image renditions on Cloudflare: transforms without an explicit quality were encoded near-losslessly by the Images binding (a 2048px WebP came out ~900 KB instead of ~100 KB). Lossy transforms (WebP/AVIF/JPEG) now default to quality 85, matching Cloudflare's image-resizing default. PNG output keeps no explicit quality — an explicit PNG quality switches the binding to lossy PNG8, which is not a safe default for a lossless format. An explicit?q=in the request URL still wins for every format.Note: image responses are cached with
Cache-Control: immutable, max-age=31536000keyed on the request URL, so previously-served oversized renditions stay cached at the edge/browser until they expire. To benefit immediately after upgrading, purge the Cloudflare cache for your/_image*URLs (or the whole site cache). -
#2129
fc6cdfbThanks @dchaudhari7177! - The content API now answers 500 NOT_CONFIGURED instead of 401 UNAUTHORIZED when the EmDash runtime failed to initialize. Previously the permission check ran first, so a server fault (broken DB binding, init failure) was reported as an authentication error even for requests carrying a valid token — and retry logic correctly treating 4xx as non-retryable gave up instead of retrying. The 13 affected content routes now check initialization before permissions, matching the schema routes. -
#2153
8d6b20bThanks @swissky! - Stops draft-only saves and autosaves on published entries from advancingupdatedAt. On revision-supporting collections, staging or discarding a pending draft leaves live content untouched, so sitemap<lastmod>and JSON-LDdateModifiedno longer register a modification until Publish actually changes the live entry. -
#1079
1b1ff42Thanks @eyupcanakman! - Fixes the admin content list returning a genericCONTENT_LIST_ERRORwhen a collection's backing table is missing thedeleted_atcolumn. It now returnsCOLLECTION_SCHEMA_MISMATCHnaming the affected collection, so the schema problem is visible instead of an opaque failure. -
#1898
e2c7549Thanks @swissky! - Fixes plugin storagequery()andcount()failing on PostgreSQL with "operator does not exist: boolean = integer" whenever awherefilter was supplied. -
#1945
6c96ac8Thanks @swissky! - Fixes unsaved inline (visual) editor changes being silently lost when navigating away, e.g. via the browser back button. Edits are now flushed with a keepalive request when the page unloads. -
#1902
7ff08dbThanks @marcusbellamyshaw-cell! - Fixes the login, signup, and invite-accept pages showing the stock EmDash mark and name even when a customadmin.logo/admin.siteNameis configured for white-labeling. These pre-authentication pages now render the configured logo and site name (completing the scope approved in #639/PR #705, which wired branding into the sidebar and setup wizard but missed the pages users see before signing in), falling back to the default EmDash mark when no custom branding is configured. -
#2080
de44730Thanks @logelog! - Fixes trusted plugin API routes receiving empty site metadata and relative URLs by using the same site context as plugin hooks. -
#2018
32be60bThanks @ttmx! - Adds schedulerless cron access, scheduled publication timestamps, and external authentication support to plugin routes. -
#2152
b22a3d5Thanks @vedanshujain! - fix(core): compare plugin-storage numeric filters and ordering numerically on Postgres._plugin_storage.datais atextcolumn, so after the::jsonbcast (#1898) the extracted value is still text and numeric guards compared lexically —{ stock: { gte: 10 } }over 9/10/100 matched 9 (over-count/oversell) and numericorderBysorted[10, 100, 9]. Numeric comparisons now use a type-guarded::numericcast and ordering uses the jsonb-native value, so results are numeric and parity-correct with SQLite. Non-numeric stored values yield no match instead of erroring. -
#1980
32f8261Thanks @swissky! - Fixes plugin storagestartsWithqueries treating%,_, and\in the prefix as LIKE wildcards instead of literal characters. -
#2036
4b7fd08Thanks @swissky! - Fixes publishing an entry whose staged slug is already used by another entry in the same locale failing with an opaque database error. Publish now returns a validation error naming the conflicting slug and entry, which the admin can show inline, and leaves the live entry untouched. -
#2082
cf6e4faThanks @logelog! - Fixes production build warnings when database adapters do not provide the optional cold-start query coalescing dialect. -
#2084
d303738Thanks @logelog! - Avoid production render warnings when Astro's built-in CSP is disabled while preserving JSON-LD script hashes when it is enabled. -
#1958
6a79b03Thanks @swissky! - Warns at build time when@astrojs/reactis not registered in the Astro config. Without it the admin UI builds successfully but never hydrates, leaving the page stuck on "Loading EmDash..." with no error. -
#2128
34b3017Thanks @jcheese1! - Fixes fresh database setup failures for sites with large seed schemas. -
#2081
6890eddThanks @logelog! - Fixes sandboxed plugins receiving empty site metadata and relative URLs fromctx.url(). -
#2050
cfdb8f0Thanks @edrpls! - Fixes admin-account recovery whenemdash:setup_completeis set but the users table is empty (a wiped or sanitised database copied between environments)./api/setup/statusalready resumes the wizard at the admin step for this state, but the admin-step routes rejected it withSETUP_COMPLETE, leaving no UI path to an admin account. Both routes now reject on the flag only when a user also exists; the fully-set-up and admin-exists rejections are unchanged. -
#1845
ca660c6Thanks @marcusbellamyshaw-cell! - Fixes OAuth login (Google/GitHub) failing with "Failed to start OAuth flow" on Astro 6+ Cloudflare deployments. The OAuth start and callback routes read provider credentials viaAstro.locals.runtime.env, which Astro 6 removed — accessing it now throws instead of returningundefined, so the existing optional-chaining fallback never ran. Both routes now read Cloudflare bindings through a build-time virtual module instead, falling back toimport.meta.envon non-Cloudflare adapters exactly as before. -
#1838
c4a2ffdThanks @marcusbellamyshaw-cell! - Fixes admin forms (e.g. Create Taxonomy) showing a generic "Invalid request data" error instead of the actual validation problem. Field-level validation messages from the server are now shown to the user. -
#1962
c24b7d3Thanks @MA2153! - Fixes taxonomy-filtered collection listings reading the entire collection on SQLite/D1 when the term is selective. Such listings now seek the matching entries directly, cutting D1 rows-read from tens of thousands to the page size. -
#2085
84173ddThanks @logelog! - Watch resolved sandbox plugin entry files so rebuilding a plugin invalidates its embedded virtual module during development. -
#2030
c350e86Thanks @swissky! - Fixes MCP OAuth discovery advertisinghttp://URLs on Cloudflare and other proxied deployments. The/.well-known/oauth-protected-resourceand/.well-known/oauth-authorization-serverroutes now honorsiteUrlon anonymous requests, so MCP clients can attach without settingEMDASH_SITE_URLas an env var. -
Updated dependencies [
82827d3,2cb8dd3,f961f6e,aa7ef09,1329cc0,a6b7424,44e2685,3176f4f,1c15097,aa7ef09,aa7ef09,a272e58,64b2e73,7ff08db,aa7ef09,aa7ef09,c80cab6,4c57ee2,e52dea9,3f8b778,d4c565e,07c9f21,2da4a40,b871de2,9c858b1,1d7550b,2da14cc,aa7ef09,aa7ef09,22b96e5,8903aef,b5a60c1]:- @emdash-cms/admin@0.30.0
- @emdash-cms/auth@0.30.0
- @emdash-cms/plugin-types@0.3.0
- @emdash-cms/registry-client@0.3.4
- @emdash-cms/gutenberg-to-portable-text@0.30.0