diff --git a/workflow/usage.rst b/workflow/usage.rst
index 57fc4eb79dc..532837fe4bd 100644
--- a/workflow/usage.rst
+++ b/workflow/usage.rst
@@ -14,6 +14,15 @@ install the workflow feature before using it:
$ composer require symfony/workflow
+Configuration
+-------------
+
+To see all configuration options, if you are using the component inside a Symfony project run this command:
+
+.. code-block:: terminal
+
+ $ bin/console config:dump-reference framework workflows
+
Creating a Workflow
-------------------
@@ -533,3 +542,224 @@ You can access the message from a Twig template as follows:
Don't need a human-readable message? You can still use::
$event->setBlocked('true');
+
+Storing Metadata
+----------------
+
+.. versionadded:: 4.1
+
+ The feature to store metadata in workflows was introduced in Symfony 4.1.
+
+In case you need it, you can store arbitrary metadata in workflows, their
+places, and their transitions using the ``metadata`` option. This metadata can
+be as simple as the title of the workflow or as complex as your own application
+requires:
+
+.. configuration-block::
+
+ .. code-block:: yaml
+
+ # config/packages/workflow.yaml
+ framework:
+ workflows:
+ blog_publishing:
+ metadata:
+ title: 'Blog Publishing Workflow'
+ # ...
+ places:
+ draft:
+ metadata:
+ max_num_of_words: 500
+ # ...
+ transitions:
+ to_review:
+ from: draft
+ to: review
+ metadata:
+ priority: 0.5
+ # ...
+
+ .. code-block:: xml
+
+
+
+
+
+
+
+
+ Blog Publishing Workflow
+
+
+
+
+
+ 500
+
+
+
+
+
+ draft
+ review
+
+ 0.5
+
+
+
+
+
+
+
+ .. code-block:: php
+
+ // config/packages/workflow.php
+
+ $container->loadFromExtension('framework', [
+ // ...
+ 'workflows' => [
+ 'blog_publishing' => [
+ 'metadata' => [
+ 'title' => 'Blog Publishing Workflow',
+ ],
+ // ...
+ 'places' => [
+ 'draft' => [
+ 'metadata' => [
+ 'max_num_of_words' => 500,
+ ],
+ ],
+ // ...
+ ],
+ 'transitions' => [
+ 'to_review' => [
+ 'from' => 'draft',
+ 'to' => 'review',
+ 'metadata' => [
+ 'priority' => 0.5,
+ ],
+ ],
+ ],
+ ],
+ ],
+ ]);
+
+Then you can access this metadata in your controller as follows::
+
+ public function myControllerAction(Registry $registry, Article $article)
+ {
+ $workflow = $registry->get($article);
+
+ $workflow
+ ->getMetadataStore()
+ ->getWorkflowMetadata()['title'] ?? false
+ ;
+
+ // or
+ $workflow->getMetadataStore()
+ ->getWorkflowMetadata()['title'] ?? false
+ ;
+
+ // or
+ $aTransition = $workflow->getDefinition()->getTransitions()[0];
+ $workflow
+ ->getMetadataStore()
+ ->getTransitionMetadata($aTransition)['title'] ?? false
+ ;
+ }
+
+There is a shortcut that works with everything::
+
+ $workflow
+ ->getMetadataStore()
+ ->getMetadata('title')
+ ;
+
+In a Flash message in your Controller::
+
+ // $transition = ...; (an instance of Transition)
+
+ // $workflow is a Workflow instance retrieved from the Registry (see above)
+ $title = $workflow->getMetadataStore()->getMetadata('title', $transition);
+ $this->addFlash('info', "You have successfully applied the transition with title: '$title'");
+
+Metadata can also be accessed in a Listener, from the Event object.
+
+Using transition blockers you can
+return a user-friendly error message when you stop a transition from happening. In the example we
+get this message from the :class:`Symfony\\Component\\Workflow\\Event\\Event`'s metadata, giving
+you a central place to manage the text.
+
+.. tip::
+
+ This example has been simplified; in production you may prefer to use the :doc:`Translation `
+ component to manage messages in one place::
+
+ namespace App\Listener\Workflow\Task;
+
+ use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+ use Symfony\Component\Workflow\Event\GuardEvent;
+ use Symfony\Component\Workflow\TransitionBlocker;
+
+ class OverdueGuard implements EventSubscriberInterface
+ {
+ public function guardPublish(GuardEvent $event)
+ {
+ $timeLimit = $event->getMetadata('time_limit', $event->getTransition());
+
+ if (date('Hi') <= $timeLimit) {
+ return;
+ }
+
+ $explanation = $event->getMetadata('explanation', $event->getTransition());
+ $event->addTransitionBlocker(new TransitionBlocker($explanation , 0));
+ }
+
+ public static function getSubscribedEvents()
+ {
+ return [
+ 'workflow.task.guard.done' => 'guardPublish',
+ ];
+ }
+ }
+
+.. versionadded:: 4.1
+
+ The transition blockers were introduced in Symfony 4.1.
+
+In Twig templates, metadata is available via the ``workflow_metadata()`` function:
+
+.. code-block:: html+twig
+
+
Metadata
+
+ Workflow:
+ {{ workflow_metadata(article, 'title') }}
+
+
+ Current place(s)
+
+ {% for place in workflow_marked_places(article) %}
+ -
+ {{ place }}:
+
{{ workflow_metadata(article, 'max_num_of_words', place) ?: 'Unlimited'}}
+
+ {% endfor %}
+
+
+
+ Enabled transition(s)
+
+ {% for transition in workflow_transitions(article) %}
+ -
+ {{ transition.name }}:
+
{{ workflow_metadata(article, 'priority', transition) ?: '0' }}
+
+ {% endfor %}
+
+