diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index d3345ac0917d02059f635fce0fbd090d6aaee1c7..295804bf49aaebf16570da0ee0c8ed36f03f0fd0 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -13,7 +13,7 @@ build:
     - apt install -y nodejs
     - rm ./package-lock.json
     - npm install 
-    - ./node_modules/@angular/cli/bin/ng build  --prod --base-href=/
+    - ./node_modules/@angular/cli/bin/ng build  --prod --base-href=/ --configuration=$CI_COMMIT_REF_NAME
   artifacts:
     paths:
       - ./dist/
diff --git a/angular.json b/angular.json
index 8039483552efe4335085ed095ee7a41031b5c7d5..fdd4dcfb0e99f8e2ed7c7dee22a2606d2500e6ab 100644
--- a/angular.json
+++ b/angular.json
@@ -42,6 +42,30 @@
                   "with": "src/environments/environment.prod.ts"
                 }
               ]
+            },
+            "test": {
+              "fileReplacements": [
+                {
+                  "replace": "src/assets/config/apiservers.json",
+                  "with": "src/assets/config/apiservers.test.json"
+                },
+                {
+                  "replace": "src/assets/config/computesites.json",
+                  "with": "src/assets/config/computesites.test.json"
+                }
+              ]
+            },
+            "dev": {
+              "fileReplacements": [
+                {
+                  "replace": "src/assets/config/apiservers.json",
+                  "with": "src/assets/config/apiservers.dev.json"
+                },
+                {
+                  "replace": "src/assets/config/computesites.json",
+                  "with": "src/assets/config/computesites.dev.json"
+                }
+              ]
             }
           }
         },
@@ -129,4 +153,4 @@
       "prefix": "app"
     }
   }
-}
\ No newline at end of file
+}
diff --git a/src/assets/config/apiservers.dev.json b/src/assets/config/apiservers.dev.json
new file mode 100644
index 0000000000000000000000000000000000000000..de0e38f2970357fd71200bb74c62d5de9ab709fe
--- /dev/null
+++ b/src/assets/config/apiservers.dev.json
@@ -0,0 +1,14 @@
+[
+    {
+        "name": "Dev",
+        "tes": "https://strudel2-api-dev.cloud.cvl.org.au/tes",
+        "tws": "https://strudel2-api-dev.cloud.cvl.org.au"
+    },
+    {
+        "name": "Dev - Pawsey",
+        "tes": "https://strudel2-api-dev-pawsey.cloud.cvl.org.au/tes",
+        "tws": "https://strudel2-api-dev-pawsey.cloud.cvl.org.au"
+    }
+]
+
+
diff --git a/src/assets/config/apiservers.test.json b/src/assets/config/apiservers.test.json
new file mode 100644
index 0000000000000000000000000000000000000000..017812a56a80779869bc7141de850817701a5a1c
--- /dev/null
+++ b/src/assets/config/apiservers.test.json
@@ -0,0 +1,9 @@
+[
+    {
+        "name": "Testing",
+        "tes": "https://strudel2-api-test.cloud.cvl.org.au/tes",
+        "tws": "https://strudel2-api-test.cloud.cvl.org.au"
+    }
+]
+
+
diff --git a/src/assets/config/computesites.dev.json b/src/assets/config/computesites.dev.json
new file mode 100644
index 0000000000000000000000000000000000000000..ee3e971c4ac849190978fd95c1b1848f2cbcd382
--- /dev/null
+++ b/src/assets/config/computesites.dev.json
@@ -0,0 +1,35 @@
+[
+  {
+    "url": "https://strudel2-api-dev.cloud.cvl.org.au/m3/",
+    "name": "M3",
+    "host": "m3-login2.massive.org.au",
+    "dtn": "m3-dtn1.massive.org.au",
+    "cafingerprint": "RSA SHA256:cmDxHrZQSPlBMUUcI/BWmruXho1XOzfXPDHSqVTwV2I",
+    "appCatalog": [],
+    "appCatalogUri": "./assets/config/m3apps.dev.json",
+    "cancelcmd": "/usr/local/sv2/dev/sv2scancel.sh {jobid}",
+    "statcmd": "/usr/local/sv2/dev/sv2stat.py"
+  },
+  {
+    "url": "https://strudel2-api-dev.cloud.cvl.org.au/cvluwa/",
+    "name": "CVL@UWA",
+    "host": "146.118.65.246",
+    "dtn": "146.118.65.246",
+    "cafingerprint": "RSA SHA256:cmDxHrZQSPlBMUUcI/BWmruXho1XOzfXPDHSqVTwV2I",
+    "appCatalog": [],
+    "appCatalogUri": "./assets/config/cvluwaapps.dev.json",
+    "cancelcmd": "/usr/local/sv2/dev/sv2scancel.sh {jobid}",
+    "statcmd": "/usr/local/sv2/dev/sv2stat.py"
+  },
+  {
+    "url": null ,
+    "name": "Vault-V2@Monash",
+    "host": "dtn-2.erc.monash.edu.au",
+    "dtn": "dtn-2.erc.monash.edu.au",
+    "lscmd": "/srv/home/chines/hsmls.py",
+    "dtnport": "33001",
+    "cafingerprint": "RSA SHA256:cmDxHrZQSPlBMUUcI/BWmruXho1XOzfXPDHSqVTwV2I",
+    "appCatalog": [],
+    "appCatalogUri": null
+  }
+]
diff --git a/src/assets/config/computesites.test.json b/src/assets/config/computesites.test.json
new file mode 100644
index 0000000000000000000000000000000000000000..b9b9882776ecfdceadffe8b798b96a70990fd6da
--- /dev/null
+++ b/src/assets/config/computesites.test.json
@@ -0,0 +1,35 @@
+[
+  {
+    "url": "https://strudel2-api-test.cloud.cvl.org.au/m3/",
+    "name": "M3",
+    "host": "m3-login2.massive.org.au",
+    "dtn": "m3-dtn1.massive.org.au",
+    "cafingerprint": "RSA SHA256:cmDxHrZQSPlBMUUcI/BWmruXho1XOzfXPDHSqVTwV2I",
+    "appCatalog": [],
+    "appCatalogUri": "./assets/config/m3apps.test.json",
+    "cancelcmd": "/usr/local/sv2/sv2scancel.sh {jobid}",
+    "statcmd": "/usr/local/sv2/sv2stat.py"
+  },
+  {
+    "url": "https://strudel2-api-test.cloud.cvl.org.au/cvluwa/",
+    "name": "CVL@UWA",
+    "host": "146.118.65.246",
+    "dtn": "146.118.65.246",
+    "cafingerprint": "RSA SHA256:cmDxHrZQSPlBMUUcI/BWmruXho1XOzfXPDHSqVTwV2I",
+    "appCatalog": [],
+    "appCatalogUri": "./assets/config/cvluwaapps.test.json",
+    "cancelcmd": "/usr/local/sv2/sv2scancel.sh {jobid}",
+    "statcmd": "/usr/local/sv2/sv2stat.py"
+  },
+  {
+    "url": null ,
+    "name": "Vault-V2@Monash",
+    "host": "dtn-2.erc.monash.edu.au",
+    "dtn": "dtn-2.erc.monash.edu.au",
+    "lscmd": "/srv/home/chines/hsmls.py",
+    "dtnport": "33001",
+    "cafingerprint": "RSA SHA256:cmDxHrZQSPlBMUUcI/BWmruXho1XOzfXPDHSqVTwV2I",
+    "appCatalog": [],
+    "appCatalogUri": null
+  }
+]
diff --git a/src/assets/config/cvluwaapps.dev.json b/src/assets/config/cvluwaapps.dev.json
new file mode 100644
index 0000000000000000000000000000000000000000..76a46daaf809ccee4e455500d197cbee019e1971
--- /dev/null
+++ b/src/assets/config/cvluwaapps.dev.json
@@ -0,0 +1,36 @@
+[
+  { "url": null,
+    "name": "Desktop",
+    "startscript": "#!/bin/bash\n/usr/local/sv2/desktop/desktop.slurm\n ",
+    "paramscmd": "/usr/local/sv2/desktop/params.py",
+    "client": {"cmd": null, "redir": "vnc.html?password={password}" },
+    "localbind": true,
+    "applist": null
+  },
+ {
+   "url": null,
+   "name": "Jupyter Lab",
+   "startscript": "#!/bin/bash\n/usr/local/sv2/jupyter/jupyter.slurm\n",
+   "paramscmd": "/usr/local/sv2/jupyter/jupyter_params.py",
+   "client": {"cmd": null, "redir": "?token={token}"},
+   "localbind": true,
+   "applist": null
+  },
+  {
+    "url": null,
+    "name": "R Studio Server",
+    "startscript": "#!/bin/bash\n/usr/local/sv2/rstudioserver/run.sh\n",
+    "paramscmd": "/usr/local/sv2/rstudioserver/params.py",
+    "client": {"cmd": null, "redir": ""},
+    "localbind": true,
+    "applist": null
+  },
+  { "url": "transfer",
+    "name": "Transfer files",
+    "startscript": "#!/bin/bash\n echo '{appparams}' > ft.json",
+    "paramscmd": "/usr/local/sv2/copytool.py",
+    "client": {"cmd": null, "redir": null },
+    "localbind": true,
+    "applist": null
+  }
+]
diff --git a/src/assets/config/cvluwaapps.test.json b/src/assets/config/cvluwaapps.test.json
new file mode 100644
index 0000000000000000000000000000000000000000..76a46daaf809ccee4e455500d197cbee019e1971
--- /dev/null
+++ b/src/assets/config/cvluwaapps.test.json
@@ -0,0 +1,36 @@
+[
+  { "url": null,
+    "name": "Desktop",
+    "startscript": "#!/bin/bash\n/usr/local/sv2/desktop/desktop.slurm\n ",
+    "paramscmd": "/usr/local/sv2/desktop/params.py",
+    "client": {"cmd": null, "redir": "vnc.html?password={password}" },
+    "localbind": true,
+    "applist": null
+  },
+ {
+   "url": null,
+   "name": "Jupyter Lab",
+   "startscript": "#!/bin/bash\n/usr/local/sv2/jupyter/jupyter.slurm\n",
+   "paramscmd": "/usr/local/sv2/jupyter/jupyter_params.py",
+   "client": {"cmd": null, "redir": "?token={token}"},
+   "localbind": true,
+   "applist": null
+  },
+  {
+    "url": null,
+    "name": "R Studio Server",
+    "startscript": "#!/bin/bash\n/usr/local/sv2/rstudioserver/run.sh\n",
+    "paramscmd": "/usr/local/sv2/rstudioserver/params.py",
+    "client": {"cmd": null, "redir": ""},
+    "localbind": true,
+    "applist": null
+  },
+  { "url": "transfer",
+    "name": "Transfer files",
+    "startscript": "#!/bin/bash\n echo '{appparams}' > ft.json",
+    "paramscmd": "/usr/local/sv2/copytool.py",
+    "client": {"cmd": null, "redir": null },
+    "localbind": true,
+    "applist": null
+  }
+]
diff --git a/src/assets/config/m3apps.dev.json b/src/assets/config/m3apps.dev.json
new file mode 100644
index 0000000000000000000000000000000000000000..426c6f0476d7bf659f1c54bee83f0ed27091c594
--- /dev/null
+++ b/src/assets/config/m3apps.dev.json
@@ -0,0 +1,36 @@
+[
+  { "url": null,
+    "name": "Desktop",
+    "startscript": "#!/bin/bash\n/usr/local/sv2/desktop/desktop.slurm\n ",
+    "paramscmd": "/usr/local/sv2/desktop/params.py",
+    "client": {"cmd": null, "redir": "vnc.html?password={password}" },
+    "localbind": true,
+    "applist": null
+  },
+ {
+   "url": null,
+   "name": "Jupyter Lab",
+   "startscript": "#!/bin/bash\n/usr/local/sv2/jupyter/jupyter.slurm\n",
+   "paramscmd": "/usr/local/sv2/jupyter/jupyter_params.py",
+   "client": {"cmd": null, "redir": "?token={token}"},
+   "localbind": true,
+   "applist": null
+  },
+  { "url": "transfer",
+    "name": "Transfer files",
+    "startscript": "#!/bin/bash\n echo '{appparams}' | /usr/local/sv2/copytool.py\n",
+    "paramscmd": "/usr/local/sv2/desktop/params.py",
+    "client": {"cmd": null, "redir": null },
+    "localbind": true,
+    "applist": null
+  },
+  {
+    "url": null,
+    "name": "CryoSPARC",
+    "startscript": null,
+    "paramscmd": "/usr/local/sv2/cryosparc/cryosparc_params.py",
+    "client": {"cmd": null, "redir": ""},
+    "localbind": true,
+    "applist": null
+  }
+]
diff --git a/src/assets/config/m3apps.test.json b/src/assets/config/m3apps.test.json
new file mode 100644
index 0000000000000000000000000000000000000000..426c6f0476d7bf659f1c54bee83f0ed27091c594
--- /dev/null
+++ b/src/assets/config/m3apps.test.json
@@ -0,0 +1,36 @@
+[
+  { "url": null,
+    "name": "Desktop",
+    "startscript": "#!/bin/bash\n/usr/local/sv2/desktop/desktop.slurm\n ",
+    "paramscmd": "/usr/local/sv2/desktop/params.py",
+    "client": {"cmd": null, "redir": "vnc.html?password={password}" },
+    "localbind": true,
+    "applist": null
+  },
+ {
+   "url": null,
+   "name": "Jupyter Lab",
+   "startscript": "#!/bin/bash\n/usr/local/sv2/jupyter/jupyter.slurm\n",
+   "paramscmd": "/usr/local/sv2/jupyter/jupyter_params.py",
+   "client": {"cmd": null, "redir": "?token={token}"},
+   "localbind": true,
+   "applist": null
+  },
+  { "url": "transfer",
+    "name": "Transfer files",
+    "startscript": "#!/bin/bash\n echo '{appparams}' | /usr/local/sv2/copytool.py\n",
+    "paramscmd": "/usr/local/sv2/desktop/params.py",
+    "client": {"cmd": null, "redir": null },
+    "localbind": true,
+    "applist": null
+  },
+  {
+    "url": null,
+    "name": "CryoSPARC",
+    "startscript": null,
+    "paramscmd": "/usr/local/sv2/cryosparc/cryosparc_params.py",
+    "client": {"cmd": null, "redir": ""},
+    "localbind": true,
+    "applist": null
+  }
+]