diff --git a/module/VuFindConsole/Module.php b/module/VuFindConsole/Module.php
index 1a8f4efdfc77ffb12822b54e4d4d7321d1c5a74e..0bbe894155c6caf45357b7c1757191c182a93ce2 100644
--- a/module/VuFindConsole/Module.php
+++ b/module/VuFindConsole/Module.php
@@ -79,6 +79,7 @@ class Module implements \Zend\ModuleManager\Feature\ConsoleUsageProviderInterfac
         return [
             'generate extendservice' => 'Override a service with a new child class',
             'generate nontabrecordaction' => 'Add routes for non-tab record action',
+            'generate dynamicroute' => 'Add a dynamic route',
             'generate recordroute' => 'Add a record route',
             'generate staticroute' => 'Add a static route',
             'harvest harvest_oai' => 'OAI-PMH harvester',
diff --git a/module/VuFindConsole/src/VuFindConsole/Controller/GenerateController.php b/module/VuFindConsole/src/VuFindConsole/Controller/GenerateController.php
index 01d630a31153708d89dc1a7cc9d94aa85232a964..0b12e6d3c30344437d79205aa4011d8c2cfea610 100644
--- a/module/VuFindConsole/src/VuFindConsole/Controller/GenerateController.php
+++ b/module/VuFindConsole/src/VuFindConsole/Controller/GenerateController.php
@@ -43,6 +43,53 @@ use Zend\Console\Console;
  */
 class GenerateController extends AbstractBase
 {
+    /**
+     * Add a new dynamic route definition
+     *
+     * @return \Zend\Console\Response
+     */
+    public function dynamicrouteAction()
+    {
+        $argv = $this->consoleOpts->getRemainingArgs();
+        if (!isset($argv[3])) {
+            Console::writeLine(
+                "Usage: {$_SERVER['argv'][0]} [route] [controller] [action]"
+                . " [target_module]"
+            );
+            Console::writeLine(
+                "\troute - the route name (used by router), e.g. customList"
+            );
+            Console::writeLine(
+                "\tcontroller - the controller name (used in URL), e.g. MyResearch"
+            );
+            Console::writeLine(
+                "\taction - the action and segment params, e.g. CustomList/[:id]"
+            );
+            Console::writeLine(
+                "\ttarget_module - the module where the new route will be generated"
+            );
+            return $this->getFailureResponse();
+        }
+
+        $route = $argv[0];
+        $controller = $argv[1];
+        $action = $argv[2];
+        $module = $argv[3];
+
+        // Create backup of configuration
+        $configPath = $this->getModuleConfigPath($module);
+        $this->backUpFile($configPath);
+
+        // Append the route
+        $config = include $configPath;
+        $routeGenerator = new \VuFind\Route\RouteGenerator();
+        $routeGenerator->addDynamicRoute($config, $route, $controller, $action);
+
+        // Write updated configuration
+        $this->writeModuleConfig($configPath, $config);
+        return $this->getSuccessResponse();
+    }
+
     /**
      * Extend an existing service
      *