Store custom messages displayed by \Drupal::messenger()->addMessage() in the database In a custom module, I have the following code:

\Drupal::messenger()-&gt;addMessage(t("Email changed to %email.", ['%email' =&gt; $new_email]));


I issue more than a dozen different messages in this way.

I want a way to store these messages in the database with a way to list them and edit them, assign an ID or keyword to each message, and then do the equivalent of

\Drupal::messenger()-&gt;addMessage(message_id, parameters);


I'm sure I can accomplish this by creating a "message" content type with keyword and message fields, adding a message node for each message, and then writing a function in my custom module that loads a node by keyword, inserts any variables, and then calls \Drupal::messenger()->addMessage() to display it. I could also create a View to list all messages for editing purposes. But it seems like there should be a better way that doesn't involve adding messages to the content of the site.

Is there a module or a built-in Drupal facility that does this? 

My reading hasn't uncovered anything that looks like it will do these things. I realize Interface translation will support some of what I'm looking for, but don't know that it can be used with \Drupal::messenger()->addMessage().
The first thing to determine is whether you need your messages to be content or configuration. Content is (usually not) migrated between environments. It is created on an environment, and is unique to that environment. So your development environment may have one set of messages used for testing, and your production environment has another set of messages, used live.

Configuration on the other hand is migrated between environments. So you would create the messages on one environment, and when configuration is exported from that environment, the existing messages would be included in that export.

You probably want content entities.

How to create a new content entity type: https://www.drupal.org/docs/8/api/entity-api/creating-a-content-entity-type-in-drupal-8

How to create a new configuration entity type: https://www.drupal.org/docs/8/api/configuration-api/creating-a-configuration-entity-type-in-drupal-8

If you create a new content entity type, give the entity two fields, message_key and message_value. You will then load the entity as follows:

$entity = \Drupal::entityTypeManager()-&gt;getStorage('my_entity_type_id')-&gt;loadByProperties([
  'message_key' =&gt; $message_key,
]);

$message_value = NULL;
if ($entity) {
  $message_value = $entity-&gt;get('message_value')-&gt;value;
}


If you create a configuration entity, the ID of the entity will be the message key, and the entity only needs one more field for message value. The code above would be adjusted slightly:

$entity = \Drupal::entityTypeManager()-&gt;getStorage('my_entity_type_id')-&gt;loadByProperties([
  'id' =&gt; $message_key,
]);

$message_value = NULL;
if ($entity) {
  $message_value = $entity-&gt;get('message_value')-&gt;value;
}


The entity type you choose will become the storage mechanism for your messages, which you can then recover with the above methodology. Don't run $message_value through the t() function, as variables should not be run through that function, and translations of the message values are handled as translations of the entity, rather than the t() function.