Minor Changes
-
#367
8f44ec2Thanks @ttmx! - Addscontent:afterPublishandcontent:afterUnpublishplugin hooks, fired after content is published or unpublished. Both are fire-and-forget notifications requiringread:contentcapability, supporting trusted and sandboxed plugins. -
#431
7ee7d95Thanks @jdevalk! - Per-collection sitemaps with sitemap index and lastmod/sitemap.xmlnow serves a<sitemapindex>with one child sitemap per SEO-enabled collection. Each collection's sitemap is at/sitemap-{collection}.xmlwith<lastmod>on both index entries and individual URLs. Uses the collection'surl_patternfor correct URL building. -
#414
4d4ac53Thanks @jdevalk! - Addsbreadcrumbs?: BreadcrumbItem[]toPublicPageContextso themes can publish a breadcrumb trail as part of the page context, and SEO plugins (or any otherpage:metadataconsumer) can read it without having to invent their own per-theme override mechanism.BreadcrumbItemis also exported from theemdashpackage root. The field is optional and non-breaking — existing themes and plugins work unchanged, and consumers can adopt it incrementally. Empty array (breadcrumbs: []) is an explicit opt-out signal (e.g. for homepages);undefinedmeans "no opinion, fall back to consumer's own derivation". -
#111
87b0439Thanks @mvanhorn! - Adds repeater field type for structured repeating data -
#382
befaeecThanks @UpperM! - AddssiteUrlconfig option to fix reverse-proxy origin mismatch. ReplacespasskeyPublicOriginwith a single setting that covers all origin-dependent features: passkeys, CSRF, OAuth, auth redirects, MCP discovery, snapshots, sitemap, robots.txt, and JSON-LD.Supports
EMDASH_SITE_URL/SITE_URLenvironment variables for container deployments where the domain is only known at runtime.Disables Astro's
security.checkOrigin(EmDash's own CSRF layer handles origin validation with dual-origin support and runtime siteUrl resolution). WhensiteUrlis set in config, also setssecurity.allowedDomainssoAstro.urlreflects the public origin in templates.Breaking:
passkeyPublicOriginis removed. Rename tositeUrlin yourastro.config.mjs.
Patch Changes
-
#182
156ba73Thanks @masonjames! - Fixes media routes so storage keys with slashes resolve correctly. -
#422
80a895bThanks @baezor! - Fixes SEO hydration exceeding D1 SQL variable limit on large collections by chunking thecontent_id IN (...)clause inSeoRepository.getMany. -
#94
da957ceThanks @eyupcanakman! - Reject dangerous URL schemes in menu custom links -
#223
fcd8b7bThanks @baezor! - Fixes byline hydration exceeding D1 SQL variable limit on large collections by chunking IN clauses. -
#479
8ac15a4Thanks @ascorbic! - Enforces permission checks on content status transitions, media provider endpoints, and translation group creation. -
#250
ba2b020Thanks @JULJERYT! - Optimize dashboard stats (3x fewer db queries) -
#340
0b108cfThanks @mvanhorn! - Passes emailPipeline to plugin route handler context so plugins with email:send capability can send email from route handlers. -
#148
1989e8bThanks @masonjames! - Adds public plugin settings helpers. -
#352
e190324Thanks @barckcode! - Allows external HTTPS images in the admin UI by addinghttps:to theimg-srcCSP directive. Fixes external content images (e.g. from migration or external hosting) being blocked in the content editor. -
#72
724191cThanks @travisbreaks! - Fix CLI login against remote Cloudflare-deployed instances by unwrapping API response envelope and adding admin scope -
#480
ed28089Thanks @ascorbic! - Fixes admin demotion guard, OAuth consent flow, device flow token exchange, preview token scoping, and revision cleanup on permanent delete. -
#247
a293708Thanks @NaeemHaque! - Fixes email settings page showing empty by registering the missing API route. Adds error state to the admin UI so fetch failures are visible instead of silently swallowed. -
#324
c75cc5bThanks @barckcode! - Fixes admin editor crash when image blocks lack theassetwrapper. Image blocks withurlat the top level (e.g. from CMS migrations) now render correctly instead of throwingTypeError: Cannot read properties of undefined (reading 'url'). -
#353
6ebb797Thanks @ilicfilip! - fix(core): pass field.options through to admin manifest for plugin field widgets -
#209
d421ee2Thanks @JonahFoster! - Fixes base OG, Twitter, and article JSON-LD titles so they can use a page-specific title without including the site name suffix from the document title. -
#394
391caf4Thanks @datienzalopez! - Fixesplugin:activateandplugin:deactivatehooks not being called when enabling or disabling a plugin via the admin UI orsetPluginStatus. Previously,setPluginStatusrebuilt the hook pipeline but never invoked the lifecycle hooks. Nowplugin:activatefires after the pipeline is rebuilt with the plugin included, andplugin:deactivatefires on the current pipeline before the plugin is removed. -
#357
6474daeThanks @Vallhalen! - Fix: default adminPages and dashboardWidgets to empty arrays in manifest to prevent admin UI crash when plugins omit these properties. -
#453
30c9a96Thanks @all3f0r1! - Fixesctx.content.create()andctx.content.update()so plugins can write
to the core SEO panel. When the inputdatacontains a reservedseokey,
it is now extracted and routed to_emdash_seovia the SEO repository,
matching the REST API shape.ctx.content.get()andctx.content.list()
also hydrate theseofield on returned items for SEO-enabled collections. -
#326
122c236Thanks @barckcode! - Fixes WXR import not preserving original post dates or publish status. Useswp:post_date_gmt(UTC) with fallback chain topubDate(RFC 2822) thenwp:post_date(site-local). Handles the WordPress0000-00-00 00:00:00sentinel for unpublished drafts. Setspublished_atfor published posts. Applies to both WXR file upload and plugin-based import paths. -
#371
5320321Thanks @pejmanjohn! - Fix MCP OAuth discovery for unauthenticated POST requests. -
#338
b712ae3Thanks @mvanhorn! - Fixes standalone wildcard "" in plugin allowedHosts so plugins declaring allowedHosts: [""] can make outbound HTTP requests to any host. -
#434
9cb5a28Thanks @hayatosc! - Avoid accessing sessions on prerendered public routes. -
#119
e1014efThanks @blmyr! - Fix pluginpage:metadataandpage:fragmentshooks not firing for anonymous public page visitors. The middleware's early-return fast-path for unauthenticated requests now initializes the runtime (skipping only the manifest query), so plugin contributions render via<EmDashHead>,<EmDashBodyStart>, and<EmDashBodyEnd>for all visitors. Also addscollectPageMetadataandcollectPageFragmentsto theEmDashHandlersinterface. -
#424
476cb3aThanks @csfalcao! - Fixes public access to the search API (#104). The auth middleware blocked/_emdash/api/searchbefore the handler ran, so #107's handler-level change never took effect for anonymous callers. Adds the endpoint toPUBLIC_API_EXACTso the shippedLiveSearchcomponent works on public sites without credentials. Admin endpoints (/search/enable,/search/rebuild,/search/stats,/search/suggest) remain authenticated. -
#333
dd708b1Thanks @mvanhorn! - Adds composite index on (deleted_at, published_at DESC, id DESC) to eliminate full table scans for frontend listing queries that order by published_at. -
#448
c92e7e6Thanks @grexe! - fixes logo and favicon site settings not being applied to templates -
#319
2ba1f1fThanks @ideepakchauhan7! - Fixes i18n config returning null in Vite dev SSR by reading from virtual module instead of dynamic import. -
#251
a13c4ecThanks @yohaann196! - fix: expose client_id in device flow discovery response -
#93
a5e0603Thanks @eyupcanakman! - Fix taxonomy links missing from admin sidebar -
Updated dependencies [
0966223,53dec88,3b6b75b,a293708,1a93d51,c9bf640,87b0439,5eeab91,e3f7db8,a5e0603]:- @emdash-cms/admin@0.2.0
- @emdash-cms/auth@0.2.0
- @emdash-cms/gutenberg-to-portable-text@0.2.0