Skip to content

Messages

Status: ✅ Implemented — Message; persistence, actions and keys are 🧪 @Experimental (3.0)

After an action the user needs to know what happened, sometimes act on it (“Undo”, “View”, “Retry”), and sometimes find it again later. A message says what it is; each renderer decides how to show it on its platform — a toast on the web, a JET notification on Redwood, a snackbar on the phone, a balloon in IntelliJ.

Return a Message from an action (alone, or in a list with the new state and commands):

@Button
public Message save() {
var order = orders.save(this);
return Message.success("Order saved")
.withAction(MessageAction.open("View", "/orders/" + order.id()))
.withAction(MessageAction.run("Share", "share", Map.of("id", order.id())))
.withPersistence(MessagePersistence.inbox)
.withKey("order-" + order.id());
}
DimensionValuesMeaning
variantsuccess, info, warning, error, contrast, primaryThe severity
persistencetoast, sticky, inboxGoes away on its own · stays until dismissed · a toast that also lands in the inbox
actionsMessageAction.run(label, actionId[, parameters]), MessageAction.open(label, route), .withStyle(primary/secondary/danger/undo)What the user can do; an action runs on the component that ran the action
keyany stringA message with the same key replaces the one on screen (and the inbox entry) instead of stacking
positiontopEnd, bottomStretch…A hint for the web renderers only; the others ignore it

An error is sticky unless it says otherwise: read in three seconds and gone, the user often never saw why the save failed. Everything else is a toast. Undo is one of the actions (style undo, labelled by the renderer’s own “Undo” when unlabelled) — Message.undoable fills both the action and the older undo* fields.

An inbox message to a signed-in user is also KEPT on the server 🧪 (Mateu’s in-memory InboxStore, or yours), so it is still in the bell after a reload and in the user’s other tabs and devices — see Notification inbox. With @App(osNotifications = true) it also becomes a notification of the operating system while the app is not in front.

MessageDto {variant, position, title, text, duration, persistence, actions: [{label, actionId, parameters, route, style}], key} plus the legacy undoLabel/undoActionId/undoParameters. The .NET and Python servers send the same.