Plugin screenshot thumbnail 1/10
Plugin screenshot thumbnail 2/10
Plugin screenshot thumbnail 3/10
Plugin screenshot thumbnail 4/10
Plugin screenshot thumbnail 5/10
Plugin screenshot thumbnail 6/10
Plugin screenshot thumbnail 7/10
Plugin screenshot thumbnail 8/10
Plugin screenshot thumbnail 9/10
Plugin screenshot thumbnail 10/10

Yo for Craft CMS 5

A flash-message bus that plugins talk to.

Craft has setNotice(). It is one string, for one person, on the next page load, with no type beyond notice and error, no buttons, no way to reach anybody else, and no way for the plugin that sent it to ever learn whether it was seen.

Yo is the layer that answers all of those — once — so that thirty plugins do not each answer them differently. It is a plugin for plugins.

use justinholtweb\yo\Yo;

Yo::success('Saved.');

Yo::say('Import finished')
    ->body('412 entries in, 3 skipped.')
    ->success()
    ->action('Review the log', url: '/admin/transport/logs/88')
    ->to('group:editors')
    ->dedupe('transport:import')
    ->send();

Messages arrive in a floating control panel panel you can drag wherever you like, on your own front end in markup you style yourself, or anywhere else a plugin has taught Yo to reach.

Free. One edition. No paid tier. It is infrastructure — it is worth more the more plugins use it, and a price would be a tax on that.

Requirements

  • Craft CMS 5.3 or later
  • PHP 8.2 or later

Installation

composer require justinholtweb/craft-yo
php craft plugin/install yo

Or find Yo in the Craft Plugin Store.

What you get on day one, without changing any plugin

Switch Adopt Craft's own notices on — it is on by default — and every plugin on the site that calls setNotice(), setSuccess() or setError() shows up in the panel instead of Craft's toast. They do not know Yo exists. They do not have to.

What you get if you write to it

Craft's flashYo
Typesnotice, errorfive, and a plugin can register its own
Buttons—any number, links or POSTs
Recipientswhoever is making the requestanyone, a group, or everybody
Lifetimethe next page loaduntil dismissed, or a time to live
Repeatsstacks upa dedupe key replaces the earlier one
Did they see it?no answershown / read / dismissed / actioned, each an event
Wherethe control panelthe control panel, the front end, or a channel you wrote

Events

Everything is a seam. Nothing in Yo is a special case another plugin could not have built.

use justinholtweb\yo\services\Messages;
use justinholtweb\yo\events\DeliveryEvent;

// Learn what became of a message you sent.
Event::on(Messages::class, Messages::EVENT_MESSAGE_ACTIONED, function(DeliveryEvent $e) {
    if ($e->actionKey === 'retry') {
        MyPlugin::getInstance()->imports->retry($e->message->context['importId']);
    }
});
EventWhat it is for
Messages::EVENT_BEFORE_SENDEdit or suppress a message — including somebody else's
Messages::EVENT_AFTER_SENDKnow that one went, and where
Messages::EVENT_DEFINE_DELIVERYRoute a message to a channel it never asked for
Messages::EVENT_MESSAGE_SHOWNIt reached a screen
Messages::EVENT_MESSAGE_READSomebody opened it
Messages::EVENT_MESSAGE_DISMISSEDSomebody closed it
Messages::EVENT_MESSAGE_ACTIONEDSomebody pressed one of its buttons
Messages::EVENT_MESSAGE_EXPIREDIt ran out of time before anybody looked
Types::EVENT_REGISTER_MESSAGE_TYPESAdd a type with its own colour, icon and stickiness
Channels::EVENT_REGISTER_CHANNELSAdd a destination — Slack, e-mail, a webhook

Three template hooks let a plugin put its own markup inside the panel: yo.panel.header, yo.panel.footer, yo.message.meta.

The front end

Yo ships no front-end stylesheet, deliberately. What a warning looks like on your site is a design decision, and a plugin that arrives with an opinion about border radius is a plugin that gets ripped out.

{{ craft.yo.init() }}

That registers the behaviour and puts a container where you put the tag. Style .yo-message, .yo-message--error and friends however you like — or drop a yo/_messages.twig into your own templates directory and take the markup over outright.

Ajax without the Ajax

The panel updates itself with DataStar, vendored — no CDN, no build step, no framework in your control panel. Dismissing, acting on and clearing a message all post to the server and get back rendered HTML, which the client morphs into place. There is no client-side template of a message anywhere, so a type a third-party plugin registered looks exactly as right as one of Yo's own.

Console

php craft yo/say "Deploy finished" --type=success --to=group:editors
php craft yo/channels     # every channel, including ones other plugins added
php craft yo/types        # every message type, same
php craft yo/purge        # drop messages past their time to live

Documentation

Full docs at justinholt.com/plugins/craft-yo.

Who is the alien

An original character, drawn for this plugin: a furry, snouted, wisecracking houseguest from a faraway planet who will not stop shouting from the corner of your control panel. Any resemblance to a certain 1980s sitcom is affectionate and entirely the point.

License

The Craft License. See LICENSE.md.

Installation Instructions

To install this plugin, copy the command above to your terminal.

Reviews

This plugin doesn't have any reviews.

Active Installs
4
Version
5.0.0
License
Craft
Compatibility
Craft 5
Last release
September 15, 2026
Activity (30 days)
0
Closed Issues
0
Open Issues
0
Merged PRs
0
Open PRs