diff --git a/flag.libraries.yml b/flag.libraries.yml
index e4322a6..0410ca8 100644
--- a/flag.libraries.yml
+++ b/flag.libraries.yml
@@ -8,8 +8,19 @@ flag.admin:
     - core/drupalSettings
     - core/drupal.form
 
-flag.link:
+# Normal action link library.
+flag.action_link:
   version: VERSION
   css:
     theme:
       css/flag-link.css: {}
+
+# Ajax action link library.
+flag.action_link_ajax:
+  version: VERSION
+  js:
+    js/flag-action_link_flash.js: {}
+  dependencies:
+    - core/jquery
+    - core/drupal
+    - core/drupal.ajax
\ No newline at end of file
diff --git a/flag.module b/flag.module
index 934073c..08cdd7d 100644
--- a/flag.module
+++ b/flag.module
@@ -270,16 +270,20 @@ function flag_entity_extra_field_info() {
  * Implements hook_theme().
  */
 function flag_theme() {
+  // Base theme definition used by all action links.
+  $action_base = [
+    'variables' => [
+      'attributes' => [],
+      'title' => NULL,
+      'action' => 'flag',
+      'flag' => NULL,
+      'flaggable' => NULL,
+    ]
+  ];
+
   return [
-    'flag' => [
-      'variables' => [
-        'attributes' => [],
-        'title' => NULL,
-        'action' => 'flag',
-        'flag' => NULL,
-        'flaggable' => NULL,
-      ],
-    ],
+    'action_link' => $action_base,
+    'action_link_ajax' => $action_base,
   ];
 }
 
diff --git a/js/flag-action_link_flash.js b/js/flag-action_link_flash.js
new file mode 100644
index 0000000..c8b4590
--- /dev/null
+++ b/js/flag-action_link_flash.js
@@ -0,0 +1,33 @@
+/**
+ * @file
+ * Defines the client side code for the ActionLinkFlashCommand.
+ *
+ * see \Drupal\flag\Ajax\ActionLinkFlashCommand
+ */
+
+(function ($, Drupal) {
+
+  'use strict';
+
+  /**
+   * Display message on the screen for a short period of time.
+   *
+   * @param {Drupal.Ajax} [ajax]
+   *   The ajax object.
+   * @param {object} response
+   *   Object holding the server response.
+   * @param {string} response.selector
+   *   The selector of link to be updated.
+   * @param {string} response.message
+   *   The message to be displayed.
+   * @param {number} [status]
+   *   The HTTP status code.
+   */
+  Drupal.AjaxCommands.prototype.actionLinkFlash = function (ajax, response, status) {
+    var message_elem = $('<span>' + response.message + '</span>');
+    $(response.selector).after(message_elem);
+
+    message_elem.fadeIn('fast').fadeOut(3000);
+  };
+
+})(jQuery, Drupal);
diff --git a/src/ActionLink/ActionLinkTypeBase.php b/src/ActionLink/ActionLinkTypeBase.php
index a8130e8..1465457 100644
--- a/src/ActionLink/ActionLinkTypeBase.php
+++ b/src/ActionLink/ActionLinkTypeBase.php
@@ -113,7 +113,7 @@ abstract class ActionLinkTypeBase extends PluginBase implements ActionLinkTypePl
     $render = [];
     $render['#flag'] = $flag;
     $render['#flaggable'] = $entity;
-    $render['#theme'] = 'flag';
+    $render['#theme'] = 'action_link';
 
     // Build the URL. It is important that bubbleable metadata is explicitly
     // collected and applied to the render array, as it might be rendered on its
diff --git a/src/Ajax/ActionLinkFlashCommand.php b/src/Ajax/ActionLinkFlashCommand.php
new file mode 100644
index 0000000..6c67e10
--- /dev/null
+++ b/src/Ajax/ActionLinkFlashCommand.php
@@ -0,0 +1,47 @@
+<?php
+
+namespace Drupal\flag\Ajax;
+
+use Drupal\Core\Ajax\CommandInterface;
+
+/**
+ * Pulse a message as an action link is updated.
+ *
+ * One of the commands issued as part of a UpdateActionLinkResponse.
+ *
+ * @ingroup flag
+ */
+class ActionLinkFlashCommand implements CommandInterface {
+
+  /**
+   * The message to be "pulsed" under the link.
+   *
+   * @var string
+   */
+  protected $message;
+
+  /**
+   * Construct a message pulser.
+   *
+   * @param string $selector
+   *   Identifies the action link to be flashed.
+   * @param string $message
+   *   (optional) The message to be displayed. Defaults to ''.
+   */
+  public function __construct($selector, $message = '') {
+    $this->selector = $selector;
+    $this->message = $message;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function render() {
+    return [
+      'command' => 'actionLinkFlash',
+      'selector' => $this->selector,
+      'message' => $this->message,
+    ];
+  }
+
+}
diff --git a/src/Ajax/UpdateActionLinkResponse.php b/src/Ajax/UpdateActionLinkResponse.php
new file mode 100644
index 0000000..2558657
--- /dev/null
+++ b/src/Ajax/UpdateActionLinkResponse.php
@@ -0,0 +1,52 @@
+<?php
+
+namespace Drupal\flag\Ajax;
+
+use Drupal\Core\Ajax\AjaxResponse;
+use Drupal\Core\Ajax\ReplaceCommand;
+use Drupal\Core\Entity\EntityInterface;
+use Drupal\flag\FlagInterface;
+
+/**
+ * A commands sequence to update a given action link.
+ *
+ * A series of AJAX commands bound together into a JSON response.
+ *
+ * @ingroup flag
+ */
+class UpdateActionLinkResponse extends AjaxResponse {
+
+  /**
+   * Construct a AJAX response that updates the action link.
+   *
+   * @param \Drupal\flag\FlagInterface $flag
+   *   The Flag in the action link.
+   * @param \Drupal\Core\Entity\EntityInterface $entity
+   *   The Entity in the action link.
+   * @param string $message
+   *   (optional) The message to be displayed. Defaults to ''.
+   */
+  public function __construct(FlagInterface $flag, EntityInterface $entity, $message = '') {
+    // Initialise bare AJAX response.
+    parent::__construct();
+
+    // Identify the action link.
+    $selector = '.flag-' . $flag->id() . '-' . $entity->id();
+
+    // Get a replacement action link (as a string).
+    /* @todo Is there a simpler way of rendering the link? */
+    $link = $flag->getLinkTypePlugin()->getLink($flag, $entity);
+    /** @var \Drupal\Core\Render\Renderer $renderer */
+    $renderer = \Drupal::service('renderer');
+    $content = $renderer->renderPlain($link);
+
+    // Push a replace command onto the stack.
+    $replace = new ReplaceCommand($selector, $content);
+    $this->addCommand($replace);
+
+    // Push a message pulsing comamnd onto the stack.
+    $pulse = new ActionLinkFlashCommand($selector, $message);
+    $this->addCommand($pulse);
+  }
+
+}
diff --git a/src/Controller/ActionLinkController.php b/src/Controller/ActionLinkController.php
index 7279e7d..c67ecbd 100644
--- a/src/Controller/ActionLinkController.php
+++ b/src/Controller/ActionLinkController.php
@@ -2,23 +2,27 @@
 
 namespace Drupal\flag\Controller;
 
-use Drupal\Core\Ajax\AjaxResponse;
-use Drupal\Core\Ajax\ReplaceCommand;
-use Drupal\Core\Controller\ControllerBase;
-use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
-use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\EventSubscriber\MainContentViewSubscriber;
-use Drupal\Core\Render\RendererInterface;
-use Symfony\Component\DependencyInjection\ContainerInterface;
+use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
+use Drupal\flag\Ajax\UpdateActionLinkResponse;
 use Drupal\flag\FlagInterface;
 use Drupal\flag\FlagServiceInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\HttpFoundation\RedirectResponse;
 use Symfony\Component\HttpFoundation\Request;
 
 /**
- * Provides a controller to flag and unflag when routed from a normal link.
+ * Controller responses to flag and unflag action links.
+ *
+ * If the action_link is a normal link then after an update the response to a
+ *  valid request is a redirect to the entity with drupal update message.
+ *
+ * For an ajax_action_link the response is a set of AJAX commands to update the
+ * link in the page. If the user agent has javascript disabled then the
+ * behaviour reverts to that of a normal link.
+ *
  */
-class ActionLinkController extends ControllerBase implements ContainerInjectionInterface {
-
+class ActionLinkController implements ContainerInjectionInterface {
   /**
    * The flag service.
    *
@@ -27,21 +31,13 @@ class ActionLinkController extends ControllerBase implements ContainerInjectionI
   protected $flagService;
 
   /**
-   * The renderer service.
-   *
-   * @var \Drupal\Core\Render\RendererInterface
-   */
-  protected $renderer;
-
-  /**
    * Constructor.
    *
    * @param FlagServiceInterface $flag
    *   The flag service.
    */
-  public function __construct(FlagServiceInterface $flag, RendererInterface $renderer) {
+  public function __construct(FlagServiceInterface $flag) {
     $this->flagService = $flag;
-    $this->renderer = $renderer;
   }
 
   /**
@@ -49,23 +45,22 @@ class ActionLinkController extends ControllerBase implements ContainerInjectionI
    */
   public static function create(ContainerInterface $container) {
     return new static(
-      $container->get('flag'),
-      $container->get('renderer')
+      $container->get('flag')
     );
   }
 
   /**
-   * Performs a flagging when called via a route.
+   * Performs a flagging.
    *
    * @param \Drupal\flag\FlagInterface $flag
    *   The flag entity.
    * @param int $entity_id
    *   The flaggable entity ID.
-   * @param \Symfony\Component\HttpFoundation\Request $request
-   *   The request.
+   * @param Symfony\Component\HttpFoundation\Request $request
+   *   The requets object.
    *
-   * @return \Symfony\Component\HttpFoundation\RedirectResponse
-   *   The response object.
+   * @return \Drupal\flag\Ajax\UpdateActionLinkResponse|\Symfony\Component\HttpFoundation\RedirectResponse|null
+   *   The response object, only if successful.
    *
    * @see \Drupal\flag\Plugin\Reload
    */
@@ -77,25 +72,37 @@ class ActionLinkController extends ControllerBase implements ContainerInjectionI
       $this->flagService->flag($flag, $entity);
     }
     catch (\LogicException $e) {
-      // Fail silently so we return to the entity, which will show an updated
-      // link for the existing state of the flag.
+      echo 'flag expection';
+      exit();
+      // Issue no repsonse.
+      // For ajax requests this forces an AJAX timeout.
+      // For normal links, for security reasons, a redirect determined by the
+      // user is inappropiate; the user agent will report a broken link.
+    }
+
+    if ($request->get(MainContentViewSubscriber::WRAPPER_FORMAT) == 'drupal_ajax') {
+      // Respond by updating the link.
+      $return = new UpdateActionLinkResponse($flag, $entity, $flag->getFlagMessage());
+    }
+    else {
+      drupal_set_message($flag->getFlagMessage());
+
+      // Back to the entity.
+      $return = new RedirectResponse($entity->toUrl()->toUriString());
     }
 
-    return $this->generateResponse($flag, $entity, $request);
+    return $return;
   }
 
   /**
-   * Performs a flagging when called via a route.
+   * Performs an unflagging.
    *
    * @param \Drupal\flag\FlagInterface $flag
    *   The flag entity.
    * @param int $entity_id
    *   The flaggable entity ID.
-   * @param \Symfony\Component\HttpFoundation\Request $request
-   *   The request.
    *
-   * @return \Symfony\Component\HttpFoundation\RedirectResponse
-   *   The response object.
+   * @return \Drupal\flag\Ajax\UpdateActionLinkResponse|\Symfony\Component\HttpFoundation\RedirectResponse|null
    *
    * @see \Drupal\flag\Plugin\Reload
    */
@@ -107,55 +114,26 @@ class ActionLinkController extends ControllerBase implements ContainerInjectionI
       $this->flagService->unflag($flag, $entity);
     }
     catch (\LogicException $e) {
-      // Fail silently so we return to the entity, which will show an updated
-      // link for the existing state of the flag.
+            echo 'unflag expection';
+      exit();
+      // Issue no repsonse.
+      // For ajax requests this forces an AJAX timeout.
+      // For normal links, for security reasons, a redirect determined by the
+      // user is inappropiate; the user agent will report a broken link.
     }
 
-    return $this->generateResponse($flag, $entity, $request);
-  }
-
-  /**
-   * Generates a response object after handing the un/flag request.
-   *
-   * Depending on the wrapper format of the request, it will either redirect
-   * or return an ajax response.
-   *
-   * @param \Drupal\flag\FlagInterface $flag
-   *   The flag entity.
-   * @param \Drupal\Core\Entity\EntityInterface $entity
-   *   The entity object.
-   * @param \Symfony\Component\HttpFoundation\Request $request
-   *   The request.
-   *
-   * @return \Drupal\Core\Ajax\AjaxResponse|\Symfony\Component\HttpFoundation\RedirectResponse
-   *   The response object.
-   */
-  protected function generateResponse(FlagInterface $flag, EntityInterface $entity, Request $request) {
     if ($request->get(MainContentViewSubscriber::WRAPPER_FORMAT) == 'drupal_ajax') {
-      // Create a new AJAX response.
-      $response = new AjaxResponse();
-
-      // Get the link type plugin.
-      $link_type = $flag->getLinkTypePlugin();
-
-      // Generate the link render array.
-      $link = $link_type->getLink($flag, $entity);
-
-      // Generate a CSS selector to use in a JQuery Replace command.
-      $selector = '.flag-' . $flag->id() . '-' . $entity->id();
-
-      // Create a new JQuery Replace command to update the link display.
-      $replace = new ReplaceCommand($selector, $this->renderer->renderPlain($link));
-      $response->addCommand($replace);
-
-      return $response;
+      // Respond by updating the link.
+      $return = new UpdateActionLinkResponse($flag, $entity, $flag->getUnflagMessage());
     }
     else {
-      // Redirect back to the entity. A passed in destination query parameter
-      // will automatically override this.
-      $url_info = $entity->toUrl();
-      return $this->redirect($url_info->getRouteName(), $url_info->getRouteParameters());
+      drupal_set_message($flag->getUnflagMessage());
+
+      // Back to the entity.
+      $return = new RedirectResponse($entity->toUrl()->toUriString());
     }
 
+    return $return;
   }
+
 }
diff --git a/src/Plugin/ActionLink/AJAXactionLink.php b/src/Plugin/ActionLink/AJAXactionLink.php
index f58f7ec..e4a69cb 100644
--- a/src/Plugin/ActionLink/AJAXactionLink.php
+++ b/src/Plugin/ActionLink/AJAXactionLink.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\flag\Plugin\ActionLink;
 
-use Drupal\flag\ActionLink\ActionLinkTypeBase;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\flag\FlagInterface;
 
@@ -25,8 +24,8 @@ class AJAXactionLink extends Reload {
    */
   public function buildLink($action, FlagInterface $flag, EntityInterface $entity) {
     $render = parent::buildLink($action, $flag, $entity);
-    $render['#attached']['library'][] = 'core/drupal.ajax';
-    $render['#attributes']['class'][] = 'use-ajax';
+    // Divert to a theme that adds AJAX functionality.
+    $render['#theme'] = 'action_link_ajax';
     return $render;
   }
 
diff --git a/templates/action-link-ajax.html.twig b/templates/action-link-ajax.html.twig
new file mode 100644
index 0000000..d0a97e9
--- /dev/null
+++ b/templates/action-link-ajax.html.twig
@@ -0,0 +1,23 @@
+{#
+/**
+ * @file
+ * Augment the normal action link with AJAX functionaliy.
+ *
+ * Available variables:
+ * - attributes: HTML attributes for the link element.
+ * - title: The flag link title.
+ * - action: 'flag' or 'unflag'
+ * - flag: The flag object.
+ * - flaggable: The flaggable entity.
+ */
+#}
+{% spaceless %}
+
+  {# Add the client side 'javascript command' code to style the link. #}
+  {{ attach_library('flag/flag.action_link_ajax') }}
+
+  {# Make the link an AJAX link. #}
+  {% set attributes = attributes.addClass('use-ajax') %}
+  {# Extend the default link. #}
+  {% include 'action-link.html.twig' %}
+{% endspaceless %}
diff --git a/templates/action-link.html.twig b/templates/action-link.html.twig
new file mode 100644
index 0000000..5e0968d
--- /dev/null
+++ b/templates/action-link.html.twig
@@ -0,0 +1,37 @@
+{#
+/**
+ * @file
+ * Default theme implementation for action links.
+ *
+ * Available variables:
+ * - attributes: HTML attributes for the link element.
+ * - title: The flag link title.
+ * - action: 'flag' or 'unflag'
+ * - flag: The flag object.
+ * - flaggable: The flaggable entity.
+ */
+#}
+{% spaceless %}
+
+  {# Add the CSS library for a normal link. #}
+  {{ attach_library('flag/flag.action_link') }}
+
+  {# Depending on the flag action, set the appropriate action class. #}
+  {% if action == 'unflag' %}
+    {% set action_class = 'action-unflag' %}
+  {% else %}
+    {% set action_class = 'action-flag' %}
+  {% endif %}
+
+  {# Set the remaining Flag CSS classes. #}
+  {% set classes = [
+    'flag',
+    'flag-' ~ flag.id(),
+    'flag-' ~ flag.id() ~ '-' ~ flaggable.id(),
+    action_class
+   ]
+  %}
+
+  <a{{ attributes.addClass(classes) }}>{{ title }}</a>
+
+{% endspaceless %}
diff --git a/templates/flag.html.twig b/templates/flag.html.twig
deleted file mode 100644
index b7080a1..0000000
--- a/templates/flag.html.twig
+++ /dev/null
@@ -1,35 +0,0 @@
-{#
-/**
- * @file
- * Default theme implementation for flag links.
- *
- * Available variables:
- * - attributes: HTML attributes for the link element.
- * - title: The flag link title.
- * - action: 'flag' or 'unflag'
- * - flag: The flag object.
- * - flaggable: The flaggable entity.
- */
-#}
-{% spaceless %}
-{# Attach the flag CSS library.#}
-{{ attach_library('flag/flag.link') }}
-
-{# Depending on the flag action, set the appropriate action class. #}
-{% if action == 'unflag' %}
-    {% set action_class = 'action-unflag' %}
-{% else %}
-    {% set action_class = 'action-flag' %}
-{% endif %}
-
-{# Set the remaining Flag CSS classes. #}
-{% set classes = [
-'flag',
-'flag-' ~ flag.id(),
-'flag-' ~ flag.id() ~ '-' ~ flaggable.id(),
-action_class
-] %}
-{% set attributes = attributes.addClass(classes) %}
-
-<a{{ attributes }}>{{ title }}</a>
-{% endspaceless %}
