Repository: superdesk/superdesk-publisher (language: python)

Issue:
make sure that tenant is reset



Discussion / hints:

Fix patch:
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index e0ff0d30..4e095a88 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -8,7 +8,7 @@ jobs:
 
     strategy:
       matrix:
-        node-version: [10.x, 12.x, 14.x]
+        node-version: [14.x]
 
     steps:
       - name: Set Timezone
diff --git a/client/components/Analytics/ArticleItem.jsx b/client/components/Analytics/ArticleItem.jsx
index e70634a9..5d34e85f 100644
--- a/client/components/Analytics/ArticleItem.jsx
+++ b/client/components/Analytics/ArticleItem.jsx
@@ -44,12 +44,12 @@ const ArticleItem = ({ item, style }) => {
             target="_blank"
             href={
               item.tenant.subdomain
-                ? "http://" +
+                ? "https://" +
                   item.tenant.subdomain +
                   "." +
                   item.tenant.domain_name +
                   item._links.online.href
-                : "http://" + item.tenant.domain_name + item._links.online.href
+                : "https://" + item.tenant.domain_name + item._links.online.href
             }
           >
             <i className="icon-external" />
@@ -71,7 +71,7 @@ const ArticleItem = ({ item, style }) => {
 
 ArticleItem.propTypes = {
   item: PropTypes.object.isRequired,
-  style: PropTypes.object.isRequired
+  style: PropTypes.object.isRequired,
 };
 
 export default ArticleItem;
diff --git a/client/components/ContentLists/ListCard.jsx b/client/components/ContentLists/ListCard.jsx
index 4c175d22..ec7bcb55 100644
--- a/client/components/ContentLists/ListCard.jsx
+++ b/client/components/ContentLists/ListCard.jsx
@@ -39,6 +39,9 @@ class ListCard extends React.Component {
       ? helpers.getUpdatedValues(this.state.list, this.props.list)
       : { ...this.state.list };
 
+    delete list.updated_at;
+    delete list.latest_items;
+
     this.props.publisher
       .manageList(list, this.state.list.id)
       .then((res) => {
@@ -122,6 +125,16 @@ class ListCard extends React.Component {
                     onChange={this.handleInputChange}
                   />
                 </div>
+                <div className="field">
+                  <label htmlFor="listLimit">Description</label>
+                  <input
+                    type="text"
+                    className="line-input"
+                    value={this.state.list.description}
+                    name="description"
+                    onChange={this.handleInputChange}
+                  />
+                </div>
                 <div className="field">
                   <label htmlFor="listCacheLifeTime">cache lifetime</label>
                   <input
diff --git a/client/components/Dashboard/Tenant.jsx b/client/components/Dashboard/Tenant.jsx
index c22d5843..582a9fa3 100644
--- a/client/components/Dashboard/Tenant.jsx
+++ b/client/components/Dashboard/Tenant.jsx
@@ -9,11 +9,13 @@ const Tenant = ({ tenant }) => {
           <a
             target="_blank"
             href={
-              tenant.output_channel
+              tenant.pwa_config && tenant.pwa_config.url
+                ? tenant.pwa_config.url
+                : tenant.output_channel
                 ? tenant.output_channel.config.url
                 : tenant.subdomain
-                ? "http://" + tenant.subdomain + "." + tenant.domain_name
-                : "http://" + tenant.domain_name
+                ? "https://" + tenant.subdomain + "." + tenant.domain_name
+                : "https://" + tenant.domain_name
             }
             flow="down"
           >
@@ -21,6 +23,9 @@ const Tenant = ({ tenant }) => {
             <i className="icon-external"></i>
           </a>
         </h3>
+        {tenant.pwa_config && tenant.pwa_config.url && (
+          <span className="sp-logo-pwa"></span>
+        )}
       </div>
       <div className="sd-card sd-card--flex-grow">
         <div className="dashboard-content-header sd-shadow--z1">
@@ -65,7 +70,7 @@ const Tenant = ({ tenant }) => {
           className="sd-card__content"
           style={{
             maxHeight: "210px",
-            overflowY: "auto"
+            overflowY: "auto",
           }}
         >
           <ul className="sd-card__content-list">
@@ -82,7 +87,7 @@ const Tenant = ({ tenant }) => {
                 <p className="panel-info__description">&nbsp;</p>
               </div>
             ) : (
-              tenant.content_lists.map(list => (
+              tenant.content_lists.map((list) => (
                 <li
                   key={list.name + list.id}
                   className="sd-card__content-list-item sd-card__content-list-item--no-padding"
@@ -107,7 +112,7 @@ const Tenant = ({ tenant }) => {
 };
 
 Tenant.propTypes = {
-  tenant: PropTypes.object.isRequired
+  tenant: PropTypes.object.isRequired,
 };
 
 export default Tenant;
diff --git a/client/components/Output/ArticleItem.jsx b/client/components/Output/ArticleItem.jsx
index b9d4eb6f..f04f9346 100644
--- a/client/components/Output/ArticleItem.jsx
+++ b/client/components/Output/ArticleItem.jsx
@@ -149,14 +149,19 @@ const ArticleItem = ({ item, style, onRemove }) => {
                   key={`articlestatuslabel_${index}_${article.id}`}
                   article={article}
                   url={
-                    article.tenant
+                    article.tenant &&
+                    article.tenant.pwa_config &&
+                    article.tenant.pwa_config.url
+                      ? article.tenant.pwa_config.url +
+                        article._links.online.href
+                      : article.tenant
                       ? article.tenant.subdomain
-                        ? "http://" +
+                        ? "https://" +
                           article.tenant.subdomain +
                           "." +
                           article.tenant.domain_name +
                           article._links.online.href
-                        : "http://" +
+                        : "https://" +
                           article.tenant.domain_name +
                           article._links.online.href
                       : null
diff --git a/client/components/Output/Listing.jsx b/client/components/Output/Listing.jsx
index f8bb5073..f8d11a5c 100644
--- a/client/components/Output/Listing.jsx
+++ b/client/components/Output/Listing.jsx
@@ -216,10 +216,18 @@ class Listing extends React.Component {
             item.page_views_count = helpers.countPageViews(item.articles);
             item.articles.forEach((item) => {
               if (item.route && item.status == "published" && item.tenant) {
-                let tenantUrl = item.tenant.subdomain
-                  ? item.tenant.subdomain + "." + item.tenant.domain_name
-                  : item.tenant.domain_name;
-                item.live_url = "http://" + tenantUrl + item._links.online.href;
+                let tenantUrl =
+                  item.tenant &&
+                  item.tenant.pwa_config &&
+                  item.tenant.pwa_config.url
+                    ? item.tenant.pwa_config.url
+                    : item.tenant.subdomain
+                    ? "https://" +
+                      item.tenant.subdomain +
+                      "." +
+                      item.tenant.domain_name
+                    : "https://" + item.tenant.domain_name;
+                item.live_url = tenantUrl + item._links.online.href;
               }
             });
           });
diff --git a/client/components/Output/PreviewPane.jsx b/client/components/Output/PreviewPane.jsx
index ff35f472..dedf457b 100644
--- a/client/components/Output/PreviewPane.jsx
+++ b/client/components/Output/PreviewPane.jsx
@@ -18,7 +18,7 @@ class PreviewPane extends React.Component {
 
     this.state = {
       package: null,
-      loading: true
+      loading: true,
     };
   }
 
@@ -42,14 +42,16 @@ class PreviewPane extends React.Component {
   loadPackage = () => {
     this.setState({ loading: true });
 
-    this.context.publisher.getPackage(this.props.package.id).then(response => {
-      if (this._isMounted) {
-        this.setState({
-          loading: false,
-          package: response
-        });
-      }
-    });
+    this.context.publisher
+      .getPackage(this.props.package.id)
+      .then((response) => {
+        if (this._isMounted) {
+          this.setState({
+            loading: false,
+            package: response,
+          });
+        }
+      });
   };
 
   render() {
@@ -58,12 +60,11 @@ class PreviewPane extends React.Component {
     let slideshows = [];
 
     if (this.state.package && this.state.package.extra_items) {
-      this.state.package.extra_items.map(gal => {
+      this.state.package.extra_items.map((gal) => {
         if (gal.id === "gallery") {
           if (gal.items[1] && Number.isInteger(parseInt(gal.items[1].order))) {
             gal.items = _.sortBy(gal.items, "order");
           }
-
           slideshows.push(gal);
         }
       });
@@ -77,12 +78,12 @@ class PreviewPane extends React.Component {
 
     let article = {
       feature_media:
-        this.state.package && this.state.package.feature_media
-          ? this.state.package.feature_media
+        this.state.package && this.state.package.featured_media
+          ? this.state.package.featured_media
           : null,
       updated_at: this.props.package.updated_at,
       article_statistics: {
-        page_views_number: this.props.package.page_views_count
+        page_views_number: this.props.package.page_views_count,
       },
       comments_count: this.props.package.comments_count,
       title: this.props.package.headline,
@@ -94,7 +95,7 @@ class PreviewPane extends React.Component {
         ? this.props.package.articles[0].paywall_secured
         : false,
       articles: this.props.package.articles,
-      authors: this.props.package.authors ? this.props.package.authors : []
+      authors: this.props.package.authors ? this.props.package.authors : [],
     };
 
     return <ArticlePreview article={article} close={this.props.close} />;
@@ -103,7 +104,7 @@ class PreviewPane extends React.Component {
 
 PreviewPane.propTypes = {
   close: PropTypes.func.isRequired,
-  package: PropTypes.object
+  package: PropTypes.object,
 };
 
 export default PreviewPane;
diff --git a/client/components/Output/PublishPane/Preview.jsx b/client/components/Output/PublishPane/Preview.jsx
index 006c7f0d..b09b24d2 100644
--- a/client/components/Output/PublishPane/Preview.jsx
+++ b/client/components/Output/PublishPane/Preview.jsx
@@ -28,13 +28,20 @@ class Preview extends React.Component {
       let token = this.context.publisher.getToken();
       let destination = this.props.item;
 
-      let tenantUrl = destination.tenant.subdomain
-        ? destination.tenant.subdomain + "." + destination.tenant.domain_name
-        : destination.tenant.domain_name;
+      console.log(destination);
+
+      let tenantUrl =
+        destination.tenant.pwa_config && destination.tenant.pwa_config.url
+          ? destination.tenant.pwa_config.url
+          : destination.tenant.subdomain
+          ? "//" +
+            destination.tenant.subdomain +
+            "." +
+            destination.tenant.domain_name
+          : "//" + destination.tenant.domain_name;
 
       let urls = {
         regular:
-          "//" +
           tenantUrl +
           "/preview/package/" +
           destination.route.id +
@@ -43,7 +50,6 @@ class Preview extends React.Component {
           "?auth_token=" +
           token,
         amp:
-          "//" +
           tenantUrl +
           "/preview/package/" +
           destination.route.id +
diff --git a/client/components/Output/PublishPane/PublishPane.jsx b/client/components/Output/PublishPane/PublishPane.jsx
index d3687f14..8a5a8902 100644
--- a/client/components/Output/PublishPane/PublishPane.jsx
+++ b/client/components/Output/PublishPane/PublishPane.jsx
@@ -77,9 +77,12 @@ class PublishPane extends React.Component {
           });
 
           if (tenant && item.route) {
-            let tenantUrl = tenant.subdomain
-              ? tenant.subdomain + "." + tenant.domain_name
-              : tenant.domain_name;
+            let tenantUrl =
+              tenant.pwa_config && tenant.pwa_config.url
+                ? tenant.pwa_config.url
+                : tenant.subdomain
+                ? "https://" + tenant.subdomain + "." + tenant.domain_name
+                : "https://" + tenant.domain_name;
 
             destinations.push({
               tenant: tenant,
@@ -93,7 +96,7 @@ class PublishPane extends React.Component {
               slug: item.slug,
               live_url:
                 item.status === "published"
-                  ? "http://" + tenantUrl + item._links.online.href
+                  ? tenantUrl + item._links.online.href
                   : null,
             });
           }
diff --git a/client/components/Output/Swimlane/TenantBoard.jsx b/client/components/Output/Swimlane/TenantBoard.jsx
index a74e8898..7b2c57e3 100644
--- a/client/components/Output/Swimlane/TenantBoard.jsx
+++ b/client/components/Output/Swimlane/TenantBoard.jsx
@@ -127,10 +127,18 @@ class TenantBoard extends React.Component {
           item.page_views_count = helpers.countPageViews(item.articles);
           item.articles.forEach((item) => {
             if (item.route && item.status == "published" && item.tenant) {
-              let tenantUrl = item.tenant.subdomain
-                ? item.tenant.subdomain + "." + item.tenant.domain_name
-                : item.tenant.domain_name;
-              item.live_url = "http://" + tenantUrl + item._links.online.href;
+              let tenantUrl =
+                item.tenant &&
+                item.tenant.pwa_config &&
+                item.tenant.pwa_config.url
+                  ? item.tenant.pwa_config.url
+                  : item.tenant.subdomain
+                  ? "https://" +
+                    item.tenant.subdomain +
+                    "." +
+                    item.tenant.domain_name
+                  : "https://" + item.tenant.domain_name;
+              item.live_url = tenantUrl + item._links.online.href;
             }
           });
         });
diff --git a/client/components/TargetedPublishing/AddWebsite.jsx b/client/components/TargetedPublishing/AddWebsite.jsx
index 26c6dbdb..f1336212 100644
--- a/client/components/TargetedPublishing/AddWebsite.jsx
+++ b/client/components/TargetedPublishing/AddWebsite.jsx
@@ -87,21 +87,15 @@ class AddWebsite extends React.Component {
           <div style={{ padding: "1.5rem" }}>
             <h3 className="tp-dropdown-heading">Add Website</h3>
             <ul className="simple-list--dotted simple-list">
-              {remainingSites.map((site) => {
-                let siteDomain = site.subdomain
-                  ? site.subdomain + "." + site.domain_name
-                  : site.domain_name;
-
-                return (
-                  <li
-                    key={site.id}
-                    className="simple-list__item tp-dropdown-li"
-                    onClick={() => this.addDestination(site)}
-                  >
-                    {siteDomain}
-                  </li>
-                );
-              })}
+              {remainingSites.map((site) => (
+                <li
+                  key={site.id}
+                  className="simple-list__item tp-dropdown-li"
+                  onClick={() => this.addDestination(site)}
+                >
+                  {site.name}
+                </li>
+              ))}
             </ul>
           </div>
         </div>
diff --git a/client/components/TargetedPublishing/Destination.jsx b/client/components/TargetedPublishing/Destination.jsx
index 6e174d58..6f7d0bcf 100644
--- a/client/components/TargetedPublishing/Destination.jsx
+++ b/client/components/TargetedPublishing/Destination.jsx
@@ -9,9 +9,6 @@ import { Label, IconButton } from "superdesk-ui-framework/react";
 import ContentLists from "./ContentLists";
 import RouteSelect from "./RouteSelect";
 import PublishingOptionSwitches from "../generic/PublishingOptionSwitches";
-
-import SaveBar from "../UI/SaveBar";
-
 class Destination extends Component {
   constructor(props) {
     super(props);
@@ -21,6 +18,8 @@ class Destination extends Component {
     const protocol = pubConfig.protocol || "https";
     let subdomain = null;
     let domainName = null;
+    let pwaUrl = null;
+    let siteName = null;
     let hasOutputChannel = false;
     let hasFbiaEnabled = false;
     let hasPaywallEnabled = false;
@@ -50,6 +49,11 @@ class Destination extends Component {
         hasOutputChannel = props.site.output_channel;
         subdomain = props.site.subdomain ? props.site.subdomain : "";
         domainName = props.site.domain_name;
+        siteName = props.site.name;
+        pwaUrl =
+          props.site.pwa_config && props.site.pwa_config.url
+            ? props.site.pwa_config.url
+            : null;
       } else if (props.rule) {
         destination.tenant = props.rule.tenant.code;
         destination.route = props.rule.route ? props.rule.route.id : null;
@@ -74,6 +78,11 @@ class Destination extends Component {
           ? props.rule.tenant.subdomain
           : "";
         domainName = props.rule.tenant.domain_name;
+        siteName = props.rule.tenant.name;
+        pwaUrl =
+          props.rule.tenant.pwa_config && props.rule.tenant.pwa_config.url
+            ? props.rule.tenant.pwa_config.url
+            : null;
       }
     }
 
@@ -88,6 +97,8 @@ class Destination extends Component {
         : "",
       subdomain: subdomain ? subdomain : "",
       domainName: domainName ? domainName : "",
+      pwaUrl: pwaUrl,
+      siteName: siteName ? siteName : "",
       hasOutputChannel: hasOutputChannel ? hasOutputChannel : false,
       hasPaywallEnabled: hasPaywallEnabled ? hasPaywallEnabled : false,
       hasAppleNewsEnabled: hasAppleNewsEnabled ? true : false,
@@ -122,6 +133,8 @@ class Destination extends Component {
       const protocol = pubConfig.protocol || "https";
       let subdomain = null;
       let domainName = null;
+      let pwaUrl = null;
+      let siteName = null;
       let hasOutputChannel = false;
       let hasFbiaEnabled = false;
       let hasPaywallEnabled = false;
@@ -138,6 +151,11 @@ class Destination extends Component {
         hasOutputChannel = props.site.output_channel;
         subdomain = props.site.subdomain ? props.site.subdomain : "";
         domainName = props.site.domain_name;
+        siteName = props.site.name;
+        pwaUrl =
+          props.site.pwa_config && props.site.pwa_config.url
+            ? props.site.pwa_config.url
+            : null;
       } else if (props.rule) {
         destination.tenant = props.rule.tenant.code;
         destination.route = props.rule.route ? props.rule.route.id : null;
@@ -162,6 +180,11 @@ class Destination extends Component {
           ? props.rule.tenant.subdomain
           : "";
         domainName = props.rule.tenant.domain_name;
+        siteName = props.rule.tenant.name;
+        pwaUrl =
+          props.rule.tenant.pwa_config && props.rule.tenant.pwa_config.url
+            ? props.rule.tenant.pwa_config.url
+            : null;
       }
 
       this.setState(
@@ -172,6 +195,8 @@ class Destination extends Component {
           }${domainName}/api/v2/`,
           subdomain: subdomain,
           domainName: domainName,
+          pwaUrl: pwaUrl,
+          siteName: siteName,
           hasOutputChannel: hasOutputChannel,
           hasPaywallEnabled: hasPaywallEnabled,
           hasAppleNewsEnabled: hasAppleNewsEnabled,
@@ -209,8 +234,17 @@ class Destination extends Component {
         { headers: this.props.apiHeader }
       )
       .then((res) => {
+        let previewUrl = res.data.preview_url;
+
+        if (this.state.pwaUrl) {
+          const regex = /preview\/publish\/package\/([a-zA-Z0-9]+)/gm;
+          const match = regex.exec(previewUrl);
+
+          previewUrl = this.state.pwaUrl + "/preview/token/" + match[1];
+        }
+
         this.setState({
-          previewUrl: res.data.preview_url,
+          previewUrl: previewUrl,
         });
         return res;
       });
@@ -301,10 +335,6 @@ class Destination extends Component {
 
   render() {
     if (this.state.deleted) return null;
-
-    let siteDomain = this.state.subdomain
-      ? this.state.subdomain + "." + this.state.domainName
-      : this.state.domainName;
     const destination = { ...this.state.destination };
     let contentListsNames = "";
 
@@ -360,7 +390,7 @@ class Destination extends Component {
               <div className="sd-list-item__row">
                 <span className="sd-overflow-ellipsis sd-list-item--element-grow">
                   <span className="sd-list-item__text-strong">
-                    {siteDomain}
+                    {this.state.siteName}
                   </span>
                 </span>
               </div>
@@ -405,7 +435,7 @@ class Destination extends Component {
                 <div className="sd-list-item__column sd-list-item__column--grow sd-list-item__column--no-border">
                   <div className="sd-list-item__row">
                     <span className="sd-overflow-ellipsis sd-list-item--element-grow sd-list-item__text-strong">
-                      {siteDomain}
+                      {this.state.siteName}
                     </span>
                     {preview}
                   </div>
diff --git a/client/components/generic/PreviewStatusLabels.jsx b/client/components/generic/PreviewStatusLabels.jsx
index ea78aed5..d24657f6 100644
--- a/client/components/generic/PreviewStatusLabels.jsx
+++ b/client/components/generic/PreviewStatusLabels.jsx
@@ -27,14 +27,19 @@ const PreviewStatusLabels = ({ articles }) => {
                   article={article}
                   style={{ marginRight: ".6em" }}
                   url={
-                    article.tenant
+                    article.tenant &&
+                    article.tenant.pwa_config &&
+                    article.tenant.pwa_config.url
+                      ? article.tenant.pwa_config.url +
+                        article._links.online.href
+                      : article.tenant
                       ? article.tenant.subdomain
-                        ? "http://" +
+                        ? "https://" +
                           article.tenant.subdomain +
                           "." +
                           article.tenant.domain_name +
                           article._links.online.href
-                        : "http://" +
+                        : "https://" +
                           article.tenant.domain_name +
                           article._links.online.href
                       : null
diff --git a/client/controllers/WebPublisherDashboardController.js b/client/controllers/WebPublisherDashboardController.js
index 6659ca8c..51c917d4 100644
--- a/client/controllers/WebPublisherDashboardController.js
+++ b/client/controllers/WebPublisherDashboardController.js
@@ -10,20 +10,15 @@ import React from "react";
 import ReactDOM from "react-dom";
 import Dashboard from "../components/Dashboard/Dashboard";
 
-WebPublisherDashboardController.$inject = [
-  "publisher"
-];
-export function WebPublisherDashboardController(
-  publisher
-) {
+WebPublisherDashboardController.$inject = ["publisher"];
+export function WebPublisherDashboardController(publisher) {
   class WebPublisherDashboard {
     constructor() {
       this.publisher = publisher;
+      this.publisher.setTenant();
 
       ReactDOM.render(
-        <Dashboard
-          publisher={this.publisher}
-        />,
+        <Dashboard publisher={this.publisher} />,
         document.getElementById("sp-dashboard-react-app")
       );
     }
diff --git a/client/controllers/WebPublisherErrorLogController.js b/client/controllers/WebPublisherErrorLogController.js
index 64874577..0c124fa9 100644
--- a/client/controllers/WebPublisherErrorLogController.js
+++ b/client/controllers/WebPublisherErrorLogController.js
@@ -10,20 +10,15 @@ import React from "react";
 import ReactDOM from "react-dom";
 import ErrorLog from "../components/ErrorLog/ErrorLog";
 
-WebPublisherErrorLogController.$inject = [
-  "publisher"
-];
-export function WebPublisherErrorLogController(
-  publisher
-) {
+WebPublisherErrorLogController.$inject = ["publisher"];
+export function WebPublisherErrorLogController(publisher) {
   class WebPublisherErrorLog {
     constructor() {
       this.publisher = publisher;
+      this.publisher.setTenant();
 
       ReactDOM.render(
-        <ErrorLog
-          publisher={this.publisher}
-        />,
+        <ErrorLog publisher={this.publisher} />,
         document.getElementById("sp-error-log-react-app")
       );
     }
diff --git a/client/controllers/WebPublisherOutputController.js b/client/controllers/WebPublisherOutputController.js
index 277519f4..1bebbfd0 100644
--- a/client/controllers/WebPublisherOutputController.js
+++ b/client/controllers/WebPublisherOutputController.js
@@ -18,7 +18,7 @@ WebPublisherOutputController.$inject = [
   "vocabularies",
   "notify",
   "config",
-  "api"
+  "api",
 ];
 export function WebPublisherOutputController(
   $scope,
@@ -34,14 +34,19 @@ export function WebPublisherOutputController(
       this.editorOpen = false;
       let isLanguagesEnabled = false;
 
-      vocabularies.getVocabularies().then(res => {
-        let languages = res.find(v => v._id === "languages");
-        languages = languages && languages.items ? languages.items.filter(l => l.is_active) : [];
+      vocabularies.getVocabularies().then((res) => {
+        let languages = res.find((v) => v._id === "languages");
+        languages =
+          languages && languages.items
+            ? languages.items.filter((l) => l.is_active)
+            : [];
 
         if (languages.length > 1) {
           isLanguagesEnabled = true;
         }
 
+        publisher.setTenant();
+
         ReactDOM.render(
           React.createElement(Output, {
             publisher: publisher,
@@ -50,21 +55,19 @@ export function WebPublisherOutputController(
             authoringWorkspace: authoringWorkspace,
             api: api,
             isLanguagesEnabled: isLanguagesEnabled,
-            languages: languages
+            languages: languages,
           }),
           document.getElementById("sp-output-react-app")
         );
-      })
+      });
 
-      $scope.$watch(authoringWorkspace.getState, state => {
+      $scope.$watch(authoringWorkspace.getState, (state) => {
         this.editorOpen = state && state.item ? true : false;
         let event = new CustomEvent("isSuperdeskEditorOpen", {
-          detail: this.editorOpen
+          detail: this.editorOpen,
         });
         document.dispatchEvent(event);
       });
-
-
     }
   }
 
diff --git a/client/controllers/WebPublisherSettingsController.js b/client/controllers/WebPublisherSettingsController.js
index 39bf1a7f..64a0cbbc 100644
--- a/client/controllers/WebPublisherSettingsController.js
+++ b/client/controllers/WebPublisherSettingsController.js
@@ -13,7 +13,7 @@ WebPublisherSettingsController.$inject = [
   "vocabularies",
   "$sce",
   "notify",
-  "api"
+  "api",
 ];
 export function WebPublisherSettingsController(
   $scope,
@@ -33,9 +33,12 @@ export function WebPublisherSettingsController(
 
       this.isLanguagesEnabled = false;
 
-      vocabularies.getVocabularies().then(res => {
-        this.languages = res.find(v => v._id === "languages");
-        this.languages = this.languages && this.languages.items ? this.languages.items.filter(l => l.is_active) : [];
+      vocabularies.getVocabularies().then((res) => {
+        this.languages = res.find((v) => v._id === "languages");
+        this.languages =
+          this.languages && this.languages.items
+            ? this.languages.items.filter((l) => l.is_active)
+            : [];
 
         if (this.languages.length > 1) {
           this.isLanguagesEnabled = true;
@@ -48,33 +51,34 @@ export function WebPublisherSettingsController(
       publisher
         .setToken()
         .then(publisher.querySites)
-        .then(sites => {
+        .then((sites) => {
           this.sites = sites;
           $scope.mainLoading = false;
           // loading routes
           angular.forEach(this.sites, (siteObj, key) => {
             publisher.setTenant(siteObj);
-            publisher.queryRoutes({ type: "collection" }).then(routes => {
+            publisher.queryRoutes({ type: "collection" }).then((routes) => {
               siteObj.routes = routes;
             });
           });
+          publisher.setTenant();
           // rules panel is default
           this.changePanel("tenant");
         });
     }
 
     loadAuthors(page = 0) {
-
-      api.users.query({
-        max_results: 200,
-        page: page,
-        sort: '[("first_name", 1), ("last_name", 1)]',
-        where: {
-          is_support: { $ne: true }
-        }
-      })
-        .then(response => {
-          let authors = response._items.filter(item => item.is_author);
+      api.users
+        .query({
+          max_results: 200,
+          page: page,
+          sort: '[("first_name", 1), ("last_name", 1)]',
+          where: {
+            is_support: { $ne: true },
+          },
+        })
+        .then((response) => {
+          let authors = response._items.filter((item) => item.is_author);
 
           if (authors.length) this.authors = [...this.authors, ...authors];
           if (response._links.next) this.loadAuthors(page + 1);
@@ -117,7 +121,7 @@ export function WebPublisherSettingsController(
     /**
      * @ngdoc method
      * @name WebPublisherSettingsController#toggleSiteWizard
-     * @param {String} outputChannelType - channel type (eg wordpress, drupal)
+     * @param {String} outputChannelType - channel type (eg wordpress, drupal, PWA)
      * @description Toggles site creation wizard
      */
     toggleSiteWizard(outputChannelType) {
@@ -145,8 +149,8 @@ export function WebPublisherSettingsController(
         case "routes":
           this.routeType = "";
           // getting only route redirects to fill route objects
-          this.redirectType = "route";
-          this.loadRedirects(true, 100000).then(redirects => this._refreshRoutes(redirects));
+          this.redirectType = "";
+          this._refreshRoutes();
 
           break;
         case "redirects":
@@ -211,11 +215,12 @@ export function WebPublisherSettingsController(
 
       publisher
         .manageWebhook(_.pick(newWebhook, updatedKeys), this.selectedWebhook.id)
-        .then(webhook => {
+        .then((webhook) => {
           this.webhookPaneOpen = false;
           this.selectedWebhook = {};
           this._refreshWebhooks();
-        }).catch(err => {
+        })
+        .catch((err) => {
           $scope.loading = false;
           let message = err.data.message
             ? err.data.message
@@ -238,7 +243,7 @@ export function WebPublisherSettingsController(
             this._refreshWebhooks();
           })
         )
-        .catch(err => {
+        .catch((err) => {
           let message = err.data.message
             ? err.data.message
             : "Something went wrong. Try again.";
@@ -253,7 +258,7 @@ export function WebPublisherSettingsController(
      */
     _refreshWebhooks() {
       $scope.loading = true;
-      publisher.getWebhooks().then(webhooks => {
+      publisher.getWebhooks().then((webhooks) => {
         this.webhooks = webhooks;
         $scope.loading = false;
       });
@@ -290,9 +295,9 @@ export function WebPublisherSettingsController(
         const regex = /\/{([a-zA-Z0-9]*)}/gm;
         let match = regex.exec($scope.newRoute.variable_pattern);
 
-        $scope.newRoute.variableName = match[1] ? match[1] : '';
+        $scope.newRoute.variableName = match[1] ? match[1] : "";
 
-        delete $scope.newRoute.requirements
+        delete $scope.newRoute.requirements;
         delete $scope.newRoute.variable_pattern;
       }
 
@@ -307,21 +312,20 @@ export function WebPublisherSettingsController(
      * @description Saving route
      */
     saveRoute() {
-
       if ($scope.newRoute.type === "custom") {
-        $scope.newRoute.variable_pattern = "/{" + $scope.newRoute.variableName + "}";
+        $scope.newRoute.variable_pattern =
+          "/{" + $scope.newRoute.variableName + "}";
 
         $scope.newRoute.requirements = [
           {
-            "key": $scope.newRoute.variableName,
-            "value": "[a-zA-Z\\-_]+"
-          }
+            key: $scope.newRoute.variableName,
+            value: "[a-zA-Z\\-_]+",
+          },
         ];
 
         delete $scope.newRoute.variableName;
       }
 
-
       let updatedKeys = this._updatedKeys($scope.newRoute, this.selectedRoute);
 
       // only for updating, parent is received as object but for update id is needed
@@ -334,7 +338,7 @@ export function WebPublisherSettingsController(
           _.pick($scope.newRoute, updatedKeys),
           this.selectedRoute.id
         )
-        .then(route => {
+        .then((route) => {
           this.paneOpen = false;
           this._refreshRoutes();
         });
@@ -354,7 +358,7 @@ export function WebPublisherSettingsController(
             this._refreshRoutes();
           })
         )
-        .catch(err => {
+        .catch((err) => {
           let message = err.data.message
             ? err.data.message
             : "Something went wrong. Try again.";
@@ -394,7 +398,7 @@ export function WebPublisherSettingsController(
 
           if (removedItem) {
             removedItem.removed = true;
-            parent.children = parent.children.filter(item => !item.removed);
+            parent.children = parent.children.filter((item) => !item.removed);
           }
         } else if (!item.parent) {
           // item was top level and was moved to other list
@@ -403,7 +407,7 @@ export function WebPublisherSettingsController(
           if (removedItem) {
             removedItem.removed = true;
             $scope.routes.children = $scope.routes.children.filter(
-              item => !item.removed
+              (item) => !item.removed
             );
           }
         }
@@ -412,7 +416,7 @@ export function WebPublisherSettingsController(
           .slice(0, index)
           .concat(item)
           .concat(list.children.slice(index))
-          .filter(item => !item.removed);
+          .filter((item) => !item.removed);
 
         let parentId = list.children[0].parent;
         let newPosition = list.children.indexOf(item);
@@ -435,55 +439,49 @@ export function WebPublisherSettingsController(
      * @ngdoc method
      * @name WebPublisherSettingsController#_refreshRoutes
      * @private
-     * @param {Array} redirects - list of redirects
      * @description Loads list of routes
      */
-    _refreshRoutes(redirects) {
+    _refreshRoutes() {
       $scope.loading = true;
-      publisher.queryRoutes().then(routes => {
+      publisher.queryRoutes().then((routes) => {
         $scope.loading = false;
         let filteredRoutes = { children: null };
 
         if (this.routeType === "content") {
           filteredRoutes.children = routes.filter(
-            item => item.type === "content"
+            (item) => item.type === "content"
           );
         } else if (this.routeType === "collection") {
           filteredRoutes.children = routes
-            .filter(item => item.type === "collection")
-            .filter(item => !item.parent);
+            .filter((item) => item.type === "collection")
+            .filter((item) => !item.parent);
         } else {
-          filteredRoutes.children = routes.filter(item => !item.parent);
+          filteredRoutes.children = routes.filter((item) => !item.parent);
         }
 
-        if (redirects && redirects.length) {
-          filteredRoutes.children.forEach(route => {
-            let routeRedirect = redirects.find(r => {
-              return r.route_source.id === route.id
-            }
-            );
-            if (routeRedirect) route.redirect = routeRedirect;
-          })
-        }
         $scope.routes = filteredRoutes;
+        $scope.routes_flat = this._flattenTree(filteredRoutes);
       });
     }
     // ---------------------------------- REDIRECTS
     /**
-    * @ngdoc method
-    * @name WebPublisherSettingsController#toogleCreateRedirect
-    * @param {Boolean} paneOpen - should pane be open
-    * @param {String} kind - type of redirect
-    * @description Opens window for creating new redirect
-    */
-    toggleCreateRedirect(paneOpen, kind = 'route') {
+     * @ngdoc method
+     * @name WebPublisherSettingsController#toogleCreateRedirect
+     * @param {Boolean} paneOpen - should pane be open
+     * @param {String} kind - type of redirect
+     * @description Opens window for creating new redirect
+     */
+    toggleCreateRedirect(paneOpen, kind = "route") {
       this.selectedRedirect = {};
       $scope.newRedirect = { kind: kind, permanent: "true" };
       this.paneOpen = paneOpen;
     }
 
     onChangeRedirectKind() {
-      $scope.newRedirect = { kind: $scope.newRedirect.kind, permanent: $scope.newRedirect.permanent };
+      $scope.newRedirect = {
+        kind: $scope.newRedirect.kind,
+        permanent: $scope.newRedirect.permanent,
+      };
     }
 
     changeRedirectFilter(type) {
@@ -492,20 +490,21 @@ export function WebPublisherSettingsController(
     }
 
     saveRedirect() {
-      let updatedKeys = this._updatedKeys($scope.newRedirect, this.selectedRedirect);
+      let updatedKeys = this._updatedKeys(
+        $scope.newRedirect,
+        this.selectedRedirect
+      );
       let newRedirect = _.pick($scope.newRedirect, updatedKeys);
 
       delete newRedirect.kind;
 
       publisher
-        .manageRedirect(
-          newRedirect,
-          this.selectedRedirect.id
-        )
-        .then(r => {
+        .manageRedirect(newRedirect, this.selectedRedirect.id)
+        .then((r) => {
           this.toggleCreateRedirect(false);
           this.loadRedirects(true);
-        }).catch(err => {
+        })
+        .catch((err) => {
           let message = err.data.message
             ? err.data.message
             : "Something went wrong. Try again.";
@@ -516,7 +515,7 @@ export function WebPublisherSettingsController(
     editRedirect(redirect) {
       let editedRedirect = {
         permanent: redirect.permanent ? "true" : "false",
-        id: redirect.id
+        id: redirect.id,
       };
 
       if (redirect.route_target && redirect.route_source) {
@@ -540,11 +539,13 @@ export function WebPublisherSettingsController(
         .confirm(gettext("Please confirm you want to delete redirect."))
         .then(() =>
           publisher.removeRedirect(id).then(() => {
-            let index = $scope.redirects.items.findIndex(redirect => redirect.id === id);
+            let index = $scope.redirects.items.findIndex(
+              (redirect) => redirect.id === id
+            );
             if (index !== -1) $scope.redirects.items.splice(index, 1);
           })
         )
-        .catch(err => {
+        .catch((err) => {
           let message = err.data.message
             ? err.data.message
             : "Something went wrong. Try again.";
@@ -555,43 +556,47 @@ export function WebPublisherSettingsController(
     loadRedirects(reset, limit) {
       if (reset) $scope.redirects = { items: [], pages: 1 };
 
-
       const page = !$scope.redirects.page ? 1 : $scope.redirects.page + 1;
       const params = {
         page: page,
         limit: limit ? limit : 50,
-        "sorting[createdAt]": "desc"
+        "sorting[createdAt]": "desc",
       };
 
-      if ((!reset && $scope.redirects.pages && page > $scope.redirects.pages) || $scope.redirects.loading) {
+      if (
+        (!reset && $scope.redirects.pages && page > $scope.redirects.pages) ||
+        $scope.redirects.loading
+      ) {
         return;
       }
 
       $scope.redirects.loading = true;
 
-      return publisher.queryRedirects(params).then(redirects => {
+      return publisher.queryRedirects(params).then((redirects) => {
         let filteredRedirects = redirects._embedded._items;
 
         if (this.redirectType === "route") {
           filteredRedirects = filteredRedirects.filter(
-            redirect => redirect.route_target && redirect.route_source
+            (redirect) => redirect.route_target && redirect.route_source
           );
         } else if (this.redirectType === "custom") {
           filteredRedirects = filteredRedirects.filter(
-            redirect => !redirect.route_target && !redirect.route_source
+            (redirect) => !redirect.route_target && !redirect.route_source
           );
         }
 
         $scope.redirects.loading = false;
         $scope.redirects.page = page;
         $scope.redirects.pages = redirects.pages;
-        $scope.redirects.items = [...$scope.redirects.items, ...filteredRedirects];
+        $scope.redirects.items = [
+          ...$scope.redirects.items,
+          ...filteredRedirects,
+        ];
 
         return $scope.redirects.items;
       });
     }
 
-
     // ---------------------------------- NAVIGATION
 
     /**
@@ -644,11 +649,15 @@ export function WebPublisherSettingsController(
       }
 
       if ($scope.newMenu.route) {
-        let route = $scope.routes.find(r => r.id === $scope.newMenu.route);
-        if (route.type === 'custom') {
-          let valueSlug = $scope.newMenu.variableValue.toLowerCase().replaceAll(" ", "-");
-
-          $scope.newMenu.uri = valueSlug.length ? route.static_prefix + "/" + valueSlug : route.static_prefix;
+        let route = $scope.routes.find((r) => r.id === $scope.newMenu.route);
+        if (route.type === "custom") {
+          let valueSlug = $scope.newMenu.variableValue
+            .toLowerCase()
+            .replaceAll(" ", "-");
+
+          $scope.newMenu.uri = valueSlug.length
+            ? route.static_prefix + "/" + valueSlug
+            : route.static_prefix;
           delete $scope.newMenu.route;
           delete $scope.newMenu.variableValue;
         }
@@ -686,7 +695,7 @@ export function WebPublisherSettingsController(
     editMenuTree(menu) {
       $scope.menu = menu;
       $scope.menusInTree = this._flattenTree(menu);
-      publisher.queryRoutes().then(routes => {
+      publisher.queryRoutes().then((routes) => {
         $scope.routes = routes;
       });
       this.changeManageTab("navigation-menu");
@@ -728,14 +737,14 @@ export function WebPublisherSettingsController(
     isRouteTypeCustom(routeId) {
       if (!$scope.routes || !$scope.routes.length) return null;
 
-      let route = $scope.routes.find(r => r.id === routeId);
-      return route.type === 'custom';
+      let route = $scope.routes.find((r) => r.id === routeId);
+      return route.type === "custom";
     }
 
     getRouteNameById(routeId) {
       if (!$scope.routes || !$scope.routes.length) return null;
 
-      let route = $scope.routes.find(r => r.id === routeId);
+      let route = $scope.routes.find((r) => r.id === routeId);
       return route.name;
     }
 
@@ -761,7 +770,7 @@ export function WebPublisherSettingsController(
     navigationMenuSetUri() {
       if ($scope.newMenu.route) {
         let route = $scope.routes.find(
-          route => route.id === $scope.newMenu.route
+          (route) => route.id === $scope.newMenu.route
         );
 
         $scope.newMenu.uri = route.staticPrefix;
@@ -805,7 +814,7 @@ export function WebPublisherSettingsController(
           .slice(0, index)
           .concat(item)
           .concat(list.children.slice(index))
-          .filter(item => !item.removed);
+          .filter((item) => !item.removed);
 
         let menuPosition = list.children.indexOf(item);
 
@@ -828,7 +837,7 @@ export function WebPublisherSettingsController(
      */
     _refreshCurrentMenu() {
       this.menuPaneOpen = false;
-      publisher.getMenu($scope.menu.id).then(menu => {
+      publisher.getMenu($scope.menu.id).then((menu) => {
         $scope.menu = menu;
         $scope.menusInTree = this._flattenTree(menu);
       });
@@ -844,7 +853,7 @@ export function WebPublisherSettingsController(
       $scope.loading = true;
       this.menuAdd = false;
       this.menuPaneOpen = false;
-      publisher.queryMenus().then(menus => {
+      publisher.queryMenus().then((menus) => {
         $scope.loading = false;
         $scope.menus = menus;
       });
@@ -913,21 +922,29 @@ export function WebPublisherSettingsController(
       let filteredNewSite = { ...$scope.newSite };
       delete filteredNewSite.updated_at;
 
-      if (filteredNewSite.apple_news_config === null) filteredNewSite.apple_news_config = { api_key_id: null, api_key_secret: null, channel_id: null };
+      if (filteredNewSite.apple_news_config === null)
+        filteredNewSite.apple_news_config = {
+          api_key_id: null,
+          api_key_secret: null,
+          channel_id: null,
+        };
 
       let updatedKeys = this._updatedKeys(filteredNewSite, this.selectedSite);
       this.loading = true;
 
       publisher
-        .manageSite(_.pick(filteredNewSite, updatedKeys), this.selectedSite.code)
-        .then(site => {
+        .manageSite(
+          _.pick(filteredNewSite, updatedKeys),
+          this.selectedSite.code
+        )
+        .then((site) => {
           this.siteForm.$setPristine();
           this.selectedSite = site;
           this.loading = false;
           publisher.setTenant(site);
           this._refreshSites();
         })
-        .catch(err => {
+        .catch((err) => {
           $scope.newSite = angular.copy(this.selectedSite);
           this.loading = false;
         });
@@ -949,7 +966,7 @@ export function WebPublisherSettingsController(
               publisher.setTenant();
               this._refreshSites();
             })
-            .catch(err => {
+            .catch((err) => {
               if (err.status === 409) {
                 modal
                   .confirm(
@@ -969,7 +986,11 @@ export function WebPublisherSettingsController(
     }
 
     switchAppleNewsConfig() {
-      $scope.newSite.apple_news_config = $scope.newSite.apple_news_config === null || $scope.newSite.apple_news_config.channel_id === null ? { api_key_id: '', api_key_secret: '', channel_id: '' } : null;
+      $scope.newSite.apple_news_config =
+        $scope.newSite.apple_news_config === null ||
+        $scope.newSite.apple_news_config.channel_id === null
+          ? { api_key_id: "", api_key_secret: "", channel_id: "" }
+          : null;
       this.siteForm.$setDirty();
     }
 
@@ -1012,10 +1033,10 @@ export function WebPublisherSettingsController(
      * @description Saving theme settings and logo
      */
     saveThemeSettings() {
-      let settingsToSave = _.map($scope.newThemeSettings.settings, value => {
+      let settingsToSave = _.map($scope.newThemeSettings.settings, (value) => {
         return _.pick(value, ["name", "value"]);
       });
-      publisher.saveSettings({ bulk: settingsToSave }).then(settings => {
+      publisher.saveSettings({ bulk: settingsToSave }).then((settings) => {
         this.themeSettingsForm.$setPristine();
       });
     }
@@ -1035,12 +1056,12 @@ export function WebPublisherSettingsController(
         if (!logoFile.$error) {
           publisher
             .uploadThemeLogo({ logo: logoFile }, type)
-            .then(response => {
+            .then((response) => {
               this.themeSettings[type] = response.data;
               let flagName = "replace_" + type;
               this[flagName] = false;
             })
-            .catch(err => {
+            .catch((err) => {
               $scope.newThemeSettings[type].error = true;
             });
         }
@@ -1058,7 +1079,7 @@ export function WebPublisherSettingsController(
       $scope.newRule = {
         type: type,
         destinations: [],
-        expressions: [{}]
+        expressions: [{}],
       };
 
       this.rulePaneOpen = type ? true : false;
@@ -1072,7 +1093,7 @@ export function WebPublisherSettingsController(
      * @description gets tenant name by its code
      */
     getTenantNameByCode(code) {
-      let tenant = this.sites.find(site => {
+      let tenant = this.sites.find((site) => {
         return site.code == code;
       });
 
@@ -1086,7 +1107,7 @@ export function WebPublisherSettingsController(
      * @description gets tenant name by its code
      */
     getTenantOutputChannelNameByCode(code) {
-      let tenant = this.sites.find(site => {
+      let tenant = this.sites.find((site) => {
         return site.code == code;
       });
 
@@ -1106,7 +1127,11 @@ export function WebPublisherSettingsController(
         return site.code == code;
       });
 
-      return tenant ? tenant.subdomain + "." + tenant.domain_name : null;
+      return tenant
+        ? tenant.pwa_config && tenant.pwa_config.url
+          ? tenant.pwa_config.url
+          : tenant.subdomain + "." + tenant.domain_name
+        : null;
     }
 
     /**
@@ -1320,7 +1345,7 @@ export function WebPublisherSettingsController(
         // organization rule
         $scope.newRule.destinations = [];
 
-        _.each($scope.newRule.configuration.destinations, destination => {
+        _.each($scope.newRule.configuration.destinations, (destination) => {
           let tenant = this.sites.find(function (site) {
             return site.code == destination.tenant;
           });
@@ -1342,18 +1367,18 @@ export function WebPublisherSettingsController(
         description: $scope.newRule.description,
         priority: "1",
         expression: "",
-        configuration: []
+        configuration: [],
       };
 
       if ($scope.newRule.type == "organization") {
         newRule.configuration.push({
           key: "destinations",
-          value: []
+          value: [],
         });
 
-        _.each($scope.newRule.destinations, destination => {
+        _.each($scope.newRule.destinations, (destination) => {
           let configuration = {
-            tenant: destination.code
+            tenant: destination.code,
           };
 
           newRule.configuration[0].value.push(configuration);
@@ -1365,7 +1390,7 @@ export function WebPublisherSettingsController(
         if ($scope.newRule.action.route) {
           newRule.configuration.push({
             key: "route",
-            value: $scope.newRule.action.route
+            value: $scope.newRule.action.route,
           });
         }
         if ($scope.newRule.action.published) {
@@ -1414,10 +1439,7 @@ export function WebPublisherSettingsController(
           }
         });
       }
-      return _(newRule)
-        .omitBy(_.isNil)
-        .omitBy(_.isEmpty)
-        .value();
+      return _(newRule).omitBy(_.isNil).omitBy(_.isEmpty).value();
     }
 
     /**
@@ -1436,7 +1458,7 @@ export function WebPublisherSettingsController(
             _.pick(newRule, updatedKeys),
             this.selectedRule.id
           )
-          .then(rule => {
+          .then((rule) => {
             this.rulePaneOpen = false;
             this.selectedRule = {};
             this._refreshRules();
@@ -1445,7 +1467,7 @@ export function WebPublisherSettingsController(
         publisher.setTenant($scope.newRule.action.tenant);
         publisher
           .manageTenantRule(_.pick(newRule, updatedKeys), this.selectedRule.id)
-          .then(rule => {
+          .then((rule) => {
             this.rulePaneOpen = false;
             this.selectedRule = {};
             this._refreshRules();
@@ -1472,7 +1494,7 @@ export function WebPublisherSettingsController(
 
     sitesFilter(site) {
       return $scope.newRule.destinations.find(
-        destination => destination.code === site.code
+        (destination) => destination.code === site.code
       )
         ? false
         : true;
@@ -1498,7 +1520,7 @@ export function WebPublisherSettingsController(
 
     _loadThemes() {
       $scope.loading = true;
-      return publisher.getOrganizationThemes().then(response => {
+      return publisher.getOrganizationThemes().then((response) => {
         $scope.loading = false;
         $scope.organizationThemes = response._embedded._items;
       });
@@ -1514,11 +1536,11 @@ export function WebPublisherSettingsController(
       $scope.loading = true;
       return publisher
         .querySites()
-        .then(sites => {
+        .then((sites) => {
           // assigning theme to site
-          angular.forEach(sites, site => {
+          angular.forEach(sites, (site) => {
             site.theme = $scope.organizationThemes.find(
-              theme => site.theme_name == theme.name
+              (theme) => site.theme_name == theme.name
             );
           });
           $scope.sites = sites;
@@ -1527,7 +1549,7 @@ export function WebPublisherSettingsController(
             this.toggleInfoCarousel();
           }
         })
-        .catch(err => {
+        .catch((err) => {
           $scope.loading = false;
           notify.error("Couldn't get list of tenants. Try again");
         });
@@ -1540,22 +1562,22 @@ export function WebPublisherSettingsController(
      * @description Loads theme settings
      */
     _refreshThemeSettings() {
-      return publisher.getThemeSettings().then(settings => {
+      return publisher.getThemeSettings().then((settings) => {
         this.themeSettings = {};
         this.themeSettings.theme_logo = _.find(settings, {
-          name: "theme_logo"
+          name: "theme_logo",
         });
         this.themeSettings.theme_logo_second = _.find(settings, {
-          name: "theme_logo_second"
+          name: "theme_logo_second",
         });
         this.themeSettings.theme_logo_third = _.find(settings, {
-          name: "theme_logo_third"
+          name: "theme_logo_third",
         });
-        _.remove(settings, setting => {
+        _.remove(settings, (setting) => {
           return setting.name.includes("theme_logo") ? true : false;
         });
         // little hack to make ng-select work properly
-        this.themeSettings.settings = settings.map(setting => {
+        this.themeSettings.settings = settings.map((setting) => {
           if (setting.options) {
             setting.value = setting.value.toString();
           }
@@ -1584,10 +1606,12 @@ export function WebPublisherSettingsController(
      * @description Loads Organization Rules
      */
     _loadOrganizationRules() {
-      return publisher.queryOrganizationRules({ limit: 99999 }).then(rules => {
-        this.organizationRules = rules;
-        return rules;
-      });
+      return publisher
+        .queryOrganizationRules({ limit: 99999 })
+        .then((rules) => {
+          this.organizationRules = rules;
+          return rules;
+        });
     }
 
     /**
@@ -1599,8 +1623,8 @@ export function WebPublisherSettingsController(
       this.tenantsRules = {};
       // tenants configured with organization rules
       this.availableTenants = [];
-      _.each(this.organizationRules, rule => {
-        _.each(rule.configuration.destinations, dest => {
+      _.each(this.organizationRules, (rule) => {
+        _.each(rule.configuration.destinations, (dest) => {
           let tenant = this.sites.find(function (site) {
             return site.code == dest.tenant;
           });
@@ -1608,7 +1632,7 @@ export function WebPublisherSettingsController(
           if (tenant) {
             publisher.setTenant(tenant);
             this.availableTenants.push(tenant);
-            this._loadTenantRules().then(rules => {
+            this._loadTenantRules().then((rules) => {
               this.tenantsRules[tenant.code] = rules;
             });
           }
@@ -1622,16 +1646,16 @@ export function WebPublisherSettingsController(
      * @description Loads Tenant Rules
      */
     _loadTenantRules() {
-      return publisher.queryTenantRules({ limit: 99999 }).then(rules => {
+      return publisher.queryTenantRules({ limit: 99999 }).then((rules) => {
         return rules;
       });
     }
 
     /**
-    * @ngdoc method
-    * @name WebPublisherSettingsController#_loadIngestSources
-    * @description Loads ingest sources
-    */
+     * @ngdoc method
+     * @name WebPublisherSettingsController#_loadIngestSources
+     * @description Loads ingest sources
+     */
     _loadIngestSources = (page = 1) => {
       api.ingestProviders
         .query({ max_results: 200, page: page })
@@ -1639,12 +1663,10 @@ export function WebPublisherSettingsController(
           let ingestSources = response._items;
 
           if (ingestSources.length) {
-            this.ingestSources = [...this.ingestSources, ...ingestSources]
+            this.ingestSources = [...this.ingestSources, ...ingestSources];
           }
 
           if (response._links.next) this._loadIngestSources(page + 1);
-
-
         });
     };
 
@@ -1658,18 +1680,24 @@ export function WebPublisherSettingsController(
 
       this.expressionBuilder = {
         operators: {
-          string: [{ name: "=", value: "==" }, { name: "!=", value: "!=" }],
+          string: [
+            { name: "=", value: "==" },
+            { name: "!=", value: "!=" },
+          ],
           number: [
             { name: "=", value: "==" },
             { name: "!=", value: "!=" },
             { name: "<", value: "<" },
             { name: ">", value: ">" },
             { name: "<=", value: "<=" },
-            { name: ">=", value: ">=" }
+            { name: ">=", value: ">=" },
           ],
           in: [{ name: "=", value: "in" }],
-          custom: [{ name: "=", value: "==" }, { name: "!=", value: "!=" }]
-        }
+          custom: [
+            { name: "=", value: "==" },
+            { name: "!=", value: "!=" },
+          ],
+        },
       };
 
       if ($scope.newRule.type == "organization") {
@@ -1680,10 +1708,10 @@ export function WebPublisherSettingsController(
           {
             name: "Ingest Source",
             value: "package.getSource()",
-            type: "string"
+            type: "string",
           },
           { name: "Priority", value: "package.getPriority()", type: "number" },
-          { name: "Urgency", value: "package.getUrgency()", type: "number" }
+          { name: "Urgency", value: "package.getUrgency()", type: "number" },
         ];
       } else {
         // article
@@ -1694,29 +1722,29 @@ export function WebPublisherSettingsController(
           {
             name: "Category",
             value: "article.getPackage().getServicesNames()",
-            type: "in"
+            type: "in",
           },
           { name: "Author", value: "article.getAuthorsNames()", type: "in" },
           {
             name: "Ingest Source",
             value: "article.getPackage().getSource()",
-            type: "string"
+            type: "string",
           },
           {
             name: "Priority",
             value: "article.getPackage().getPriority()",
-            type: "number"
+            type: "number",
           },
           {
             name: "Urgency",
             value: "article.getPackage().getUrgency()",
-            type: "number"
-          }
+            type: "number",
+          },
         ];
       }
 
-      vocabularies.getAllActiveVocabularies().then(result => {
-        result.forEach(vocabulary => {
+      vocabularies.getAllActiveVocabularies().then((result) => {
+        result.forEach((vocabulary) => {
           if (vocabulary._id === "categories") {
             this.expressionBuilder.categories = vocabulary.items;
           }
@@ -1725,7 +1753,7 @@ export function WebPublisherSettingsController(
               name: vocabulary.display_name,
               value:
                 customRuleFunctionName + "['" + vocabulary.display_name + "']",
-              type: "custom"
+              type: "custom",
             });
           }
         });
diff --git a/client/directives/siteWizard/SiteWizardDirective.js b/client/directives/siteWizard/SiteWizardDirective.js
index 3c483493..edab1da7 100644
--- a/client/directives/siteWizard/SiteWizardDirective.js
+++ b/client/directives/siteWizard/SiteWizardDirective.js
@@ -12,7 +12,7 @@ export function SiteWizardDirective(publisher, WizardHandler) {
       this.scope = {
         active: "=active",
         managerController: "=managerController",
-        outputChannelType: "=outputChannelType"
+        outputChannelType: "=outputChannelType",
       };
       this.template = require("./wizard.html");
     }
@@ -28,18 +28,24 @@ export function SiteWizardDirective(publisher, WizardHandler) {
           busy: false,
           errorMessage: null,
           site: null,
-          ready: false
+          ready: false,
         };
         scope.newSite = {};
 
         if (scope.outputChannelType) {
-          scope.newSite.output_channel = {
-            type: scope.output_channelType.toLowerCase(),
-            config: {
+          if (scope.outputChannelType === "PWA") {
+            scope.newSite.pwa_config = {
               url: "",
-              authorization_key: ""
-            }
-          };
+            };
+          } else {
+            scope.newSite.output_channel = {
+              type: scope.outputChannelType.toLowerCase(),
+              config: {
+                url: "",
+                authorization_key: "",
+              },
+            };
+          }
         }
       };
 
@@ -69,7 +75,7 @@ export function SiteWizardDirective(publisher, WizardHandler) {
         scope.wizard.busy = true;
         let newUrl = scope.newSite.subdomain + "." + scope.newSite.domain_name;
 
-        publisher.checkIfPublisher(newUrl).then(isPublisher => {
+        publisher.checkIfPublisher(newUrl).then((isPublisher) => {
           if (!isPublisher) {
             scope.wizard.busy = false;
             scope.wizard.errorMessage =
@@ -79,7 +85,7 @@ export function SiteWizardDirective(publisher, WizardHandler) {
 
           publisher
             .manageSite(scope.newSite)
-            .then(site => {
+            .then((site) => {
               scope.wizard.errorMessage = false;
               scope.wizard.site = site;
               publisher.setTenant(site);
@@ -91,7 +97,7 @@ export function SiteWizardDirective(publisher, WizardHandler) {
                 WizardHandler.wizard("siteWizard").next();
               }
             })
-            .catch(error => {
+            .catch((error) => {
               scope.wizard.busy = false;
               if (error.status === 409) {
                 scope.wizard.errorMessage = "Site already exists";
diff --git a/client/directives/siteWizard/wizard.html b/client/directives/siteWizard/wizard.html
index 19ebfe3d..2e787b1a 100644
--- a/client/directives/siteWizard/wizard.html
+++ b/client/directives/siteWizard/wizard.html
@@ -6,11 +6,8 @@
     <h3 class="modal__heading" translate>
       Create Site Wizard
       <span ng-if="newSite.output_channel"
-        >-
-        {{
-          newSite.output_channel.type.charAt(0).toUpperCase() +
-            newSite.output_channel.type.slice(1)
-        }}</span
+        >- {{ newSite.output_channel.type.charAt(0).toUpperCase() +
+        newSite.output_channel.type.slice(1) }}</span
       >
     </h3>
   </div>
@@ -36,7 +33,10 @@ <h3 class="modal__heading" translate>
           {{ wizard.errorMessage }}
         </div>
         <fieldset>
-          <div ng-if="newSite.output_channel" class="form__row form__row--flex">
+          <div
+            ng-if="newSite.output_channel || newSite.pwa_config"
+            class="form__row form__row--flex"
+          >
             <h4 class="text--light text--thin text--uppercase">
               Superdesk Publisher tenant settings
             </h4>
@@ -101,9 +101,9 @@ <h4 class="text--light text--thin text--uppercase">
           >
             <div class="form__row-item">
               <div class="sd-line-input sd-line-input--required">
-                <label class="sd-line-input__label" translate>{{
-                  name.replace("_", " ")
-                }}</label>
+                <label class="sd-line-input__label" translate
+                  >{{ name.replace("_", " ") }}</label
+                >
                 <input
                   class="sd-line-input__input"
                   type="text"
@@ -113,6 +113,30 @@ <h4 class="text--light text--thin text--uppercase">
               </div>
             </div>
           </div>
+
+          <div ng-if="newSite.pwa_config" class="form__row form__row--flex">
+            <h4 class="text--light text--thin text--uppercase">PWA settings</h4>
+          </div>
+          <div
+            class="form__row form__row--flex"
+            ng-if="newSite.pwa_config"
+            ng-repeat="(name, value) in newSite.pwa_config"
+          >
+            <div class="form__row-item">
+              <div class="sd-line-input sd-line-input--required">
+                <label class="sd-line-input__label" translate
+                  >{{ name.replace("_", " ") }}</label
+                >
+                <input
+                  class="sd-line-input__input"
+                  type="text"
+                  ng-model="newSite.pwa_config[name]"
+                  placeholder="{{name === 'url' ? 'https://website.com' : null}}"
+                  required
+                />
+              </div>
+            </div>
+          </div>
         </fieldset>
       </form>
 
@@ -157,7 +181,7 @@ <h4 class="text--light text--thin text--uppercase">
           Configure your site
         </button>
         <button
-          class="btn btn--hollow  btn--primary"
+          class="btn btn--hollow btn--primary"
           ng-disabled="!wizard.ready"
           ng-click="managerController.toggleSiteWizard()"
         >
diff --git a/client/images/PWA_logo.svg b/client/images/PWA_logo.svg
new file mode 100644
index 00000000..d931c172
--- /dev/null
+++ b/client/images/PWA_logo.svg
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg width="100%" height="100%" viewBox="0 0 978 388" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
+    <g transform="matrix(7.83465,0,0,7.83465,-398.586,-488.321)">
+        <path d="M142.662,103.442L146.265,94.331L156.668,94.331L151.73,80.51L157.905,64.896L175.59,111.852L162.548,111.852L159.526,103.442L142.662,103.442Z" style="fill-opacity:0.91;fill-rule:nonzero;"/>
+    </g>
+    <g transform="matrix(7.83465,0,0,7.83465,-398.586,-488.321)">
+        <path d="M131.535,109.284L150.467,62.328L137.916,62.329L124.965,92.673L115.755,62.329L106.108,62.329L96.22,92.673L89.246,78.845L82.935,98.288L89.343,109.284L101.695,109.284L110.631,82.072L119.15,109.284L131.535,109.284Z" style="fill-opacity:0.91;fill-rule:nonzero;" fill="#3d8fb1"/>
+    </g>
+    <g transform="matrix(7.83465,0,0,7.83465,-398.586,-488.321)">
+        <path d="M62.789,93.166L70.52,93.166C72.862,93.166 74.947,92.905 76.776,92.382L78.775,86.223L84.363,69.007C83.938,68.333 83.452,67.694 82.905,67.093C80.036,63.917 75.838,62.33 70.312,62.33L50.875,62.33L50.875,109.286L62.789,109.286L62.789,93.166ZM73.022,73.132C74.143,74.26 74.703,75.77 74.703,77.66C74.703,79.566 74.21,81.077 73.225,82.194C72.144,83.435 70.155,84.056 67.257,84.056L62.789,84.056L62.789,71.441L67.29,71.441C69.991,71.441 71.902,72.004 73.022,73.132Z" style="fill-opacity:0.91;fill-rule:nonzero;"/>
+    </g>
+</svg>
diff --git a/client/styles/_publisher.scss b/client/styles/_publisher.scss
index 2ed6803b..78639e0c 100644
--- a/client/styles/_publisher.scss
+++ b/client/styles/_publisher.scss
@@ -23,10 +23,10 @@
 
 .modal--kindafullscreen {
   position: fixed;
-  left: 48px;
-  right: 0px;
-  top: 49px;
-  bottom: 32px;
+  left: 50px !important;
+  right: 0px !important;
+  top: 40px !important;
+  bottom: 25px !important;
   align-items: flex-start;
   flex-direction: column;
   overflow: hidden;
@@ -35,15 +35,15 @@
 }
 
 .modal--kindafullscreen .modal__dialog {
-  width: 100%;
-  height: 100%;
-  max-width: 100%;
+  width: 100% !important;
+  height: 100% !important;
+  max-width: 100% !important;
 }
 .modal--kindafullscreen .modal__content {
   margin: 0;
 }
 .modal--kindafullscreen .modal__content .modal__body {
-  max-width: 100%;
+  max-width: 100% !important;
 }
 
 .listLimitNotification {
diff --git a/client/styles/articlePreview.scss b/client/styles/articlePreview.scss
index 46e7a39a..3570d186 100644
--- a/client/styles/articlePreview.scss
+++ b/client/styles/articlePreview.scss
@@ -1,95 +1,129 @@
 .articlePreview {
-    display: flex;
-
-    &__iframe {
-        margin: auto;
-        width: 100%;
-        height: calc(100vh - 88px);
-        background-color: $white;
-        border: 1px solid #e0e0e0;
-        box-shadow: 0 0 12px rgba(0,0,0,0.1);
-
-        &--tablet {
-            width: 768px;
-            height: 1024px;
-        }
-
-        &--tabletLandscape {
-            width: 1024px;
-            height: 768px;
-        }
-
-        &--mobile {
-            width: 320px;
-            height: 640px;
-        }
-
-        &--mobileLandscape {
-            width: 640px;
-            height: 320px;
-        }
-    }
-}
+  display: flex;
 
-.previewIcon {
-    display: inline-block;
-    background-position: bottom center;
-    background-repeat: no-repeat;
-    height: 32px;
-    width: 32px;
-    opacity: 0.25;
-
-    &--desktop {
-        background-image: url(../images/icon-desktop.svg);
-    }
+  &__iframe {
+    margin: auto;
+    width: 100%;
+    height: calc(100vh - 88px);
+    background-color: $white;
+    border: 1px solid #e0e0e0;
+    box-shadow: 0 0 12px rgba(0, 0, 0, 0.1);
 
     &--tablet {
-        background-image: url(../images/icon-tablet.svg);
-        width: 26px;
-        margin-left: 15px;
+      width: 768px;
+      height: 1024px;
     }
 
     &--tabletLandscape {
-        background-image: url(../images/icon-tablet-lands.svg);
+      width: 1024px;
+      height: 768px;
     }
 
     &--mobile {
-        background-image: url(../images/icon-mobile.svg);
-        width: 16px;
-        margin-left: 10px;
+      width: 320px;
+      height: 640px;
     }
 
     &--mobileLandscape {
-        background-image: url(../images/icon-mobile-lands.svg);
+      width: 640px;
+      height: 320px;
     }
+  }
+}
 
-    &--amp {
-        background-image: url(../images/icon-amp-port.svg);
-        margin-left: 10px;
-    }
+.previewIcon {
+  display: inline-block;
+  background-position: bottom center;
+  background-repeat: no-repeat;
+  height: 32px;
+  width: 32px;
+  opacity: 0.25;
 
-    &--ampLandscape {
-        background-image: url(../images/icon-amp-land.svg);
-    }
+  &--desktop {
+    background-image: url(../images/icon-desktop.svg);
+  }
 
-    &--active {
-        opacity: 0.8;
-    }
+  &--tablet {
+    background-image: url(../images/icon-tablet.svg);
+    width: 26px;
+    margin-left: 15px;
+  }
+
+  &--tabletLandscape {
+    background-image: url(../images/icon-tablet-lands.svg);
+  }
+
+  &--mobile {
+    background-image: url(../images/icon-mobile.svg);
+    width: 16px;
+    margin-left: 10px;
+  }
+
+  &--mobileLandscape {
+    background-image: url(../images/icon-mobile-lands.svg);
+  }
+
+  &--amp {
+    background-image: url(../images/icon-amp-port.svg);
+    margin-left: 10px;
+  }
+
+  &--ampLandscape {
+    background-image: url(../images/icon-amp-land.svg);
+  }
+
+  &--active {
+    opacity: 0.8;
+  }
 }
 
 // Font size fix
 .side-panel__content-block-text p {
-    font-size: 1.5rem;
-    line-height: 140%;
-    font-weight: 300;
-    word-wrap: break-word;
-    padding-bottom: 1rem;
+  font-size: 1.5rem;
+  line-height: 140%;
+  font-weight: 300;
+  word-wrap: break-word;
+  padding-bottom: 1rem;
 }
 // Side panel embed width
 .side-panel__content-block {
-    .embed-block {
-        iframe {
-            width: 100%;
-        }
+  .embed-block {
+    iframe {
+      width: 100%;
+    }
+  }
+}
+
+// typography stuff in preview pane
+.side-panel__content-block-text {
+  ul {
+    list-style-type: revert;
+    margin: revert;
+    padding: revert;
+  }
+
+  blockquote {
+    font-size: 14px;
+    line-height: 140%;
+    margin: 16px 0;
+    border-left: 3px solid rgba(160, 160, 160, 0.5);
+    padding: 4px 0 4px 14px;
+    font-style: italic;
+  }
+
+  table {
+    width: 100%;
+    border-collapse: collapse;
+    resize: both;
+    table-layout: auto;
+    border: 1px solid #dadada;
+    margin: 16px 0;
+
+    td {
+      border: 1px solid #dadada;
+      padding: 5px 8px;
+      font-size: 14px;
+      font-weight: 300;
     }
+  }
 }
diff --git a/client/styles/helperElements.scss b/client/styles/helperElements.scss
index f73f5dea..d9dfd0a3 100644
--- a/client/styles/helperElements.scss
+++ b/client/styles/helperElements.scss
@@ -8,6 +8,15 @@
     no-repeat;
 }
 
+.sp-logo-pwa {
+  display: block;
+  float: right;
+  margin-right: 1rem;
+  width: 50px;
+  height: 30px;
+  background: transparent url(../images/PWA_logo.svg) center center no-repeat;
+}
+
 .absPosition {
   position: absolute;
 
diff --git a/client/views/settings/website-management/manage-general.html b/client/views/settings/website-management/manage-general.html
index 277f2d27..759cb3cc 100644
--- a/client/views/settings/website-management/manage-general.html
+++ b/client/views/settings/website-management/manage-general.html
@@ -46,8 +46,7 @@
           class="dropdown__toggle line-input"
           ng-model="newSite.default_language"
           ng-options="lang.qcode as lang.name for lang in webPublisherSettings.languages"
-        >
-        </select>
+        ></select>
       </div>
     </div>
     <div class="form__row">
@@ -139,5 +138,26 @@ <h4 class="text--light text--uppercase">
         </div>
       </div>
     </div>
+    <div ng-if="newSite.pwa_config && newSite.pwa_config.url">
+      <div class="form__row">
+        <h4 class="text--light text--uppercase">PWA settings</h4>
+      </div>
+      <div class="form__row" ng-repeat="(name, value) in newSite.pwa_config">
+        <div class="form__row-item">
+          <div class="sd-line-input sd-line-input--required">
+            <label class="sd-line-input__label" translate
+              >{{name.replace('_', ' ')}}</label
+            >
+            <input
+              class="sd-line-input__input"
+              type="text"
+              ng-model="newSite.pwa_config[name]"
+              placeholder="{{name === 'url' ? 'https://website.com' : null}}"
+              required
+            />
+          </div>
+        </div>
+      </div>
+    </div>
   </form>
 </div>
diff --git a/client/views/settings/website-management/manage.html b/client/views/settings/website-management/manage.html
index 832a0988..c47c710c 100644
--- a/client/views/settings/website-management/manage.html
+++ b/client/views/settings/website-management/manage.html
@@ -11,7 +11,7 @@ <h3 class="subnav__page-title">{{webPublisherSettings.selectedSite.name}}</h3>
     <a
       class="btn btn--text-only"
       target="_blank"
-      ng-href="{{webPublisherSettings.selectedSite.subdomain ? 'http://' + webPublisherSettings.selectedSite.subdomain + '.' + webPublisherSettings.selectedSite.domain_name: 'http://' + webPublisherSettings.selectedSite.domain_name}}"
+      ng-href="{{webPublisherSettings.selectedSite.pwa_config && webPublisherSettings.selectedSite.pwa_config.url ? webPublisherSettings.selectedSite.pwa_config.url : webPublisherSettings.selectedSite.subdomain ? 'http://' + webPublisherSettings.selectedSite.subdomain + '.' + webPublisherSettings.selectedSite.domain_name: 'http://' + webPublisherSettings.selectedSite.domain_name}}"
     >
       <i class="icon-globe"></i> Open website
     </a>
diff --git a/client/views/settings/website-management/partials/routes-tree.html b/client/views/settings/website-management/partials/routes-tree.html
index 15b1a6f1..f162a269 100644
--- a/client/views/settings/website-management/partials/routes-tree.html
+++ b/client/views/settings/website-management/partials/routes-tree.html
@@ -26,14 +26,16 @@
   </div>
   <div class="listElement__right">
     <span
-      sd-tooltip="This route is redirected"
+      sd-tooltip="This route is redirected to {{route.redirect_route.route_target.name}}"
       flow="left"
-      ng-if="route.redirect"
-      ><i class="icon-random"></i
-    ></span>
+      ng-if="route.redirect_route"
+    >
+      <i class="icon-random"></i>
+    </span>
     <span sd-tooltip="Paywall secured" flow="left" ng-if="route.paywall_secured"
       ><i class="icon-paywall icon--orange icon--full-opacity"></i
     ></span>
+
     <div class="dropdown dropdown--align-right" dropdown>
       <button class="dropdown__toggle dropdown--toggle" dropdown__toggle>
         <i class="icon-dots-vertical"></i>
diff --git a/client/views/settings/website-management/partials/tenant.html b/client/views/settings/website-management/partials/tenant.html
index 3383eedf..89cdb9b2 100644
--- a/client/views/settings/website-management/partials/tenant.html
+++ b/client/views/settings/website-management/partials/tenant.html
@@ -2,7 +2,7 @@
   <h3 class="sd-grid-item-header__heading sd-overflow-ellipsis">
     <a
       target="_blank"
-      ng-href="{{site.output_channel ? site.output_channel.config.url : site.subdomain ? 'http://' + site.subdomain + '.' + site.domain_name: 'http://' + site.domain_name}}"
+      ng-href="{{site.pwa_config && site.pwa_config.url ? site.pwa_config.url: site.output_channel ? site.output_channel.config.url : site.subdomain ? 'http://' + site.subdomain + '.' + site.domain_name: 'http://' + site.domain_name}}"
       flow="down"
     >
       <span>{{ site.name }}</span><i class="icon-external"></i>
@@ -28,17 +28,27 @@ <h3 class="sd-grid-item-header__heading sd-overflow-ellipsis">
 </div>
 <div class="sd-card sd-card--flex-grow">
   <div class="dashboard-content-header sd-shadow--z1">
-    <div class="dashboard-thumbnail-block">
+    <div
+      class="dashboard-thumbnail-block"
+      ng-if="site.pwa_config && site.pwa_config.url"
+    >
+      <span class="sp-logo-pwa" style="width: 100px; height: 62px"></span>
+    </div>
+    <div
+      class="dashboard-thumbnail-block"
+      ng-if="!site.pwa_config || !site.pwa_config.url"
+    >
       <div class="dashboard-thumbnail-block__image">
         <img
           ng-if="!site.theme.screenshots[0] || !site.theme.screenshots[0].url"
           src="../../../../directives/themeManager/no-theme-preview.png"
-          style="max-width:140px; max-height: 60px"
+          style="max-width: 140px; max-height: 60px"
         />
+
         <img
           ng-if="site.theme.screenshots[0] && site.theme.screenshots[0].url"
           ng-src="{{site.theme.screenshots[0].url}}"
-          style="max-width:140px; max-height: 60px"
+          style="max-width: 140px; max-height: 60px"
         />
       </div>
       <div class="dashboard-thumbnail-block__meta">
diff --git a/client/views/settings/website-management/route-form.html b/client/views/settings/website-management/route-form.html
index a02e43cf..691d5a87 100644
--- a/client/views/settings/website-management/route-form.html
+++ b/client/views/settings/website-management/route-form.html
@@ -22,10 +22,11 @@
 
 <div class="side-panel__content">
   <div class="side-panel__content-block">
-    <div class="sd-alert sd-alert--hollow" ng-if="newRoute.redirect">
+    <div class="sd-alert sd-alert--hollow" ng-if="newRoute.redirect_route">
       <Icon name="random" />
       <p className="sd-margin-l--1">
-        This Route has redirect set to another Route. Details on:
+        This Route has redirect set to
+        {{newRoute.redirect_route.route_target.name}}. Details on:
         <a
           className="text-link"
           href=""
@@ -89,7 +90,7 @@
             id="routeParent"
             class="dropdown__toggle line-input"
             ng-model="newRoute.parent"
-            ng-options="route.id as route.name for route in routes.children | filter: {id: newRoute.id ? '!' + newRoute.id : ''}"
+            ng-options="route.id as route.name for route in routes_flat | filter: {id: newRoute.id ? '!' + newRoute.id : ''}"
           >
             <option value=""></option>
           </select>
diff --git a/client/views/settings/website-management/tenant-list.html b/client/views/settings/website-management/tenant-list.html
index cb44ed4c..e49efd54 100644
--- a/client/views/settings/website-management/tenant-list.html
+++ b/client/views/settings/website-management/tenant-list.html
@@ -21,6 +21,11 @@ <h2 class="sd-page__page-heading sd-margin-r--5">Website Management</h2>
           Superdesk Publisher
         </button>
       </li>
+      <li>
+        <button ng-click="webPublisherSettings.toggleSiteWizard('PWA')">
+          PWA
+        </button>
+      </li>
       <li>
         <button ng-click="webPublisherSettings.toggleSiteWizard('Wordpress')">
           Wordpress
@@ -33,7 +38,7 @@ <h2 class="sd-page__page-heading sd-margin-r--5">Website Management</h2>
   <div class="sd-loader" ng-if="loading"></div>
   <a
     class="btn btn--sd-green btn--icon-only-circle btn--large sd-shadow--z4 fixedPosition fixedPosition--bottomRight"
-    style="z-index:1"
+    style="z-index: 1"
     ng-click="webPublisherSettings.toggleInfoCarousel()"
     ><i class="icon-info-large"></i
   ></a>
diff --git a/package.json b/package.json
index e71ed21a..4948f1cf 100644
--- a/package.json
+++ b/package.json
@@ -42,8 +42,10 @@
     "react-beautiful-dnd": "^13.0.0",
     "react-infinite-scroll-component": "^5.0.4",
     "react-select": "^3.0.4",
+    "react": "16.9.0",
+    "react-dom": "16.9.0",
     "react-virtualized": "^9.22.2",
-    "superdesk-ui-framework": "^2.3.4"
+    "superdesk-ui-framework": "^2.3.8"
   },
   "devDependencies": {
     "@babel/plugin-proposal-class-properties": "^7.4.4",
@@ -61,7 +63,7 @@
     "jest-dom": "^3.4.0",
     "jest-transform-css": "^2.0.0",
     "superdesk-code-style": "^1.0.0",
-    "superdesk-core": "superdesk/superdesk-client-core#9242566",
+    "superdesk-core": "superdesk/superdesk-client-core",
     "wait-for-expect": "^1.2.0"
   }
 }


Test patch:
diff --git a/client/__tests__/components/Analytics/FiltersPanel.js b/client/__tests__/components/Analytics/FiltersPanel.js
index 18dba15c..648b68c2 100644
--- a/client/__tests__/components/Analytics/FiltersPanel.js
+++ b/client/__tests__/components/Analytics/FiltersPanel.js
@@ -2,10 +2,10 @@ import React from "react";
 import FiltersPanel from "../../../components/Analytics/FiltersPanel";
 import { render, fireEvent } from "@testing-library/react";
 
-let api = () => { };
+let api = () => {};
 
 jest.mock("../../../components/UI/MultiSelect", () => () => {
-  return (<div></div>)
+  return <div></div>;
 });
 
 api.users = {};
@@ -13,7 +13,7 @@ api.users.query = function () {
   return new Promise((resolve, reject) => {
     resolve({
       _items: [{ is_author: true, display_name: "author" }],
-      _links: {}
+      _links: {},
     });
   });
 };
@@ -22,14 +22,14 @@ describe("Analytics/FiltersPanel", () => {
   const filters = {
     route: 1,
     published_after: "2019-07-04",
-    published_before: "2019-07-04"
+    published_before: "2019-07-04",
   };
 
   const routes = [
     {
       id: 1,
-      name: "testroute"
-    }
+      name: "testroute",
+    },
   ];
 
   it("renders correctly", () => {
@@ -59,7 +59,7 @@ describe("Analytics/FiltersPanel", () => {
       />
     );
 
-    const button = container.querySelector(".side-panel__close a");
+    const button = container.querySelector(".side-panel__close button");
 
     fireEvent.click(button);
     expect(toggle).toHaveBeenCalled();
diff --git a/client/__tests__/components/Analytics/__snapshots__/Analytics.js.snap b/client/__tests__/components/Analytics/__snapshots__/Analytics.js.snap
index c4398107..d61647ab 100644
--- a/client/__tests__/components/Analytics/__snapshots__/Analytics.js.snap
+++ b/client/__tests__/components/Analytics/__snapshots__/Analytics.js.snap
@@ -109,34 +109,48 @@ exports[`Analytics/Analytics renders correctly 1`] = `
             <div
               class="sd-check-button__group sd-check-button__group--left"
             >
-              <input
-                class="visuallyhidden"
-                id="id10"
-                type="checkbox"
-              />
               <span
-                class="sd-check-button checked"
+                class="sd-check-button sd-check-button--native"
+                tabindex="-1"
               >
+                <input
+                  class="sd-check-button__input"
+                  id="id10"
+                  name="id1"
+                  tabindex="0"
+                  type="radio"
+                />
                 <label
                   class="sd-check-button__text-label"
                   for="id10"
                 >
-                  Analytics
+                  <span
+                    class="sd-check-button__text-label-inner"
+                  >
+                    Analytics
+                  </span>
                 </label>
               </span>
-              <input
-                class="visuallyhidden"
-                id="id11"
-                type="checkbox"
-              />
               <span
-                class="sd-check-button"
+                class="sd-check-button sd-check-button--native"
+                tabindex="-1"
               >
+                <input
+                  class="sd-check-button__input"
+                  id="id11"
+                  name="id1"
+                  tabindex="0"
+                  type="radio"
+                />
                 <label
                   class="sd-check-button__text-label"
                   for="id11"
                 >
-                  Reports History
+                  <span
+                    class="sd-check-button__text-label-inner"
+                  >
+                    Reports History
+                  </span>
                 </label>
               </span>
             </div>
@@ -173,15 +187,16 @@ exports[`Analytics/Analytics renders correctly 1`] = `
                 </li>
               </ul>
             </div>
-            <a
+            <button
               class="icn-btn"
+              tabindex="0"
             >
               <i
                 aria-hidden="true"
                 aria-label="descending"
                 class="icon-descending"
               />
-            </a>
+            </button>
           </div>
         </div>
         <div
@@ -199,15 +214,16 @@ exports[`Analytics/Analytics renders correctly 1`] = `
                 <span
                   class="side-panel__close"
                 >
-                  <a
+                  <button
                     class="icn-btn"
+                    tabindex="0"
                   >
                     <i
                       aria-hidden="true"
                       aria-label="close-small"
                       class="icon-close-small"
                     />
-                  </a>
+                  </button>
                 </span>
                 <h3
                   class="side-panel__heading side-panel__heading--big"
@@ -447,12 +463,14 @@ exports[`Analytics/Analytics renders correctly 1`] = `
                   <button
                     aria-label=""
                     class="btn btn--hollow"
+                    tabindex="0"
                   >
                     Clear
                   </button>
                   <button
                     aria-label=""
                     class="btn btn--primary"
+                    tabindex="0"
                   >
                     Run Report
                   </button>
@@ -465,6 +483,7 @@ exports[`Analytics/Analytics renders correctly 1`] = `
                   <button
                     aria-label=""
                     class="btn btn--primary btn--disabled"
+                    tabindex="0"
                   >
                     Generate Report
                   </button>
diff --git a/client/__tests__/components/Analytics/__snapshots__/FiltersPanel.js.snap b/client/__tests__/components/Analytics/__snapshots__/FiltersPanel.js.snap
index bb7954df..fd06f76d 100644
--- a/client/__tests__/components/Analytics/__snapshots__/FiltersPanel.js.snap
+++ b/client/__tests__/components/Analytics/__snapshots__/FiltersPanel.js.snap
@@ -13,15 +13,16 @@ exports[`Analytics/FiltersPanel renders correctly 1`] = `
       <span
         class="side-panel__close"
       >
-        <a
+        <button
           class="icn-btn"
+          tabindex="0"
         >
           <i
             aria-hidden="true"
             aria-label="close-small"
             class="icon-close-small"
           />
-        </a>
+        </button>
       </span>
       <h3
         class="side-panel__heading side-panel__heading--big"
@@ -275,12 +276,14 @@ exports[`Analytics/FiltersPanel renders correctly 1`] = `
         <button
           aria-label=""
           class="btn btn--hollow"
+          tabindex="0"
         >
           Clear
         </button>
         <button
           aria-label=""
           class="btn btn--primary"
+          tabindex="0"
         >
           Run Report
         </button>
@@ -292,6 +295,7 @@ exports[`Analytics/FiltersPanel renders correctly 1`] = `
         <button
           aria-label=""
           class="btn btn--primary"
+          tabindex="0"
         >
           Generate Report
         </button>
diff --git a/client/__tests__/components/ContentLists/Automatic/__snapshots__/Automatic.js.snap b/client/__tests__/components/ContentLists/Automatic/__snapshots__/Automatic.js.snap
index efbd6ef7..9091a3a8 100644
--- a/client/__tests__/components/ContentLists/Automatic/__snapshots__/Automatic.js.snap
+++ b/client/__tests__/components/ContentLists/Automatic/__snapshots__/Automatic.js.snap
@@ -75,15 +75,16 @@ exports[`ContentLists/Automatic/Automatic renders properly 1`] = `
             <span
               class="side-panel__close"
             >
-              <a
+              <button
                 class="icn-btn"
+                tabindex="0"
               >
                 <i
                   aria-hidden="true"
                   aria-label="close-small"
                   class="icon-close-small"
                 />
-              </a>
+              </button>
             </span>
             <h3
               class="side-panel__heading side-panel__heading--big"
@@ -338,12 +339,14 @@ exports[`ContentLists/Automatic/Automatic renders properly 1`] = `
               <button
                 aria-label=""
                 class="btn btn--hollow"
+                tabindex="0"
               >
                 Clear
               </button>
               <button
                 aria-label=""
                 class="btn btn--primary"
+                tabindex="0"
               >
                 Update Criteria
               </button>
diff --git a/client/__tests__/components/ContentLists/Automatic/__snapshots__/FilterPanel.js.snap b/client/__tests__/components/ContentLists/Automatic/__snapshots__/FilterPanel.js.snap
index 898a78e3..d20fbdd8 100644
--- a/client/__tests__/components/ContentLists/Automatic/__snapshots__/FilterPanel.js.snap
+++ b/client/__tests__/components/ContentLists/Automatic/__snapshots__/FilterPanel.js.snap
@@ -16,15 +16,16 @@ exports[`ContentLists/Automatic/FilterPanel renders properly 1`] = `
       <span
         class="side-panel__close"
       >
-        <a
+        <button
           class="icn-btn"
+          tabindex="0"
         >
           <i
             aria-hidden="true"
             aria-label="close-small"
             class="icon-close-small"
           />
-        </a>
+        </button>
       </span>
       <h3
         class="side-panel__heading side-panel__heading--big"
@@ -293,12 +294,14 @@ exports[`ContentLists/Automatic/FilterPanel renders properly 1`] = `
         <button
           aria-label=""
           class="btn btn--hollow"
+          tabindex="0"
         >
           Clear
         </button>
         <button
           aria-label=""
           class="btn btn--primary"
+          tabindex="0"
         >
           Update Criteria
         </button>
diff --git a/client/__tests__/components/ContentLists/Listing.js b/client/__tests__/components/ContentLists/Listing.js
index 1bc947b1..68d393af 100644
--- a/client/__tests__/components/ContentLists/Listing.js
+++ b/client/__tests__/components/ContentLists/Listing.js
@@ -6,10 +6,10 @@ import Publisher from "../../../__mocks__/publisher";
 
 const publisher = new Publisher();
 
-jest.mock('moment', () => () => ({ fromNow: () => '2 days ago' }));
+jest.mock("moment", () => () => ({ fromNow: () => "2 days ago" }));
 
 let lists = [];
-publisher.queryLists().then(items => (lists = items));
+publisher.queryLists().then((items) => (lists = items));
 
 describe("ContentLists/Listing", () => {
   it("renders correctly", async () => {
@@ -18,6 +18,8 @@ describe("ContentLists/Listing", () => {
         publisher={publisher}
         lists={lists}
         onListDelete={jest.fn()}
+        onListCreated={jest.fn()}
+        onListUpdate={jest.fn()}
         addList={jest.fn()}
         listEdit={jest.fn()}
       />
@@ -33,6 +35,8 @@ describe("ContentLists/Listing", () => {
         publisher={publisher}
         lists={lists}
         onListDelete={jest.fn()}
+        onListCreated={jest.fn()}
+        onListUpdate={jest.fn()}
         addList={addList}
         listEdit={jest.fn()}
       />
diff --git a/client/__tests__/components/ContentLists/Manual/__snapshots__/FilterPanel.js.snap b/client/__tests__/components/ContentLists/Manual/__snapshots__/FilterPanel.js.snap
index ff7d596b..a5286ef4 100644
--- a/client/__tests__/components/ContentLists/Manual/__snapshots__/FilterPanel.js.snap
+++ b/client/__tests__/components/ContentLists/Manual/__snapshots__/FilterPanel.js.snap
@@ -13,15 +13,16 @@ exports[`ContentLists/Manual/FilterPanel renders properly 1`] = `
       <span
         class="side-panel__close"
       >
-        <a
+        <button
           class="icn-btn"
+          tabindex="0"
         >
           <i
             aria-hidden="true"
             aria-label="close-small"
             class="icon-close-small"
           />
-        </a>
+        </button>
       </span>
       <h3
         class="side-panel__heading"
@@ -209,12 +210,14 @@ exports[`ContentLists/Manual/FilterPanel renders properly 1`] = `
         <button
           aria-label=""
           class="btn btn--hollow"
+          tabindex="0"
         >
           Clear
         </button>
         <button
           aria-label=""
           class="btn btn--primary"
+          tabindex="0"
         >
           Filter
         </button>
diff --git a/client/__tests__/components/ContentLists/Manual/__snapshots__/Manual.js.snap b/client/__tests__/components/ContentLists/Manual/__snapshots__/Manual.js.snap
index 2bc7a928..27633210 100644
--- a/client/__tests__/components/ContentLists/Manual/__snapshots__/Manual.js.snap
+++ b/client/__tests__/components/ContentLists/Manual/__snapshots__/Manual.js.snap
@@ -83,6 +83,7 @@ exports[`ContentLists/Manual/Manual renders properly 1`] = `
         <button
           aria-label=""
           class="btn btn--primary btn--disabled"
+          tabindex="0"
         >
           Save
         </button>
@@ -267,15 +268,16 @@ exports[`ContentLists/Manual/Manual renders properly 1`] = `
             <span
               class="side-panel__close"
             >
-              <a
+              <button
                 class="icn-btn"
+                tabindex="0"
               >
                 <i
                   aria-hidden="true"
                   aria-label="close-small"
                   class="icon-close-small"
                 />
-              </a>
+              </button>
             </span>
             <h3
               class="side-panel__heading"
@@ -449,12 +451,14 @@ exports[`ContentLists/Manual/Manual renders properly 1`] = `
               <button
                 aria-label=""
                 class="btn btn--hollow"
+                tabindex="0"
               >
                 Clear
               </button>
               <button
                 aria-label=""
                 class="btn btn--primary"
+                tabindex="0"
               >
                 Filter
               </button>
diff --git a/client/__tests__/components/ContentLists/__snapshots__/ContentLists.js.snap b/client/__tests__/components/ContentLists/__snapshots__/ContentLists.js.snap
index 834c4029..7cd6638d 100644
--- a/client/__tests__/components/ContentLists/__snapshots__/ContentLists.js.snap
+++ b/client/__tests__/components/ContentLists/__snapshots__/ContentLists.js.snap
@@ -122,49 +122,70 @@ exports[`ContentLists/ContentLists renders properly 1`] = `
           <div
             class="sd-check-button__group sd-check-button__group--left"
           >
-            <input
-              class="visuallyhidden"
-              id="id10"
-              type="checkbox"
-            />
             <span
-              class="sd-check-button checked"
+              class="sd-check-button sd-check-button--native"
+              tabindex="-1"
             >
+              <input
+                class="sd-check-button__input"
+                id="id10"
+                name="id1"
+                tabindex="0"
+                type="radio"
+              />
               <label
                 class="sd-check-button__text-label"
                 for="id10"
               >
-                All
+                <span
+                  class="sd-check-button__text-label-inner"
+                >
+                  All
+                </span>
               </label>
             </span>
-            <input
-              class="visuallyhidden"
-              id="id11"
-              type="checkbox"
-            />
             <span
-              class="sd-check-button"
+              class="sd-check-button sd-check-button--native"
+              tabindex="-1"
             >
+              <input
+                class="sd-check-button__input"
+                id="id11"
+                name="id1"
+                tabindex="0"
+                type="radio"
+              />
               <label
                 class="sd-check-button__text-label"
                 for="id11"
               >
-                Automatic
+                <span
+                  class="sd-check-button__text-label-inner"
+                >
+                  Automatic
+                </span>
               </label>
             </span>
-            <input
-              class="visuallyhidden"
-              id="id12"
-              type="checkbox"
-            />
             <span
-              class="sd-check-button"
+              class="sd-check-button sd-check-button--native"
+              tabindex="-1"
             >
+              <input
+                class="sd-check-button__input"
+                id="id12"
+                name="id1"
+                tabindex="0"
+                type="radio"
+              />
               <label
                 class="sd-check-button__text-label"
                 for="id12"
               >
-                Manual
+                <span
+                  class="sd-check-button__text-label-inner"
+                >
+                  Manual
+                </span>
               </label>
             </span>
           </div>
@@ -238,6 +259,7 @@ exports[`ContentLists/ContentLists renders properly 1`] = `
                 <button
                   aria-label=""
                   class="btn btn--small btn--hollow btn--ui-dark"
+                  tabindex="0"
                 >
                   Edit
                 </button>
@@ -345,6 +367,7 @@ exports[`ContentLists/ContentLists renders properly 1`] = `
                 <button
                   aria-label=""
                   class="btn btn--small btn--hollow btn--ui-dark"
+                  tabindex="0"
                 >
                   Edit
                 </button>
diff --git a/client/__tests__/components/ContentLists/__snapshots__/ListCard.js.snap b/client/__tests__/components/ContentLists/__snapshots__/ListCard.js.snap
index 44070444..d184a2c4 100644
--- a/client/__tests__/components/ContentLists/__snapshots__/ListCard.js.snap
+++ b/client/__tests__/components/ContentLists/__snapshots__/ListCard.js.snap
@@ -18,6 +18,7 @@ exports[`ContentLists/ListCard renders correctly 1`] = `
       <button
         aria-label=""
         class="btn btn--small btn--hollow btn--ui-dark"
+        tabindex="0"
       >
         Edit
       </button>
diff --git a/client/__tests__/components/ContentLists/__snapshots__/Listing.js.snap b/client/__tests__/components/ContentLists/__snapshots__/Listing.js.snap
index 08a99d8e..9f5db411 100644
--- a/client/__tests__/components/ContentLists/__snapshots__/Listing.js.snap
+++ b/client/__tests__/components/ContentLists/__snapshots__/Listing.js.snap
@@ -34,49 +34,70 @@ exports[`ContentLists/Listing renders correctly 1`] = `
       <div
         class="sd-check-button__group sd-check-button__group--left"
       >
-        <input
-          class="visuallyhidden"
-          id="id10"
-          type="checkbox"
-        />
         <span
-          class="sd-check-button checked"
+          class="sd-check-button sd-check-button--native"
+          tabindex="-1"
         >
+          <input
+            class="sd-check-button__input"
+            id="id10"
+            name="id1"
+            tabindex="0"
+            type="radio"
+          />
           <label
             class="sd-check-button__text-label"
             for="id10"
           >
-            All
+            <span
+              class="sd-check-button__text-label-inner"
+            >
+              All
+            </span>
           </label>
         </span>
-        <input
-          class="visuallyhidden"
-          id="id11"
-          type="checkbox"
-        />
         <span
-          class="sd-check-button"
+          class="sd-check-button sd-check-button--native"
+          tabindex="-1"
         >
+          <input
+            class="sd-check-button__input"
+            id="id11"
+            name="id1"
+            tabindex="0"
+            type="radio"
+          />
           <label
             class="sd-check-button__text-label"
             for="id11"
           >
-            Automatic
+            <span
+              class="sd-check-button__text-label-inner"
+            >
+              Automatic
+            </span>
           </label>
         </span>
-        <input
-          class="visuallyhidden"
-          id="id12"
-          type="checkbox"
-        />
         <span
-          class="sd-check-button"
+          class="sd-check-button sd-check-button--native"
+          tabindex="-1"
         >
+          <input
+            class="sd-check-button__input"
+            id="id12"
+            name="id1"
+            tabindex="0"
+            type="radio"
+          />
           <label
             class="sd-check-button__text-label"
             for="id12"
           >
-            Manual
+            <span
+              class="sd-check-button__text-label-inner"
+            >
+              Manual
+            </span>
           </label>
         </span>
       </div>
@@ -150,6 +171,7 @@ exports[`ContentLists/Listing renders correctly 1`] = `
             <button
               aria-label=""
               class="btn btn--small btn--hollow btn--ui-dark"
+              tabindex="0"
             >
               Edit
             </button>
@@ -257,6 +279,7 @@ exports[`ContentLists/Listing renders correctly 1`] = `
             <button
               aria-label=""
               class="btn btn--small btn--hollow btn--ui-dark"
+              tabindex="0"
             >
               Edit
             </button>
diff --git a/client/__tests__/components/Dashboard/Tenant.js b/client/__tests__/components/Dashboard/Tenant.js
index 8affb2ac..9310ae0e 100644
--- a/client/__tests__/components/Dashboard/Tenant.js
+++ b/client/__tests__/components/Dashboard/Tenant.js
@@ -11,39 +11,39 @@ let tenant = {
   theme_name: "swp/daily-theme",
   amp_enabled: true,
   output_channel: null,
+  pwa_config: { url: null },
   articles_count: 146,
-  routes: [{
-    id: 1,
-    type: "collection",
-    name: "sport",
-    slug: "sport"
-  },
-  {
-    id: 2,
-    type: "collection",
-    name: "business",
-    slug: "business"
-  }],
+  routes: [
+    {
+      id: 1,
+      type: "collection",
+      name: "sport",
+      slug: "sport",
+    },
+    {
+      id: 2,
+      type: "collection",
+      name: "business",
+      slug: "business",
+    },
+  ],
   fbia_enabled: false,
   paywall_enabled: false,
   content_lists: [
     {
       id: 7,
-      name: "Most shared"
+      name: "Most shared",
     },
     {
       id: 8,
-      name: "Most commented"
-    }
-  ]
+      name: "Most commented",
+    },
+  ],
 };
 
-
 describe("Dashboard/Tenant", () => {
   it("renders correctly", async () => {
-    const { container } = render(
-      <Tenant tenant={tenant} />
-    );
+    const { container } = render(<Tenant tenant={tenant} />);
     expect(container).toMatchSnapshot();
   });
 });
diff --git a/client/__tests__/components/Dashboard/__snapshots__/Dashboard.js.snap b/client/__tests__/components/Dashboard/__snapshots__/Dashboard.js.snap
index b9c87496..a6b4ecf6 100644
--- a/client/__tests__/components/Dashboard/__snapshots__/Dashboard.js.snap
+++ b/client/__tests__/components/Dashboard/__snapshots__/Dashboard.js.snap
@@ -31,7 +31,7 @@ exports[`Dashboard/Dashboard renders properly 1`] = `
             >
               <a
                 flow="down"
-                href="http://site1.sourcefabric.org"
+                href="https://site1.sourcefabric.org"
                 target="_blank"
               >
                 <span>
@@ -133,7 +133,7 @@ exports[`Dashboard/Dashboard renders properly 1`] = `
             >
               <a
                 flow="down"
-                href="http://site2.sourcefabric.org"
+                href="https://site2.sourcefabric.org"
                 target="_blank"
               >
                 <span>
diff --git a/client/__tests__/components/Dashboard/__snapshots__/Tenant.js.snap b/client/__tests__/components/Dashboard/__snapshots__/Tenant.js.snap
index 685ec463..72be4784 100644
--- a/client/__tests__/components/Dashboard/__snapshots__/Tenant.js.snap
+++ b/client/__tests__/components/Dashboard/__snapshots__/Tenant.js.snap
@@ -10,7 +10,7 @@ exports[`Dashboard/Tenant renders correctly 1`] = `
     >
       <a
         flow="down"
-        href="http://site1.sourcefabric.org"
+        href="https://site1.sourcefabric.org"
         target="_blank"
       >
         <span>
diff --git a/client/__tests__/components/Output/ArticleItem.js b/client/__tests__/components/Output/ArticleItem.js
index e5632a4e..530ecbce 100644
--- a/client/__tests__/components/Output/ArticleItem.js
+++ b/client/__tests__/components/Output/ArticleItem.js
@@ -1,72 +1,75 @@
 import React from "react";
 import ArticleItem from "../../../components/Output/ArticleItem";
-import { render, fireEvent, waitForElement, wait } from "@testing-library/react";
+import {
+  render,
+  fireEvent,
+  waitForElement,
+  wait,
+} from "@testing-library/react";
 import Store from "../../../components/Output/Store";
 
-jest.mock('moment', () => () => ({ fromNow: () => '1 day ago', format: () => '2020–01–01T12:00:00+00:00' }));
+jest.mock("moment", () => () => ({
+  fromNow: () => "1 day ago",
+  format: () => "2020–01–01T12:00:00+00:00",
+}));
 
 const item = {
-  "id": 686,
-  "guid": "urn:newsml:sp-api.superdesk.pro:2019-11-28T19:44:39.315852:9517b504-ac24-48dd-8649-6d28b9038122",
-  "headline": "Med test1.3",
-  "slugline": null,
-  "language": "en",
-  "type": "text",
-  "evolvedfrom": null,
-  "firstpublished": "2019-11-28T18:48:56+0000",
-  "extra_items": [],
-  "body_html": "<p>test</p>",
-  "feature_media": null,
-  "created_at": "2019-11-28T18:49:02+00:00",
-  "updated_at": "2019-11-28T18:53:11+00:00",
-  "articles": [
+  id: 686,
+  guid:
+    "urn:newsml:sp-api.superdesk.pro:2019-11-28T19:44:39.315852:9517b504-ac24-48dd-8649-6d28b9038122",
+  headline: "Med test1.3",
+  slugline: null,
+  language: "en",
+  type: "text",
+  evolvedfrom: null,
+  firstpublished: "2019-11-28T18:48:56+0000",
+  extra_items: [],
+  body_html: "<p>test</p>",
+  feature_media: null,
+  created_at: "2019-11-28T18:49:02+00:00",
+  updated_at: "2019-11-28T18:53:11+00:00",
+  articles: [
     {
-      "id": 2160,
-      "title": "Med test1.3",
-      "body": "<p>test</p>",
-      "slug": "med-test1-3-vw6o03mj",
-      "published_at": "2019-11-28T18:49:02+00:00",
-      "status": "published",
-      "route": "Object",
-      "lead": "Med test1.3",
-      "slideshows": [],
-      "created_at": "2019-11-28T18:49:02+00:00",
-      "updated_at": "2019-11-28T18:53:13+00:00",
-      "seo_metadata": null,
-      "feature_media": null,
-      "is_published_fbia": false,
-      "article_statistics": {
-        "impressions_number": 0,
-        "page_views_number": 4,
-        "internal_click_rate": 0
+      id: 2160,
+      title: "Med test1.3",
+      body: "<p>test</p>",
+      slug: "med-test1-3-vw6o03mj",
+      published_at: "2019-11-28T18:49:02+00:00",
+      status: "published",
+      route: "Object",
+      lead: "Med test1.3",
+      slideshows: [],
+      created_at: "2019-11-28T18:49:02+00:00",
+      updated_at: "2019-11-28T18:53:13+00:00",
+      seo_metadata: null,
+      feature_media: null,
+      is_published_fbia: false,
+      article_statistics: {
+        impressions_number: 0,
+        page_views_number: 4,
+        internal_click_rate: 0,
       },
-      "comments_count": 0,
-      "tenant": { domain_name: "sourcefabric.org" },
-      "_links": { online: { href: "/test" } },
-      "live_url": "http://sourcefabric.org/sports/med-test1-3-vw6o03mj"
-    }
+      comments_count: 0,
+      tenant: { domain_name: "sourcefabric.org" },
+      _links: { online: { href: "/test" } },
+      live_url: "http://sourcefabric.org/sports/med-test1-3-vw6o03mj",
+    },
   ],
-  "status": "published",
-  "comments_count": 0,
-  "page_views_count": 4
+  status: "published",
+  comments_count: 0,
+  page_views_count: 4,
 };
 
 describe("Output/ArticleItem", () => {
-
-
   it("renders correctly", () => {
     const { container } = render(
       <Store.Provider
         value={{
           publisher: {},
-          selectedItem: null
+          selectedItem: null,
         }}
       >
-        <ArticleItem
-          item={item}
-          style={{}}
-          onRemove={jest.fn()}
-        />
+        <ArticleItem item={item} style={{}} onRemove={jest.fn()} />
       </Store.Provider>
     );
     expect(container.firstChild).toMatchSnapshot();
@@ -79,27 +82,24 @@ describe("Output/ArticleItem", () => {
       <Store.Provider
         value={{
           publisher: {
-            removeArticle: () => new Promise((resolve) => {
-              resolve(true);
-            })
+            removeArticle: () =>
+              new Promise((resolve) => {
+                resolve(true);
+              }),
           },
           selectedItem: null,
-          selectedList: 'incoming'
+          selectedList: "incoming",
         }}
       >
-        <ArticleItem
-          item={item}
-          style={{}}
-          onRemove={onRemove}
-        />
+        <ArticleItem item={item} style={{}} onRemove={onRemove} />
       </Store.Provider>
     );
-    const removeIcon = container.querySelector('a.icn-btn .icon-trash').closest('a.icn-btn');
+    const removeIcon = container
+      .querySelector(".icn-btn .icon-trash")
+      .closest(".icn-btn");
     fireEvent.click(removeIcon);
 
-    const removeButton = await waitForElement(
-      () => getByText("Remove")
-    )
+    const removeButton = await waitForElement(() => getByText("Remove"));
     fireEvent.click(removeButton);
 
     await wait(() => {
diff --git a/client/__tests__/components/Output/PublishPane/Publish.js b/client/__tests__/components/Output/PublishPane/Publish.js
index ca9c81e2..7fc5ef2e 100644
--- a/client/__tests__/components/Output/PublishPane/Publish.js
+++ b/client/__tests__/components/Output/PublishPane/Publish.js
@@ -5,21 +5,23 @@ import Store from "../../../../components/Output/Store";
 
 const destinations = [
   {
-    status: "published", tenant: {
-      name: 'tenant1', code: 'tenant1',
+    status: "published",
+    tenant: {
+      name: "tenant1",
+      code: "tenant1",
       content_lists: [
-        { type: "manual", id: 1, name: 'list1', content_list_items_count: 10 },
-        { type: "automatic", id: 2, name: 'listAutomatic' },
-        { type: "manual", id: 3, name: 'list3', content_list_items_count: 2 },
-        { type: "manual", id: 4, name: 'list4', content_list_items_count: 0 }
-      ]
+        { type: "manual", id: 1, name: "list1", content_list_items_count: 10 },
+        { type: "automatic", id: 2, name: "listAutomatic" },
+        { type: "manual", id: 3, name: "list3", content_list_items_count: 2 },
+        { type: "manual", id: 4, name: "list4", content_list_items_count: 0 },
+      ],
     },
     route: { id: 1, name: "testroute1" },
     is_published_fbia: false,
     paywall_secured: false,
     status: "new",
-    content_lists: []
-  }
+    content_lists: [],
+  },
 ];
 
 describe("Output/PublishPane/Publish", () => {
@@ -28,31 +30,38 @@ describe("Output/PublishPane/Publish", () => {
       <Store.Provider
         value={{
           config: { publisher: {} },
-          publisher: { queryRelatedArticlesStatus: jest.fn().mockResolvedValue({ related_article_items: [] }) },
+          publisher: {
+            queryRelatedArticlesStatus: jest
+              .fn()
+              .mockResolvedValue({ related_article_items: [] }),
+          },
           selectedItem: { id: 1 },
           tenants: [
             {
-              name: 'tenant1', code: 'tenant1', paywall_enabled: true, fbia_enabled: false,
+              name: "tenant1",
+              code: "tenant1",
+              paywall_enabled: true,
+              fbia_enabled: false,
               routes: [
-                { name: 'testroute1', id: 1 },
-                { name: 'testroute2', id: 2 },
-              ]
+                { name: "testroute1", id: 1 },
+                { name: "testroute2", id: 2 },
+              ],
             },
             {
-              name: 'tenant2', code: 'tenant2', paywall_enabled: true, fbia_enabled: false,
+              name: "tenant2",
+              code: "tenant2",
+              paywall_enabled: true,
+              fbia_enabled: false,
               routes: [
-                { name: 'testroute1', id: 1 },
-                { name: 'testroute2', id: 2 },
+                { name: "testroute1", id: 1 },
+                { name: "testroute2", id: 2 },
               ],
-              content_lists: []
-            }
-          ]
+              content_lists: [],
+            },
+          ],
         }}
       >
-        <Publish
-          destinations={destinations}
-          openPreview={jest.fn()}
-        />
+        <Publish destinations={destinations} openPreview={jest.fn()} />
       </Store.Provider>
     );
 
@@ -66,31 +75,38 @@ describe("Output/PublishPane/Publish", () => {
       <Store.Provider
         value={{
           config: { publisher: {} },
-          publisher: { queryRelatedArticlesStatus: jest.fn().mockResolvedValue({ related_article_items: [] }) },
+          publisher: {
+            queryRelatedArticlesStatus: jest
+              .fn()
+              .mockResolvedValue({ related_article_items: [] }),
+          },
           selectedItem: { id: 1 },
           tenants: [
             {
-              name: 'tenant1', code: 'tenant1', paywall_enabled: true, fbia_enabled: false,
+              name: "tenant1",
+              code: "tenant1",
+              paywall_enabled: true,
+              fbia_enabled: false,
               routes: [
-                { name: 'testroute1', id: 1 },
-                { name: 'testroute2', id: 2 },
-              ]
+                { name: "testroute1", id: 1 },
+                { name: "testroute2", id: 2 },
+              ],
             },
             {
-              name: 'tenant2', code: 'tenant2', paywall_enabled: true, fbia_enabled: false,
+              name: "tenant2",
+              code: "tenant2",
+              paywall_enabled: true,
+              fbia_enabled: false,
               routes: [
-                { name: 'testroute1', id: 1 },
-                { name: 'testroute2', id: 2 },
+                { name: "testroute1", id: 1 },
+                { name: "testroute2", id: 2 },
               ],
-              content_lists: []
-            }
-          ]
+              content_lists: [],
+            },
+          ],
         }}
       >
-        <Publish
-          destinations={destinations}
-          openPreview={jest.fn()}
-        />
+        <Publish destinations={destinations} openPreview={jest.fn()} />
       </Store.Provider>
     );
 
@@ -98,20 +114,17 @@ describe("Output/PublishPane/Publish", () => {
     let plusButton = container.querySelector(".btn--icon-only-circle");
     fireEvent.click(plusButton);
 
-    const tenantButton = getByText('tenant2');
+    const tenantButton = getByText("tenant2");
     fireEvent.click(tenantButton);
 
-    expect(plusButton.classList.contains('btn--disabled')).toBe(true)
-
-
+    expect(plusButton.classList.contains("btn--disabled")).toBe(true);
 
     // removes destination and updates available tenants
-    const removeTenantButton = container.querySelector('a.icn-btn .icon-trash').closest('a.icn-btn');
-
+    const removeTenantButton = container
+      .querySelector(".icn-btn .icon-trash")
+      .closest(".icn-btn");
 
     fireEvent.click(removeTenantButton);
-    expect(plusButton.classList.contains('btn--disabled')).toBe(false)
+    expect(plusButton.classList.contains("btn--disabled")).toBe(false);
   });
 });
-
-
diff --git a/client/__tests__/components/Output/PublishPane/__snapshots__/ContentListPicker.js.snap b/client/__tests__/components/Output/PublishPane/__snapshots__/ContentListPicker.js.snap
index cdc6d5d2..4c29a4d1 100644
--- a/client/__tests__/components/Output/PublishPane/__snapshots__/ContentListPicker.js.snap
+++ b/client/__tests__/components/Output/PublishPane/__snapshots__/ContentListPicker.js.snap
@@ -40,15 +40,16 @@ exports[`Output/PublishPane/ContentListPicker renders properly 1`] = `
           </option>
         </select>
       </div>
-      <a
+      <button
         class="icn-btn"
+        tabindex="0"
       >
         <i
           aria-hidden="true"
           aria-label="trash"
           class="icon-trash"
         />
-      </a>
+      </button>
     </div>
     <div
       class="sd-list-item__row sd-margin-b--1"
diff --git a/client/__tests__/components/Output/PublishPane/__snapshots__/Destination.js.snap b/client/__tests__/components/Output/PublishPane/__snapshots__/Destination.js.snap
index 14afee7d..e0870daa 100644
--- a/client/__tests__/components/Output/PublishPane/__snapshots__/Destination.js.snap
+++ b/client/__tests__/components/Output/PublishPane/__snapshots__/Destination.js.snap
@@ -28,15 +28,16 @@ exports[`Output/PublishPane/Destination renders correctly 1`] = `
               tenant1
             </span>
           </span>
-          <a
+          <button
             class="icn-btn"
+            tabindex="0"
           >
             <i
               aria-hidden="true"
               aria-label="trash"
               class="icon-trash"
             />
-          </a>
+          </button>
         </div>
         <div
           class="sd-list-item__row"
@@ -63,25 +64,27 @@ exports[`Output/PublishPane/Destination renders correctly 1`] = `
         <span
           class="sd-collapse-box__collapse-btn"
         >
-          <a
+          <button
             class="icn-btn"
+            tabindex="0"
           >
             <i
               aria-hidden="true"
               aria-label="chevron-up-thin"
               class="icon-chevron-up-thin"
             />
-          </a>
+          </button>
         </span>
-        <a
+        <button
           class="icn-btn"
+          tabindex="0"
         >
           <i
             aria-hidden="true"
             aria-label="trash"
             class="icon-trash"
           />
-        </a>
+        </button>
       </div>
       <div
         class="sd-collapse-box__content-block sd-collapse-box__content-block--top"
@@ -155,18 +158,18 @@ exports[`Output/PublishPane/Destination renders correctly 1`] = `
           <span>
             <span
               class="sd-check-new__wrapper"
+              tabindex="-1"
             >
               <input
-                class="visuallyhidden"
+                class="sd-check-new__input"
                 id="id1"
+                tabindex="0"
                 type="checkbox"
               />
               <span
-                aria-label="false"
                 class="sd-check-new"
               />
               <label
-                class=""
                 for="id1"
               >
                 Paywall
@@ -181,6 +184,7 @@ exports[`Output/PublishPane/Destination renders correctly 1`] = `
         <button
           aria-label=""
           class="btn btn--expanded btn--primary btn--hollow"
+          tabindex="0"
         >
           Add to content list
         </button>
diff --git a/client/__tests__/components/Output/PublishPane/__snapshots__/MetadataEditor.js.snap b/client/__tests__/components/Output/PublishPane/__snapshots__/MetadataEditor.js.snap
index 875c0d48..66926080 100644
--- a/client/__tests__/components/Output/PublishPane/__snapshots__/MetadataEditor.js.snap
+++ b/client/__tests__/components/Output/PublishPane/__snapshots__/MetadataEditor.js.snap
@@ -13,15 +13,16 @@ exports[`Output/PublishPane/MetadataEditor renders correctly 1`] = `
       <span
         class="sd-margin-l--1"
       >
-        <a
+        <button
           class="icn-btn"
+          tabindex="0"
         >
           <i
             aria-hidden="true"
             aria-label="arrow-left"
             class="icon-arrow-left"
           />
-        </a>
+        </button>
       </span>
       <h3
         class="side-panel__heading side-panel__heading--big"
diff --git a/client/__tests__/components/Output/PublishPane/__snapshots__/Publish.js.snap b/client/__tests__/components/Output/PublishPane/__snapshots__/Publish.js.snap
index 85c38f46..3559a328 100644
--- a/client/__tests__/components/Output/PublishPane/__snapshots__/Publish.js.snap
+++ b/client/__tests__/components/Output/PublishPane/__snapshots__/Publish.js.snap
@@ -20,6 +20,7 @@ exports[`Output/PublishPane/Publish renders properly 1`] = `
       <span>
         <button
           class="btn btn--primary btn--icon-only btn--icon-only-circle"
+          tabindex="0"
         >
           <i
             aria-label="plus-large"
@@ -41,49 +42,70 @@ exports[`Output/PublishPane/Publish renders properly 1`] = `
       <div
         class="sd-check-button__group sd-check-button__group--left"
       >
-        <input
-          class="visuallyhidden"
-          id="id10"
-          type="checkbox"
-        />
         <span
-          class="sd-check-button checked"
+          class="sd-check-button sd-check-button--native"
+          tabindex="-1"
         >
+          <input
+            class="sd-check-button__input"
+            id="id10"
+            name="id1"
+            tabindex="0"
+            type="radio"
+          />
           <label
             class="sd-check-button__text-label"
             for="id10"
           >
-            All
+            <span
+              class="sd-check-button__text-label-inner"
+            >
+              All
+            </span>
           </label>
         </span>
-        <input
-          class="visuallyhidden"
-          id="id11"
-          type="checkbox"
-        />
         <span
-          class="sd-check-button"
+          class="sd-check-button sd-check-button--native"
+          tabindex="-1"
         >
+          <input
+            class="sd-check-button__input"
+            id="id11"
+            name="id1"
+            tabindex="0"
+            type="radio"
+          />
           <label
             class="sd-check-button__text-label"
             for="id11"
           >
-            Published
+            <span
+              class="sd-check-button__text-label-inner"
+            >
+              Published
+            </span>
           </label>
         </span>
-        <input
-          class="visuallyhidden"
-          id="id12"
-          type="checkbox"
-        />
         <span
-          class="sd-check-button"
+          class="sd-check-button sd-check-button--native"
+          tabindex="-1"
         >
+          <input
+            class="sd-check-button__input"
+            id="id12"
+            name="id1"
+            tabindex="0"
+            type="radio"
+          />
           <label
             class="sd-check-button__text-label"
             for="id12"
           >
-            Unpublished
+            <span
+              class="sd-check-button__text-label-inner"
+            >
+              Unpublished
+            </span>
           </label>
         </span>
       </div>
@@ -119,15 +141,16 @@ exports[`Output/PublishPane/Publish renders properly 1`] = `
                   tenant1
                 </span>
               </span>
-              <a
+              <button
                 class="icn-btn"
+                tabindex="0"
               >
                 <i
                   aria-hidden="true"
                   aria-label="trash"
                   class="icon-trash"
                 />
-              </a>
+              </button>
             </div>
             <div
               class="sd-list-item__row"
@@ -156,25 +179,27 @@ exports[`Output/PublishPane/Publish renders properly 1`] = `
             <span
               class="sd-collapse-box__collapse-btn"
             >
-              <a
+              <button
                 class="icn-btn"
+                tabindex="0"
               >
                 <i
                   aria-hidden="true"
                   aria-label="chevron-up-thin"
                   class="icon-chevron-up-thin"
                 />
-              </a>
+              </button>
             </span>
-            <a
+            <button
               class="icn-btn"
+              tabindex="0"
             >
               <i
                 aria-hidden="true"
                 aria-label="trash"
                 class="icon-trash"
               />
-            </a>
+            </button>
           </div>
           <div
             class="sd-collapse-box__content-block sd-collapse-box__content-block--top"
@@ -251,18 +276,18 @@ exports[`Output/PublishPane/Publish renders properly 1`] = `
               <span>
                 <span
                   class="sd-check-new__wrapper"
+                  tabindex="-1"
                 >
                   <input
-                    class="visuallyhidden"
+                    class="sd-check-new__input"
                     id="id2"
+                    tabindex="0"
                     type="checkbox"
                   />
                   <span
-                    aria-label="false"
                     class="sd-check-new"
                   />
                   <label
-                    class=""
                     for="id2"
                   >
                     Paywall
@@ -277,6 +302,7 @@ exports[`Output/PublishPane/Publish renders properly 1`] = `
             <button
               aria-label=""
               class="btn btn--expanded btn--primary btn--hollow"
+              tabindex="0"
             >
               Add to content list
             </button>
diff --git a/client/__tests__/components/Output/PublishPane/__snapshots__/PublishPane.js.snap b/client/__tests__/components/Output/PublishPane/__snapshots__/PublishPane.js.snap
index 0e13beb4..c8a4c354 100644
--- a/client/__tests__/components/Output/PublishPane/__snapshots__/PublishPane.js.snap
+++ b/client/__tests__/components/Output/PublishPane/__snapshots__/PublishPane.js.snap
@@ -13,15 +13,16 @@ exports[`Output/PublishPane/PublishPane renders correctly 1`] = `
       <div
         class="side-panel__tools"
       >
-        <a
+        <button
           class="icn-btn"
+          tabindex="0"
         >
           <i
             aria-hidden="true"
             aria-label="close-small"
             class="icon-close-small"
           />
-        </a>
+        </button>
       </div>
       <ul
         class="nav-tabs nav-tabs--ui-dark"
@@ -69,6 +70,7 @@ exports[`Output/PublishPane/PublishPane renders correctly 1`] = `
           <span>
             <button
               class="btn btn--primary btn--icon-only btn--icon-only-circle"
+              tabindex="0"
             >
               <i
                 aria-label="plus-large"
@@ -95,49 +97,70 @@ exports[`Output/PublishPane/PublishPane renders correctly 1`] = `
           <div
             class="sd-check-button__group sd-check-button__group--left"
           >
-            <input
-              class="visuallyhidden"
-              id="id10"
-              type="checkbox"
-            />
             <span
-              class="sd-check-button checked"
+              class="sd-check-button sd-check-button--native"
+              tabindex="-1"
             >
+              <input
+                class="sd-check-button__input"
+                id="id10"
+                name="id1"
+                tabindex="0"
+                type="radio"
+              />
               <label
                 class="sd-check-button__text-label"
                 for="id10"
               >
-                All
+                <span
+                  class="sd-check-button__text-label-inner"
+                >
+                  All
+                </span>
               </label>
             </span>
-            <input
-              class="visuallyhidden"
-              id="id11"
-              type="checkbox"
-            />
             <span
-              class="sd-check-button"
+              class="sd-check-button sd-check-button--native"
+              tabindex="-1"
             >
+              <input
+                class="sd-check-button__input"
+                id="id11"
+                name="id1"
+                tabindex="0"
+                type="radio"
+              />
               <label
                 class="sd-check-button__text-label"
                 for="id11"
               >
-                Published
+                <span
+                  class="sd-check-button__text-label-inner"
+                >
+                  Published
+                </span>
               </label>
             </span>
-            <input
-              class="visuallyhidden"
-              id="id12"
-              type="checkbox"
-            />
             <span
-              class="sd-check-button"
+              class="sd-check-button sd-check-button--native"
+              tabindex="-1"
             >
+              <input
+                class="sd-check-button__input"
+                id="id12"
+                name="id1"
+                tabindex="0"
+                type="radio"
+              />
               <label
                 class="sd-check-button__text-label"
                 for="id12"
               >
-                Unpublished
+                <span
+                  class="sd-check-button__text-label-inner"
+                >
+                  Unpublished
+                </span>
               </label>
             </span>
           </div>
@@ -224,15 +247,16 @@ exports[`Output/PublishPane/PublishPane renders correctly 1`] = `
           <span
             class="sd-margin-l--1"
           >
-            <a
+            <button
               class="icn-btn"
+              tabindex="0"
             >
               <i
                 aria-hidden="true"
                 aria-label="arrow-left"
                 class="icon-arrow-left"
               />
-            </a>
+            </button>
           </span>
           <h3
             class="side-panel__heading side-panel__heading--big"
@@ -339,6 +363,7 @@ exports[`Output/PublishPane/PublishPane renders correctly 1`] = `
       <button
         aria-label=""
         class="btn btn--expanded btn--success btn--disabled"
+        tabindex="0"
       >
         Publish
       </button>
diff --git a/client/__tests__/components/Output/SortingOptions.js b/client/__tests__/components/Output/SortingOptions.js
index c621d18a..96ecde63 100644
--- a/client/__tests__/components/Output/SortingOptions.js
+++ b/client/__tests__/components/Output/SortingOptions.js
@@ -3,15 +3,13 @@ import SortingOptions from "../../../components/Output/SortingOptions";
 import { render, fireEvent } from "@testing-library/react";
 import Store from "../../../components/Output/Store";
 
-
 describe("Output/SortingOptions", () => {
-
   it("renders correctly", () => {
     const { container } = render(
       <Store.Provider
         value={{
-          filters: { order: 'asc' },
-          actions: { setFilters: jest.fn() }
+          filters: { order: "asc" },
+          actions: { setFilters: jest.fn() },
         }}
       >
         <SortingOptions />
@@ -26,19 +24,20 @@ describe("Output/SortingOptions", () => {
     const { container } = render(
       <Store.Provider
         value={{
-          filters: { order: 'asc' },
-          actions: { setFilters: setFilters }
+          filters: { order: "asc" },
+          actions: { setFilters: setFilters },
         }}
       >
         <SortingOptions />
       </Store.Provider>
     );
-    const orderButton = container.querySelector('a.icn-btn .icon-ascending').closest('a.icn-btn');
+    const orderButton = container
+      .querySelector(".icn-btn .icon-ascending")
+      .closest(".icn-btn");
     fireEvent.click(orderButton);
 
     expect(setFilters).toHaveBeenCalled();
-    expect(setFilters).toHaveBeenCalledWith({ order: 'desc' });
-
+    expect(setFilters).toHaveBeenCalledWith({ order: "desc" });
   });
 
   it("changes sorting", async () => {
@@ -47,17 +46,17 @@ describe("Output/SortingOptions", () => {
     const { getByText } = render(
       <Store.Provider
         value={{
-          filters: { sort: 'updated_at' },
-          actions: { setFilters: setFilters }
+          filters: { sort: "updated_at" },
+          actions: { setFilters: setFilters },
         }}
       >
         <SortingOptions />
       </Store.Provider>
     );
-    const button = getByText('Created')
+    const button = getByText("Created");
     fireEvent.click(button);
 
     expect(setFilters).toHaveBeenCalled();
-    expect(setFilters).toHaveBeenCalledWith({ sort: 'created_at' });
+    expect(setFilters).toHaveBeenCalledWith({ sort: "created_at" });
   });
 });
diff --git a/client/__tests__/components/Output/Subnav.js b/client/__tests__/components/Output/Subnav.js
index e9a35f60..8721207e 100644
--- a/client/__tests__/components/Output/Subnav.js
+++ b/client/__tests__/components/Output/Subnav.js
@@ -4,29 +4,27 @@ import { render, fireEvent } from "@testing-library/react";
 import Store from "../../../components/Output/Store";
 
 const languages = [
-  { qcode: 'pl', name: 'Polish' },
-  { qcode: 'en', name: 'English' },
-  { qcode: 'de', name: 'German' },
-]
+  { qcode: "pl", name: "Polish" },
+  { qcode: "en", name: "English" },
+  { qcode: "de", name: "German" },
+];
 
 describe("Output/Subnav", () => {
-
   it("renders correctly", () => {
     const { container } = render(
       <Store.Provider
         value={{
           articlesCounts: { incoming: 0, published: 0 },
           tenants: [
-            { name: 'tenant1', code: 'tenant1' },
-            { name: 'tenant2', code: 'tenant2' }
+            { name: "tenant1", code: "tenant1" },
+            { name: "tenant2", code: "tenant2" },
           ],
           filters: {},
-          selectedList: 'incoming',
-          actions: { setSelectedList: jest.fn() }
+          selectedList: "incoming",
+          actions: { setSelectedList: jest.fn() },
         }}
       >
-        <Subnav isLanguagesEnabled={true}
-          languages={languages} />
+        <Subnav isLanguagesEnabled={true} languages={languages} />
       </Store.Provider>
     );
     expect(container.firstChild).toMatchSnapshot();
@@ -40,20 +38,22 @@ describe("Output/Subnav", () => {
         value={{
           articlesCounts: { incoming: 0, published: 0 },
           tenants: [
-            { name: 'tenant1', code: 'tenant1' },
-            { name: 'tenant2', code: 'tenant2' }
+            { name: "tenant1", code: "tenant1" },
+            { name: "tenant2", code: "tenant2" },
           ],
           filters: {},
-          selectedList: 'incoming',
-          actions: { setSelectedList: setList }
+          selectedList: "incoming",
+          actions: { setSelectedList: setList },
         }}
       >
-        <Subnav isLanguagesEnabled={true}
-          languages={languages} />
+        <Subnav isLanguagesEnabled={true} languages={languages} />
       </Store.Provider>
     );
 
-    const button = getByText('Published');
+    const button = getByText("Published")
+      .closest(".sd-check-button")
+      .querySelector("input");
+
     fireEvent.click(button);
 
     expect(setList).toHaveBeenCalled();
diff --git a/client/__tests__/components/Output/Swimlane/__snapshots__/ArticleItem.js.snap b/client/__tests__/components/Output/Swimlane/__snapshots__/ArticleItem.js.snap
index facfa7b8..e11c12d9 100644
--- a/client/__tests__/components/Output/Swimlane/__snapshots__/ArticleItem.js.snap
+++ b/client/__tests__/components/Output/Swimlane/__snapshots__/ArticleItem.js.snap
@@ -28,24 +28,26 @@ exports[`Output/Swimlane/ArticleItem renders correctly 1`] = `
   <div
     class="sd-list-item__action-menu sd-list-item__action-menu--direction-row"
   >
-    <a
+    <button
       class="icn-btn"
+      tabindex="0"
     >
       <i
         aria-hidden="true"
         aria-label="pencil"
         class="icon-pencil"
       />
-    </a>
-    <a
+    </button>
+    <button
       class="icn-btn"
+      tabindex="0"
     >
       <i
         aria-hidden="true"
         aria-label="expand-thin"
         class="icon-expand-thin"
       />
-    </a>
+    </button>
   </div>
 </div>
 `;
diff --git a/client/__tests__/components/Output/__snapshots__/ArticleItem.js.snap b/client/__tests__/components/Output/__snapshots__/ArticleItem.js.snap
index 4c208072..dcc4fdaf 100644
--- a/client/__tests__/components/Output/__snapshots__/ArticleItem.js.snap
+++ b/client/__tests__/components/Output/__snapshots__/ArticleItem.js.snap
@@ -43,7 +43,7 @@ exports[`Output/ArticleItem renders correctly 1`] = `
       >
         <a
           class="label label--success cursorPointer"
-          href="http://sourcefabric.org/test"
+          href="https://sourcefabric.org/test"
           target="_blank"
         >
           <span>
@@ -59,24 +59,26 @@ exports[`Output/ArticleItem renders correctly 1`] = `
   <div
     class="sd-list-item__action-menu sd-list-item__action-menu--direction-row"
   >
-    <a
+    <button
       class="icn-btn"
+      tabindex="0"
     >
       <i
         aria-hidden="true"
         aria-label="pencil"
         class="icon-pencil"
       />
-    </a>
-    <a
+    </button>
+    <button
       class="icn-btn"
+      tabindex="0"
     >
       <i
         aria-hidden="true"
         aria-label="expand-thin"
         class="icon-expand-thin"
       />
-    </a>
+    </button>
   </div>
   <div
     class="modal modal--double"
diff --git a/client/__tests__/components/Output/__snapshots__/FilterPane.js.snap b/client/__tests__/components/Output/__snapshots__/FilterPane.js.snap
index 6e7932b2..2dbad13e 100644
--- a/client/__tests__/components/Output/__snapshots__/FilterPane.js.snap
+++ b/client/__tests__/components/Output/__snapshots__/FilterPane.js.snap
@@ -13,15 +13,16 @@ exports[`Output/FilterPane renders properly 1`] = `
       <span
         class="side-panel__close"
       >
-        <a
+        <button
           class="icn-btn"
+          tabindex="0"
         >
           <i
             aria-hidden="true"
             aria-label="close-small"
             class="icon-close-small"
           />
-        </a>
+        </button>
       </span>
       <h3
         class="side-panel__heading side-panel__heading--big"
@@ -238,12 +239,14 @@ exports[`Output/FilterPane renders properly 1`] = `
         <button
           aria-label=""
           class="btn btn--hollow"
+          tabindex="0"
         >
           Clear
         </button>
         <button
           aria-label=""
           class="btn btn--primary"
+          tabindex="0"
         >
           Filter
         </button>
diff --git a/client/__tests__/components/Output/__snapshots__/Output.js.snap b/client/__tests__/components/Output/__snapshots__/Output.js.snap
index 11662695..ee8ea670 100644
--- a/client/__tests__/components/Output/__snapshots__/Output.js.snap
+++ b/client/__tests__/components/Output/__snapshots__/Output.js.snap
@@ -55,34 +55,48 @@ exports[`Output/Output renders properly 1`] = `
         <div
           class="sd-check-button__group sd-check-button__group--left"
         >
-          <input
-            class="visuallyhidden"
-            id="id10"
-            type="checkbox"
-          />
           <span
-            class="sd-check-button checked"
+            class="sd-check-button sd-check-button--native"
+            tabindex="-1"
           >
+            <input
+              class="sd-check-button__input"
+              id="id10"
+              name="id1"
+              tabindex="0"
+              type="radio"
+            />
             <label
               class="sd-check-button__text-label"
               for="id10"
             >
-              Incoming
+              <span
+                class="sd-check-button__text-label-inner"
+              >
+                Incoming
+              </span>
             </label>
           </span>
-          <input
-            class="visuallyhidden"
-            id="id11"
-            type="checkbox"
-          />
           <span
-            class="sd-check-button"
+            class="sd-check-button sd-check-button--native"
+            tabindex="-1"
           >
+            <input
+              class="sd-check-button__input"
+              id="id11"
+              name="id1"
+              tabindex="0"
+              type="radio"
+            />
             <label
               class="sd-check-button__text-label"
               for="id11"
             >
-              Published
+              <span
+                class="sd-check-button__text-label-inner"
+              >
+                Published
+              </span>
             </label>
           </span>
         </div>
@@ -120,15 +134,16 @@ exports[`Output/Output renders properly 1`] = `
           </li>
         </ul>
       </div>
-      <a
+      <button
         class="icn-btn"
+        tabindex="0"
       >
         <i
           aria-hidden="true"
           aria-label="descending"
           class="icon-descending"
         />
-      </a>
+      </button>
     </div>
     <div
       class="subnav__spacer subnav__spacer--no-margin"
@@ -231,15 +246,16 @@ exports[`Output/Output renders properly 1`] = `
           <span
             class="side-panel__close"
           >
-            <a
+            <button
               class="icn-btn"
+              tabindex="0"
             >
               <i
                 aria-hidden="true"
                 aria-label="close-small"
                 class="icon-close-small"
               />
-            </a>
+            </button>
           </span>
           <h3
             class="side-panel__heading side-panel__heading--big"
@@ -456,12 +472,14 @@ exports[`Output/Output renders properly 1`] = `
             <button
               aria-label=""
               class="btn btn--hollow"
+              tabindex="0"
             >
               Clear
             </button>
             <button
               aria-label=""
               class="btn btn--primary"
+              tabindex="0"
             >
               Filter
             </button>
diff --git a/client/__tests__/components/Output/__snapshots__/PreviewPane.js.snap b/client/__tests__/components/Output/__snapshots__/PreviewPane.js.snap
index 57fe6e85..4ba72e1c 100644
--- a/client/__tests__/components/Output/__snapshots__/PreviewPane.js.snap
+++ b/client/__tests__/components/Output/__snapshots__/PreviewPane.js.snap
@@ -14,15 +14,16 @@ exports[`Output/PreviewPane renders correctly 1`] = `
       <div
         class="side-panel__tools"
       >
-        <a
+        <button
           class="icn-btn"
+          tabindex="0"
         >
           <i
             aria-hidden="true"
             aria-label="close-small"
             class="icon-close-small"
           />
-        </a>
+        </button>
       </div>
       <h3
         class="side-panel__heading"
diff --git a/client/__tests__/components/Output/__snapshots__/Subnav.js.snap b/client/__tests__/components/Output/__snapshots__/Subnav.js.snap
index fcfca4a0..27335f4f 100644
--- a/client/__tests__/components/Output/__snapshots__/Subnav.js.snap
+++ b/client/__tests__/components/Output/__snapshots__/Subnav.js.snap
@@ -13,34 +13,48 @@ exports[`Output/Subnav renders correctly 1`] = `
       <div
         class="sd-check-button__group sd-check-button__group--left"
       >
-        <input
-          class="visuallyhidden"
-          id="id10"
-          type="checkbox"
-        />
         <span
-          class="sd-check-button checked"
+          class="sd-check-button sd-check-button--native"
+          tabindex="-1"
         >
+          <input
+            class="sd-check-button__input"
+            id="id10"
+            name="id1"
+            tabindex="0"
+            type="radio"
+          />
           <label
             class="sd-check-button__text-label"
             for="id10"
           >
-            Incoming
+            <span
+              class="sd-check-button__text-label-inner"
+            >
+              Incoming
+            </span>
           </label>
         </span>
-        <input
-          class="visuallyhidden"
-          id="id11"
-          type="checkbox"
-        />
         <span
-          class="sd-check-button"
+          class="sd-check-button sd-check-button--native"
+          tabindex="-1"
         >
+          <input
+            class="sd-check-button__input"
+            id="id11"
+            name="id1"
+            tabindex="0"
+            type="radio"
+          />
           <label
             class="sd-check-button__text-label"
             for="id11"
           >
-            Published
+            <span
+              class="sd-check-button__text-label-inner"
+            >
+              Published
+            </span>
           </label>
         </span>
       </div>
@@ -78,15 +92,16 @@ exports[`Output/Subnav renders correctly 1`] = `
         </li>
       </ul>
     </div>
-    <a
+    <button
       class="icn-btn"
+      tabindex="0"
     >
       <i
         aria-hidden="true"
         aria-label="ascending"
         class="icon-ascending"
       />
-    </a>
+    </button>
   </div>
   <div
     class="subnav__spacer subnav__spacer--no-margin"
diff --git a/client/__tests__/components/TargetedPublishing/AddWebsite.js b/client/__tests__/components/TargetedPublishing/AddWebsite.js
index 99ba855f..64b64fc9 100644
--- a/client/__tests__/components/TargetedPublishing/AddWebsite.js
+++ b/client/__tests__/components/TargetedPublishing/AddWebsite.js
@@ -4,7 +4,7 @@ import {
   render,
   fireEvent,
   wait,
-  waitForElement
+  waitForElement,
 } from "@testing-library/react";
 import axios from "axios";
 
@@ -20,13 +20,9 @@ describe("TargetedPublishing/AddWebsite", () => {
         rules={[]}
       />
     );
-    await wait(() =>
-      expect(getByText("tenant1.sourcefabric.org")).toBeInTheDocument()
-    );
+    await wait(() => expect(getByText("TENANT1")).toBeInTheDocument());
 
-    await wait(() =>
-      expect(getByText("tenant2.sourcefabric.org")).toBeInTheDocument()
-    );
+    await wait(() => expect(getByText("TENANT2")).toBeInTheDocument());
   });
 
   it("filters tenants with rules - should render one tenant only", async () => {
@@ -38,13 +34,9 @@ describe("TargetedPublishing/AddWebsite", () => {
         rules={[{ tenant: { id: 2 } }]}
       />
     );
-    await wait(() =>
-      expect(getByText("tenant1.sourcefabric.org")).toBeInTheDocument()
-    );
+    await wait(() => expect(getByText("TENANT1")).toBeInTheDocument());
 
-    await wait(() =>
-      expect(queryByText("tenant2.sourcefabric.org")).not.toBeInTheDocument()
-    );
+    await wait(() => expect(queryByText("TENANT2")).not.toBeInTheDocument());
   });
 
   it("opens dropdown", async () => {
@@ -75,9 +67,7 @@ describe("TargetedPublishing/AddWebsite", () => {
         rules={[]}
       />
     );
-    const tenantItem = await waitForElement(() =>
-      getByText("tenant1.sourcefabric.org")
-    );
+    const tenantItem = await waitForElement(() => getByText("TENANT1"));
 
     fireEvent.click(tenantItem);
 
diff --git a/client/__tests__/components/TargetedPublishing/ContentListElement.js b/client/__tests__/components/TargetedPublishing/ContentListElement.js
index 2b27955b..52e4e396 100644
--- a/client/__tests__/components/TargetedPublishing/ContentListElement.js
+++ b/client/__tests__/components/TargetedPublishing/ContentListElement.js
@@ -6,26 +6,26 @@ describe("TargetedPublishing/ContentListElement", () => {
   const ruleLists = [
     {
       id: 1,
-      position: 0
-    }
+      position: 0,
+    },
   ];
 
   const list = {
     id: 1,
-    position: 0
+    position: 0,
   };
 
   const allContentLists = [
     {
       content_list_items_count: 10,
       id: 1,
-      name: "test1"
+      name: "test1",
     },
     {
       content_list_items_count: 5,
       id: 2,
-      name: "test2"
-    }
+      name: "test2",
+    },
   ];
 
   it("renders correctly", () => {
@@ -92,7 +92,9 @@ describe("TargetedPublishing/ContentListElement", () => {
       />
     );
 
-    const button = container.querySelector('a.icn-btn .icon-trash').closest('a.icn-btn');
+    const button = container
+      .querySelector(".icn-btn .icon-trash")
+      .closest(".icn-btn");
 
     fireEvent.click(button);
 
@@ -122,8 +124,8 @@ describe("TargetedPublishing/ContentListElement", () => {
     expect(save).toBeCalledWith([
       {
         id: 1,
-        position: 4
-      }
+        position: 4,
+      },
     ]);
   });
 });
diff --git a/client/__tests__/components/TargetedPublishing/MetaDataOverlay.js b/client/__tests__/components/TargetedPublishing/MetaDataOverlay.js
index 2c931b2a..974ed084 100644
--- a/client/__tests__/components/TargetedPublishing/MetaDataOverlay.js
+++ b/client/__tests__/components/TargetedPublishing/MetaDataOverlay.js
@@ -9,7 +9,7 @@ describe("TargetedPublishing/MetaDataOverlay", () => {
     og_title: null,
     og_description: null,
     twitter_title: null,
-    twitter_description: null
+    twitter_description: null,
   };
 
   it("renders correctly", () => {
@@ -42,7 +42,9 @@ describe("TargetedPublishing/MetaDataOverlay", () => {
       />
     );
 
-    fireEvent.click(container.querySelector('a.icn-btn .icon-arrow-left').closest('a.icn-btn'));
+    fireEvent.click(
+      container.querySelector(".icn-btn .icon-arrow-left").closest(".icn-btn")
+    );
 
     expect(toggle).toHaveBeenCalled();
   });
@@ -65,8 +67,8 @@ describe("TargetedPublishing/MetaDataOverlay", () => {
 
     fireEvent.change(input, {
       target: {
-        files: ["dummyValue.something"]
-      }
+        files: ["dummyValue.something"],
+      },
     });
     expect(uploadImage).toHaveBeenCalled();
   });
@@ -87,8 +89,8 @@ describe("TargetedPublishing/MetaDataOverlay", () => {
 
     fireEvent.change(container.querySelector('input[name="og_title"]'), {
       target: {
-        value: "teststring"
-      }
+        value: "teststring",
+      },
     });
 
     expect(setMetaData).toHaveBeenCalled();
diff --git a/client/__tests__/components/TargetedPublishing/TargetedPublishing.js b/client/__tests__/components/TargetedPublishing/TargetedPublishing.js
index c8583056..44cf1f96 100644
--- a/client/__tests__/components/TargetedPublishing/TargetedPublishing.js
+++ b/client/__tests__/components/TargetedPublishing/TargetedPublishing.js
@@ -10,29 +10,30 @@ describe("TargetedPublishing/TargetedPublishing", () => {
     {
       tenant: {
         code: "eif0ca",
+        name: "TENANT1",
         subdomain: "tenant1",
         domain_name: "sourcefabric.org",
         fbia_enabled: false,
         paywall_enabled: false,
-        output_channel: false
+        output_channel: false,
       },
       route: {
-        name: "route"
+        name: "route",
       },
       is_published_fbia: false,
       published: true,
-      paywall_secured: false
-    }
+      paywall_secured: false,
+    },
   ];
 
   const item = {
-    guid: "asdfasdf87876876"
+    guid: "asdfasdf87876876",
   };
 
   const config = {
     publisher: {
-      protocol: "https"
-    }
+      protocol: "https",
+    },
   };
 
   it('renders "no websites has been set" and AdddWebsite component', async () => {
@@ -66,6 +67,6 @@ describe("TargetedPublishing/TargetedPublishing", () => {
       />
     );
 
-    expect(getAllByText("tenant1.sourcefabric.org")).toHaveLength(2);
+    expect(getAllByText("TENANT1")).toHaveLength(2);
   });
 });
diff --git a/client/__tests__/components/TargetedPublishing/__snapshots__/ContentListElement.js.snap b/client/__tests__/components/TargetedPublishing/__snapshots__/ContentListElement.js.snap
index 2e01f6d4..e4ad7604 100644
--- a/client/__tests__/components/TargetedPublishing/__snapshots__/ContentListElement.js.snap
+++ b/client/__tests__/components/TargetedPublishing/__snapshots__/ContentListElement.js.snap
@@ -10,15 +10,16 @@ exports[`TargetedPublishing/ContentListElement renders correctly 1`] = `
     <div
       class="sd-list-item__row no-margin sd-flex-justify-end"
     >
-      <a
+      <button
         class="icn-btn"
+        tabindex="0"
       >
         <i
           aria-hidden="true"
           aria-label="trash"
           class="icon-trash"
         />
-      </a>
+      </button>
     </div>
     <div
       class="sd-list-item__row"
diff --git a/client/__tests__/components/TargetedPublishing/__snapshots__/ContentLists.js.snap b/client/__tests__/components/TargetedPublishing/__snapshots__/ContentLists.js.snap
index 1c8acf76..f543a397 100644
--- a/client/__tests__/components/TargetedPublishing/__snapshots__/ContentLists.js.snap
+++ b/client/__tests__/components/TargetedPublishing/__snapshots__/ContentLists.js.snap
@@ -18,15 +18,16 @@ exports[`TargetedPublishing/ContentLists renders correctly 1`] = `
       <div
         class="sd-list-item__row no-margin sd-flex-justify-end"
       >
-        <a
+        <button
           class="icn-btn"
+          tabindex="0"
         >
           <i
             aria-hidden="true"
             aria-label="trash"
             class="icon-trash"
           />
-        </a>
+        </button>
       </div>
       <div
         class="sd-list-item__row"
@@ -132,6 +133,7 @@ exports[`TargetedPublishing/ContentLists renders correctly 1`] = `
   <button
     aria-label=""
     class="btn btn--expanded btn--primary btn--hollow"
+    tabindex="0"
   >
     Add to content list
   </button>
diff --git a/client/__tests__/components/TargetedPublishing/__snapshots__/Destination.js.snap b/client/__tests__/components/TargetedPublishing/__snapshots__/Destination.js.snap
index c71e1102..a995ed4d 100644
--- a/client/__tests__/components/TargetedPublishing/__snapshots__/Destination.js.snap
+++ b/client/__tests__/components/TargetedPublishing/__snapshots__/Destination.js.snap
@@ -25,7 +25,7 @@ exports[`TargetedPublishing/Destination renders correctly 1`] = `
             <span
               class="sd-list-item__text-strong"
             >
-              tenant-1.sourcefabric.org
+              tenant 1
             </span>
           </span>
         </div>
@@ -59,25 +59,27 @@ exports[`TargetedPublishing/Destination renders correctly 1`] = `
         <span
           class="sd-collapse-box__collapse-btn"
         >
-          <a
+          <button
             class="icn-btn"
+            tabindex="0"
           >
             <i
               aria-hidden="true"
               aria-label="chevron-up-thin"
               class="icon-chevron-up-thin"
             />
-          </a>
+          </button>
         </span>
-        <a
+        <button
           class="icn-btn"
+          tabindex="0"
         >
           <i
             aria-hidden="true"
             aria-label="trash"
             class="icon-trash"
           />
-        </a>
+        </button>
       </div>
       <div
         class="sd-collapse-box__content-block sd-collapse-box__content-block--top"
@@ -94,7 +96,7 @@ exports[`TargetedPublishing/Destination renders correctly 1`] = `
               <span
                 class="sd-overflow-ellipsis sd-list-item--element-grow sd-list-item__text-strong"
               >
-                tenant-1.sourcefabric.org
+                tenant 1
               </span>
               <a
                 class="icn-btn"
@@ -157,18 +159,18 @@ exports[`TargetedPublishing/Destination renders correctly 1`] = `
           <span>
             <span
               class="sd-check-new__wrapper"
+              tabindex="-1"
             >
               <input
-                class="visuallyhidden"
+                class="sd-check-new__input"
                 id="id1"
+                tabindex="0"
                 type="checkbox"
               />
               <span
-                aria-label="false"
                 class="sd-check-new"
               />
               <label
-                class=""
                 for="id1"
               >
                 FBIA
@@ -184,18 +186,18 @@ exports[`TargetedPublishing/Destination renders correctly 1`] = `
           <span>
             <span
               class="sd-check-new__wrapper"
+              tabindex="-1"
             >
               <input
-                class="visuallyhidden"
+                class="sd-check-new__input"
                 id="id2"
+                tabindex="0"
                 type="checkbox"
               />
               <span
-                aria-label="false"
                 class="sd-check-new"
               />
               <label
-                class=""
                 for="id2"
               >
                 Paywall
diff --git a/client/__tests__/components/TargetedPublishing/__snapshots__/MetaDataOverlay.js.snap b/client/__tests__/components/TargetedPublishing/__snapshots__/MetaDataOverlay.js.snap
index 87cc74eb..45830e26 100644
--- a/client/__tests__/components/TargetedPublishing/__snapshots__/MetaDataOverlay.js.snap
+++ b/client/__tests__/components/TargetedPublishing/__snapshots__/MetaDataOverlay.js.snap
@@ -13,15 +13,16 @@ exports[`TargetedPublishing/MetaDataOverlay renders correctly 1`] = `
       <span
         class="sd-margin-l--1"
       >
-        <a
+        <button
           class="icn-btn"
+          tabindex="0"
         >
           <i
             aria-hidden="true"
             aria-label="arrow-left"
             class="icon-arrow-left"
           />
-        </a>
+        </button>
       </span>
       <h3
         class="side-panel__heading side-panel__heading--big"
diff --git a/client/__tests__/components/UI/__snapshots__/SaveBar.js.snap b/client/__tests__/components/UI/__snapshots__/SaveBar.js.snap
index f595b435..545caf20 100644
--- a/client/__tests__/components/UI/__snapshots__/SaveBar.js.snap
+++ b/client/__tests__/components/UI/__snapshots__/SaveBar.js.snap
@@ -13,12 +13,14 @@ exports[`UI/SaveBar renders correctly 1`] = `
     <button
       aria-label=""
       class="btn btn--hollow btn--ui-dark"
+      tabindex="0"
     >
       Cancel
     </button>
     <button
       aria-label=""
       class="btn btn--primary btn--ui-dark"
+      tabindex="0"
     >
       Save
     </button>
diff --git a/client/__tests__/components/generic/PublishingOptionSwitches.js b/client/__tests__/components/generic/PublishingOptionSwitches.js
index cce53e4d..d2fc81e2 100644
--- a/client/__tests__/components/generic/PublishingOptionSwitches.js
+++ b/client/__tests__/components/generic/PublishingOptionSwitches.js
@@ -4,13 +4,13 @@ import {
   render,
   fireEvent,
   waitForElement,
-  wait
+  wait,
 } from "@testing-library/react";
 
 describe("generic/PublishingOptionsSwithces", () => {
   const destination = {
     is_published_fbia: true,
-    paywall_secured: true
+    paywall_secured: true,
   };
 
   it("returns null when all options are disabled", () => {
@@ -55,9 +55,7 @@ describe("generic/PublishingOptionsSwithces", () => {
     );
 
     await waitForElement(() => getByText("FBIA"));
-    await wait(() =>
-      expect(queryByText("Paywall")).not.toBeInTheDocument()
-    );
+    await wait(() => expect(queryByText("Paywall")).not.toBeInTheDocument());
   });
 
   it("renders paywall switch only", async () => {
@@ -89,7 +87,7 @@ describe("generic/PublishingOptionsSwithces", () => {
     );
 
     const checkbox = await waitForElement(() =>
-      container.querySelector(".sd-check-new")
+      container.querySelector(".sd-check-new__input")
     );
 
     fireEvent.click(checkbox);
diff --git a/client/__tests__/components/generic/__snapshots__/ArticlePreview.js.snap b/client/__tests__/components/generic/__snapshots__/ArticlePreview.js.snap
index ca1f06f8..e4743e99 100644
--- a/client/__tests__/components/generic/__snapshots__/ArticlePreview.js.snap
+++ b/client/__tests__/components/generic/__snapshots__/ArticlePreview.js.snap
@@ -14,15 +14,16 @@ exports[`generic/ArticlePreview renders correctly 1`] = `
       <div
         class="side-panel__tools"
       >
-        <a
+        <button
           class="icn-btn"
+          tabindex="0"
         >
           <i
             aria-hidden="true"
             aria-label="close-small"
             class="icon-close-small"
           />
-        </a>
+        </button>
       </div>
       <h3
         class="side-panel__heading"
diff --git a/client/__tests__/components/generic/__snapshots__/PreviewStatusLabels.js.snap b/client/__tests__/components/generic/__snapshots__/PreviewStatusLabels.js.snap
index 06791dad..7295b272 100644
--- a/client/__tests__/components/generic/__snapshots__/PreviewStatusLabels.js.snap
+++ b/client/__tests__/components/generic/__snapshots__/PreviewStatusLabels.js.snap
@@ -10,7 +10,7 @@ exports[`generic/PreviewStatusLabels renders published article labels correctly
   <div>
     <a
       class="label label--success cursorPointer"
-      href="http://sourcefabric.org/href"
+      href="https://sourcefabric.org/href"
       style="margin-right: .6em;"
       target="_blank"
     >