diff --git a/src/components/structures/GroupView.js b/src/components/structures/GroupView.js
index b5870e793d..6f1aeaf624 100644
--- a/src/components/structures/GroupView.js
+++ b/src/components/structures/GroupView.js
@@ -21,7 +21,7 @@ import Promise from 'bluebird';
import MatrixClientPeg from '../../MatrixClientPeg';
import sdk from '../../index';
import dis from '../../dispatcher';
-import SdkConfig from '../../SdkConfig';
+import { getHostingLink } from '../../utils/HostingLink';
import { sanitizedHtmlNode } from '../../HtmlUtils';
import { _t, _td } from '../../languageHandler';
import AccessibleButton from '../views/elements/AccessibleButton';
@@ -818,7 +818,7 @@ export default React.createClass({
const header = this.state.editing ?
diff --git a/src/components/views/context_menus/TopLeftMenu.js b/src/components/views/context_menus/TopLeftMenu.js
index 2a5481ff1c..278c879404 100644
--- a/src/components/views/context_menus/TopLeftMenu.js
+++ b/src/components/views/context_menus/TopLeftMenu.js
@@ -21,6 +21,7 @@ import { _t } from '../../../languageHandler';
import LogoutDialog from "../dialogs/LogoutDialog";
import Modal from "../../../Modal";
import SdkConfig from '../../../SdkConfig';
+import { getHostingLink } from '../../../utils/HostingLink';
import MatrixClientPeg from '../../../MatrixClientPeg';
export class TopLeftMenu extends React.Component {
@@ -53,7 +54,7 @@ export class TopLeftMenu extends React.Component {
render() {
const isGuest = MatrixClientPeg.get().isGuest();
- const hostingSignupLink = SdkConfig.get().hosting_signup_link;
+ const hostingSignupLink = getHostingLink('user-context-menu');
let hostingSignup = null;
if (hostingSignupLink) {
hostingSignup =
diff --git a/src/components/views/settings/ProfileSettings.js b/src/components/views/settings/ProfileSettings.js
index 7264cbd048..d3522e7b23 100644
--- a/src/components/views/settings/ProfileSettings.js
+++ b/src/components/views/settings/ProfileSettings.js
@@ -21,7 +21,7 @@ import Field from "../elements/Field";
import AccessibleButton from "../elements/AccessibleButton";
import classNames from 'classnames';
import {User} from "matrix-js-sdk";
-import SdkConfig from '../../../SdkConfig';
+import { getHostingLink } from '../../../utils/HostingLink';
export default class ProfileSettings extends React.Component {
constructor() {
@@ -138,7 +138,7 @@ export default class ProfileSettings extends React.Component {
);
- const hostingSignupLink = SdkConfig.get().hosting_signup_link;
+ const hostingSignupLink = getHostingLink('user-settings');
let hostingSignup = null;
if (hostingSignupLink) {
hostingSignup =
diff --git a/src/utils/HostingLink.js b/src/utils/HostingLink.js
new file mode 100644
index 0000000000..7efd8b6f96
--- /dev/null
+++ b/src/utils/HostingLink.js
@@ -0,0 +1,37 @@
+/*
+Copyright 2019 New Vector Ltd.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+import url from 'url';
+import qs from 'qs';
+
+import SdkConfig from '../SdkConfig';
+
+export function getHostingLink(campaign) {
+ const hostingLink = SdkConfig.get().hosting_signup_link;
+ if (!hostingLink) return null;
+ if (!campaign) return hostingLink;
+
+ try {
+ const hostingUrl = url.parse(hostingLink);
+ const params = qs.parse(hostingUrl.query);
+ params.utm_campaign = campaign;
+ hostingUrl.search = undefined;
+ hostingUrl.query = params;
+ return hostingUrl.format();
+ } catch (e) {
+ return hostingLink;
+ }
+}