diff --git a/src/Handler.php b/src/Handler.php
index d16de1b175611d74a2b20753a82e2c47f4af23a1..a58b0ac04da0ef628fbafd06376c465754379054 100644
--- a/src/Handler.php
+++ b/src/Handler.php
@@ -87,7 +87,7 @@ class Handler extends BaseHandler {
       $filename = $twig->render($template, $options);
       $file = $def['dest'] . '/' . $filename;
       if ($overwrite || !$fs->exists($file)) {
-        $twig_loader->setTemplate($filename, file_get_contents($pluginRoot . '/templates/' . $template . '.twig'));
+        $twig_loader->setTemplate($filename, file_get_contents($pluginRoot . '/templates/' . ($def['source'] ?? '') . $template . '.twig'));
         $rendered = $twig->render($filename, $options);
         if (!empty($def['add2yaml']) && isset($options[$filename])) {
           $yaml = Yaml::parse($rendered);
@@ -109,7 +109,7 @@ class Handler extends BaseHandler {
             $orig_ignored = TRUE;
           }
         }
-        else {
+        else if (empty($def['add2git'])) {
           $this->git('ignore ' . $filename);
         }
         file_put_contents($file, $rendered);
@@ -134,6 +134,11 @@ class Handler extends BaseHandler {
       }
     }
 
+    // Setup BackstopJS.
+    $this->git('ignore tests/backstop/backstop_data/bitmaps_test');
+    $this->git('ignore tests/backstop/backstop_data/html_report');
+    $this->git('lfs track tests/backstop/**/*.png');
+
     $traefik = new Traefik($options['projectname']);
     $traefik->update();
 
@@ -181,6 +186,12 @@ class Handler extends BaseHandler {
       ],
       'wkhtmltox.sh' => [
         'dest' => $projectRoot . '/.docker-init',
+      ],
+      'backstop.json' => [
+        'source' => 'tests/backstop/',
+        'dest' => $projectRoot . '/tests/backstop',
+        'add2yaml' => TRUE,
+        'add2git' => TRUE,
       ]
     ];
   }
diff --git a/templates/tests/backstop/backstop.json b/templates/tests/backstop/backstop.json
new file mode 100644
index 0000000000000000000000000000000000000000..2c374b350f5b127cd6f73aa04a47b0fab7795206
--- /dev/null
+++ b/templates/tests/backstop/backstop.json
@@ -0,0 +1,44 @@
+{
+  "id": "backstop_{{ projectname }}",
+  "viewports": [
+    {
+      "label": "phone",
+      "width": 320,
+      "height": 480
+    },
+    {
+      "label": "tablet",
+      "width": 768,
+      "height": 1024
+    },
+    {
+      "label": "desktop",
+      "width": 1960,
+      "height": 1280
+    }
+  ],
+  "onBeforeScript": "puppet/onBefore.js",
+  "onReadyScript": "puppet/onReady.js",
+  "scenarios": [
+    {
+      "label": "{{ projectname }}",
+      "url": "http://{{ webserver.type }}"
+    }
+  ],
+  "paths": {
+    "bitmaps_reference": "backstop_data/bitmaps_reference",
+    "bitmaps_test": "backstop_data/bitmaps_test",
+    "engine_scripts": "backstop_data/engine_scripts",
+    "html_report": "backstop_data/html_report",
+    "ci_report": "backstop_data/ci_report"
+  },
+  "report": ["browser"],
+  "engine": "puppeteer",
+  "engineOptions": {
+    "args": ["--no-sandbox"]
+  },
+  "asyncCaptureLimit": 5,
+  "asyncCompareLimit": 50,
+  "debug": false,
+  "debugWindow": false
+}