Skip to content

Version 0.3.0

Release date: November 3, 2026

  • Ownership: records can have an owner and deputies, also groups. Only they change a record, IT corrects responsibility without access to the content. When an owner leaves, deputies are told, and IT gets a task if nobody can take over.
  • Conditional forms: fields, tabs and wizard steps appear and become required depending on other fields, in the browser and on the server, also in action, workflow and task forms and in the API.
  • Dependent selects: the options of a select follow another field, from a list, a closure or related records.
  • Domain events: your code reacts to changed records, workflow transitions and completed tasks, however the change was made.
  • Database errors no longer reach the client, see Security.

No breaking changes in the API of Anvil. Run the migrations before anything else, see Upgrading to 0.3.0.

  • Errors of the database no longer reach the client: when saving failed in the database (for example Column 'vat_rate' cannot be null), the message with column, table or constraint names was sent to the browser or API client as a validation error. It now goes to the log, the client gets a neutral message.
  • Conditional forms: visibleWhen() on fields and layouts, requiredWhen() and keepWhenHidden() on fields, with conditions built by When. The server evaluates them in panels, action, workflow and task forms and in the API, the browser shows and hides fields, tabs and wizard steps at once. Fields hidden by a condition are not validated and saved as empty. See Conditional forms.
  • Ownership: records can have an owner and deputies (users or groups). $ownership on a resource restricts changes to them, <slug>.ownership and <slug>.override are for IT, Actor::owner() for workflows. When an owner leaves, deputies are told; if nobody can take over, IT gets a task. ownershipFilter() and OwnerlessRecordsWidget show missing responsibility. anvil:ownership:assign gives existing records an owner, the API operation ownership changes owner and deputies. See Ownership.
  • A link can set the filters of a list: /admin/deals?filter_stage=open.
  • Domain events: record.created, record.updated, record.deleted, workflow.transitioned, task.completed and your own, with listeners after the commit or inside the transaction. See Domain events.
  • Select options that depend on another field: Select::optionsFrom() with a list per value or a closure, BelongsTo::dependsOn() for records, also searchable. The server checks that a value fits. See Conditional forms.