Minor Changes
-
#2267
e8048e4Thanks @DavidPivert! - Adds an explicit sidebar order for collections. Drag the rows on the Content Types screen, or setsortOrderin a seed file, and the admin sidebar follows that order instead of sorting alphabetically by slug. Collections without asortOrderkeep the alphabetical order and are listed after the ordered ones, so existing sites look the same until someone reorders.reorderis now a reserved collection slug. -
#2044
534f238Thanks @scottbuscemi! - Addsemdash/ui/commentsforCommentsandCommentFormso their CSS only loads on pages that import them. Importing fromemdash/uistill works but is deprecated and will be removed in 1.0 — preferimport { Comments, CommentForm } from "emdash/ui/comments". -
#2264
741c40cThanks @DavidPivert! - Adds ahiddenflag to collections that omits their auto-generated entry from the admin sidebar. Hidden collections keep working everywhere else — REST API, MCP, plugin hooks, and their editor at/_emdash/admin/content/<slug>— so a plugin that owns a collection end to end can point editors at its own admin UI instead of a raw CRUD list. Set it in a seed file ("hidden": true) or via the schema API. -
#2353
ea4c39bThanks @MA2153! - Adds manual ordering for taxonomy terms. Move terms up and down from the Taxonomies screen, and term listings —getTerms()and the terms REST endpoint — return them in that order. The terms attached to a single entry are still listed alphabetically.Existing terms keep the order they display in today, now stored explicitly instead of derived from their labels. Terms added afterwards go to the end of their sibling group rather than slotting in alphabetically — if you want a taxonomy alphabetical, order it that way once and it stays.
A term's position is shared by all of its translations, so ordering a taxonomy in one locale orders it everywhere. On upgrade that means each taxonomy keeps the alphabetical order of the locale its terms were first written in, and other locales are re-sorted to match; reorder once from the Taxonomies screen if you want something different. Sites that need a genuinely different order per language should use separate taxonomies.
Also fixes moving a term to a new parent only taking effect in the locale you moved it in, which left the term nested in that locale and still at the top level in the others. Moving a term now moves it in every locale, and terms already split this way are repaired on upgrade.
Patch Changes
-
#2304
85dd99dThanks @edrpls! - Fixes sites that don't use bylines paying dead byline lookup queries on every content read. When the bylines table is empty, entries with an author no longer send hydration down the byline query path — the folded result is served directly, removing the wasted round trips from anonymous page renders. -
#2405
f6385daThanks @ascorbic! - Deprecatesemdash devand hides it from CLI help. Existing invocations still work, but now warn you to use the project'sdevscript, such aspnpm dev, or runastro devdirectly. -
#2349
72660daThanks @khoinguyenpham04! - Fixes scheduled content appearing publicly before its staged slug and content are atomically published. -
#2407
969c6cbThanks @ascorbic! - Fixes scheduled maintenance reading the entire revision history on every cron invocation. -
#2409
0c3af01Thanks @ascorbic! - Fixes Hyperdrive requests leaving request-scoped pool teardown pending when background layout prefetch outlives the response. -
#2348
640da63Thanks @khoinguyenpham04! - Fixes numbered lists restarting at 1 after intervening content blocks in the editor and rendered pages. -
#2257
e7c445cThanks @mvanhorn! - Adds per-collection search tokenizers so multilingual content can use trigram or non-stemming Unicode search. -
#2370
ef78aa1Thanks @danielmlr! - Fixes outbound email links (magic link, invites, signup confirmation, account recovery, comment notifications) ignoring the configuredsiteUrl. The configured origin —siteUrlin the integration options or theEMDASH_SITE_URL/SITE_URLenvironment variables — now takes precedence over the origin stored during setup, so a site set up on a temporary domain no longer needs a manual database edit to correct its email links. -
#2408
0237678Thanks @ascorbic! - Fixes redirect changes remaining stale across Cloudflare Worker isolates by refreshing cached rules within 30 seconds. -
#2306
e07f0c8Thanks @edrpls! - Fixes media-usage tracking rows accumulating without bound. Superseded and abandoned usage generations are now garbage-collected by the periodic maintenance sweep, so the usage table no longer grows with every content save. -
#2163
425e7c0Thanks @dchaudhari7177! - Plugin API routes with an input schema now work over GET, HEAD, and DELETE. These methods carry no request body, sorequest.json()resolved toundefinedand every such request failed validation. Route input is now parsed from the URL query string for bodyless methods (repeated keys become arrays) while POST/PUT/PATCH continue to parse the JSON body. -
#2308
7099d13Thanks @edrpls! - Fixes plugin-declared storage indexes never being created. Indexes declared in a plugin manifest'sstoragesection are now materialized on marketplace/registry install and update, dropped on uninstall, and synced for configured plugins on the scheduler tick — so plugin storage queries (like the audit-log dashboard widgets) use an index instead of scanning the whole table. The index shape also changed to a composite that SQLite actually uses on D1, where table statistics are never collected. -
#2280
f586100Thanks @scottbuscemi! - Fixes anonymous public pages reseeding edge/object caches with stale Hyperdrive query results right after content publishes. WhencachedBindingand a distributed Object Cache are configured, public reads across Worker isolates prefer the uncached Hyperdrive binding for a short window after content writes (default 60s, overridable viapreferUncachedAfterWriteMsto match your Hyperdrive max_age). -
#2251
1dd7f13Thanks @dchaudhari7177! - Normalize media values inside repeater image sub-fields. A bare media id posted via the REST API into a repeater sub-field is now normalized into a fullMediaValue(the same treatment top-level image/file fields already get), instead of being stored verbatim and rendered as "Image not found" in the admin. -
#2214
447647dThanks @marcusbellamyshaw-cell! - Fixes public routes onsandboxed: [](config-declared) plugins requiring authentication regardless of the plugin's ownpublic: truedeclaration. Declareroutes(and optionallyhooks) on the plugin's descriptor to have them honored, the same wayadminPages/capabilitiesalready are. -
#2315
aec4fa1Thanks @edrpls! - Fixes renaming a translation taking its canonical page offline. When two locale variants share a slug, renaming either one created a 301 away from a URL the other still serves, making the live page unreachable. Slug-change redirects are now skipped when another entry still holds the old slug. -
#2328
8040e27Thanks @MA2153! - Fixes translation lookups reading every non-deleted row of a content table. Content tables now carry(translation_group, locale)and(deleted_at, translation_group, locale)indexes, replacing the single-columntranslation_groupone, so fetching an entry's translations — one entry's, a whole page's, or a menu link's target — seeks straight to the group instead of scanning. The improvement is largest on big collections and on D1, where the query planner has no statistics to fall back on. -
Updated dependencies [
6215e93,e8048e4,28b17fd,d9b76be,640da63,741c40c,e61cb63,6e47033,1cf2811,2400a3e,ea4c39b]:- @emdash-cms/admin@0.33.0
- @emdash-cms/auth@0.33.0
- @emdash-cms/gutenberg-to-portable-text@0.33.0