What's new
Every release, what changed and why it matters.
- Rebuild the dashboard on React Aria Components, with keyboard navigation, focus management and screen reader support throughout, a new theme with dark mode, a responsive layout, entry history and a references panel that shows which entries link to the current one.
- Add
alinea/components, the public component library the dashboard is built from, to build custom fields and views. Dashboard icons are available fromalinea/dashboard/icons. - Add
Field.localiserto keep every locale of a value in a single field, with fallbacks. - Add the
overviewoption to container types and roots to configure how the dashboard lists their children: columns (Config.column) with per-type selects, formatting and custom cells, built-in type, status, updated and author columns, sorting by column header (kept in the URL), the defaultsort,layout, cardthumbnailand toolbaractions. The media library lists previews, dimensions, sizes and file types.EntryTableinalinea/cmsrenders the same columns in custom views.overview.sortreplacesorderChildrenBy,summaryRowandsummaryThumbare deprecated and theoverviewfield option only applies when the parent defines no columns. - Record URL aliases in the metadata field when an entry's URL changes, and
resolve them in queries (
aliasfilter,Query.aliases). The metadata field also storescreatedAt,createdBy,updatedAtandupdatedBy. - Add
beforeCommitandafterCommithandler hooks to rewrite changes before they are committed, or to revalidate, notify and deploy after. - Publish instantly: deployed sites sync new content as soon as it is committed,
driven by the repository sha.
syncIntervalis now a fallback, defaulting to 60 seconds. - Add an MCP server to
alinea dev(http://localhost:4500/mcp) so coding agents can read the schema and create, edit, publish, move and delete entries and upload media through the dashboard's save path. - Bundle a SQLite content database with full text fuzzy search.
- Add the
adminPath,maxUploadSizeandtracerconfig options, and a workspacemediaUrloption. - Add
Field.select.multiple,minandmaxfor lists, images and link options in rich text, rich text anchors, link anchors and suffixes, andallowDuplicatesfor links. - Add a composable backend in
alinea/backend(createBackend,auth,database,github,uploads) with S3 and Supabase uploads and user management. - Require Node.js 24 or higher and React 19.
- Require
handlerUrlin the config.dashboardFileis deprecated in favor ofadminPath. - Serve media files through
${adminPath}/file/...on the site: image and file links now return that URL instead of the stored location. - Change
Config.media()to take root options, children move tochildren. - Remove the options of
Field.metadata()and thestepoption ofField.time(). - Move the rich text editor to Tiptap 3.
extensionsis now a function that receives the default extensions,defaultToolbartakes an options object. - Change
Edit.moveto{id, target, dropPosition}. - Remove the
remotehandler option and the unused entry hooks. OAuth2 backends requirevalidateClaims. Drafts are no longer stored in the database. - Remove the components from
alinea/uiexceptRichText, and the form atoms fromalinea/dashboard. TheuseFieldhooks are deprecated. - Fix read-only roles for nested fields and upload permissions in nested media folders.
- Fix the locale of translations created in another root.
- Fix bundled content being served stale right after a cold start.
- Verify signed Alinea Cloud handshake requests and pin preview messages to the dashboard origin.
- Fix rich text parsing of marks around images and keep
data-attributes on rich text nodes.
- Add user roles and permission policies. Permissions can now be scoped by workspace, root, type, field, entry id and locale, and cover actions such as create, read, update, delete, reorder, move, publish, archive, upload and explore. The dashboard and backend now enforce these policies.
- Add configurable rich text toolbars and custom Tiptap extension support.
- Improve the Next.js integration.
withAlineanow uses the CLI-provided admin path, proxies the dashboard in development, rewrites to the generated dashboard in production and supports customdashboardFilevalues. - Allow
baseUrlto be configured per environment. - Add workspace and root information to
EntryUrlMeta. - Return CORS headers for local uploads.
- Improve OAuth and JWT handling with explicit SameSite cookies, access-token refresh without treating refresh tokens as JWTs, stricter JWKS key selection and optional extra claim validation.
- Fix rich text HTML parsing so marks are applied across nested content and root-level whitespace is ignored.
- Filter unresolved entry links from multi-link query results.
- Add
llms-full.txtto the published package.
- Don't use Y.js for preview deltas, but a more predictable diff
- Fix link order in rich text fields
- Fix search results turning up empty
- Show children indicator in tree even if all children are untranslated
- Previous release mistakenly included features that were not ready for release.
- Refactor how we build the internal index of all entries. This is now done immutably so that any problems during mutations to entries do not corrupt the index.
- Add more richtext table options (mergeCells, splitCell, toggleHeaderCell and toggleHeaderColumn)
- Fix Query.next and Query.previous which were not sorted correctly
- Set access token at the root so
cms.user()calls work in preview environments
- Prefix upload locations with media dir for self-hosted backends
- Handle logout endpoint for OAuth backends
- Handle authentication with Alinea Cloud using OAuth 2.0
- Enable ctrl and middle mouse clicks in the entry tree to open in new tab
- Use a shared EventSource in dev mode to avoid the browser maximum of 6 connections per origin
- Check workspace and root properties during entry creation
- Fix: handle missing blobs in local IndexedDB store
- Fix: data coming from Alinea Cloud was not handled correctly
- Fix: previous release was published with extraneous dependencies
- Disabled arrow up/down when on first/last row in lists (#450)
- Keep copy icon visible during drag state; disable icons while dragging (#451)
- SelectField: responsive layout improvements (#448)
- ImageView: show cursor crosshair (#449)
- Collapsible list rows (#444)
- IconButton: focus layout change (#447)
- TextField: added placeholder support (#442) and type email, tel, text, or url (#445)
- Remove web workspace; move website to alineacms/alineacms.com
- Fix: don't bundle contents in edge functions
- Fix: order results of Query.parents by level
- Fix: respect parent insert order on create
- Fix: internal links to image and file entries from the link preview
- Fix: publishing changes to file details no longer removes the associated file
- Fix: don't use transparency in averageColor property for images
- The previous release mistakenly added
nextas a direct dependency to thealineapackage. While we're currently focused on providing a clean Next.js integration, Alinea is not tied to Next.js and should not depend on it.
- Using the
alinea initcommand for a Next.js website will now auto-create the handler route inapp/(alinea)/api/cms/route.ts. The generatedcms.tsconfig file also includes more default options such as thebaseUrlandhandlerUrl.
- Restore drag-drop behavior in entry tree. The drag and drop functionality was broken in the previous release due to a change in the way entries are rendered in the sidebar.
- Better support for drafts in Alinea. Drafts can be enabled using the config
option
enableDrafts: true. Drafts and archived entries will now show their status in the sidebar as well. Workflows are adjusted to be able to create a draft entry, including draft children. These will show up as "unpublished" and can be published in one go. Further stability improvements were made to updating entry statuses.
- Fix usage of cms.user() in api routes
- Stability improvements.
- Fix use of the readOnly field property which was overwritten from context
- Minor fixes to path field
- Make sure the editor widget doesn't interfere with pointer events of underlying elements
- Added a preview property to TypeConfig to disable the preview on Type level (#407)
- UI tweaks
- Archiving an entry results in archived children entries as well.
- Adjust the inferred results of
cms.findandcms.getso they work reliable in non-strict Typescript codebases as well.
- Fix the query result type of
Query.parent,Query.nextandQuery.previouswhich were incorrectly typed as anArray.
- Add a copy and paste button to List field blocks
- Update link properties condition and location to be dynamic. The contents can be set by using a function.
- Fix navigation tree in link picker
- Set the default depth of querying children to 1
- Fix handling mutation retries based on the http status code received.
- Fix skip/take for queries which were not used
- Disable navigation in the internal link picker if a condition is used
- Fix live previews for translated entries
- Fix querying linked entries without locale
- Fix querying linked entries - the requested locale was not passed
- Alinea will now fail if linked entries cannot be resolved during querying. Before it would log the error but continue - but this is rarely desired.
Fix removing field contents in
Edit.update. Pass an undefined value to remove field contents:await cms.commit( Edit.update({ id: '...', set: {removeMe: undefined} }) )- Fix processing link data correctly even it contains legacy data
- Only access normalized config in next cms adapter. This fixes an error in production builds which would prevent you from querying media files.
- Tweak the withAlinea config function to work in all environments including Next 14.
Add the Infer.Entry and Infer.ListItem types which can be used to infer the type of an entry or list item from a query.
type Entry = Infer.Entry<typeof EntryType> const entry: Entry = await cms.get({type: MyType}) type ListItem = Infer.ListItem<typeof ListType> const list: Array<ListItem> = await cms.get({select: MyType.list})
- Add support for Next.js 15 and Turbopack.
- Removed all previously deprecated options.
- Next.js config changes are now bundled in a
withAlineaexport found in 'alinea/next'. - Querying via
cms.find/getis rewritten to take a single query object. Have a look at the docs to see how to use the new query api. - Creating custom fields can now be done through
Field.create. - Entries now have a single id. If you are upgrading and were using i18n you
can stabilize your ids by running
npx alinea build --fix.