-
-
+
+
+
+
diff --git a/test/e2e/specs/status-page.spec.js b/test/e2e/specs/status-page.spec.js
index 0bec78c79..9e5de4a43 100644
--- a/test/e2e/specs/status-page.spec.js
+++ b/test/e2e/specs/status-page.spec.js
@@ -59,9 +59,8 @@ test.describe("Status Page", () => {
await page.getByTestId("show-tags-checkbox").uncheck();
await page.getByTestId("show-powered-by-checkbox").uncheck();
await page.getByTestId("show-certificate-expiry-checkbox").uncheck();
- await page.getByTestId("google-analytics-input").fill(googleAnalyticsId);
- await page.getByTestId("umami-analytics-domain-url-input").fill(umamiAnalyticsDomainUrl);
- await page.getByTestId("umami-analytics-website-id-input").fill(umamiAnalyticsWebsiteId);
+ await page.getByTestId("analytics-type-select").selectOption("google");
+ await page.getByTestId("analytics-id-input").fill(googleAnalyticsId);
await page.getByTestId("custom-css-input").getByTestId("textarea").fill(customCss); // Prism
await expect(page.getByTestId("description-editable")).toHaveText(descriptionText);
await expect(page.getByTestId("custom-footer-editable")).toHaveText(footerText);
@@ -104,14 +103,12 @@ test.describe("Status Page", () => {
expect(updateCountdown).toBeLessThanOrEqual(refreshInterval + 10);
await expect(page.locator("body")).toHaveClass(theme);
- expect(await page.locator("head").innerHTML()).toContain(googleAnalyticsId);
- expect(await page.locator("head").innerHTML()).toContain(umamiAnalyticsDomainUrl);
- expect(await page.locator("head").innerHTML()).toContain(umamiAnalyticsWebsiteId);
const backgroundColor = await page.evaluate(() => window.getComputedStyle(document.body).backgroundColor);
expect(backgroundColor).toEqual("rgb(0, 128, 128)");
await screenshot(testInfo, page);
+ expect(await page.locator("head").innerHTML()).toContain(googleAnalyticsId);
// Flip the "Show Tags" and "Show Powered By" switches:
await page.getByTestId("edit-button").click();
@@ -120,6 +117,11 @@ test.describe("Status Page", () => {
await page.getByTestId("show-powered-by-checkbox").setChecked(true);
await screenshot(testInfo, page);
+
+ // Fill in umami analytics after editing
+ await page.getByTestId("analytics-type-select").selectOption("umami");
+ await page.getByTestId("analytics-domain-url-input").fill(umamiAnalyticsDomainUrl);
+ await page.getByTestId("analytics-id-input").fill(umamiAnalyticsWebsiteId);
await page.getByTestId("save-button").click();
await expect(page.getByTestId("edit-sidebar")).toHaveCount(0);
@@ -127,6 +129,9 @@ test.describe("Status Page", () => {
await expect(page.getByTestId("monitor-tag")).toContainText(tagValue);
await screenshot(testInfo, page);
+
+ expect(await page.locator("head").innerHTML()).toContain(umamiAnalyticsDomainUrl);
+ expect(await page.locator("head").innerHTML()).toContain(umamiAnalyticsWebsiteId);
});
// @todo Test certificate expiry
From 6bade1fe812ef642589145d84ba96ab4955c38e4 Mon Sep 17 00:00:00 2001
From: hadestructhor <60148800+hadestructhor@users.noreply.github.com>
Date: Wed, 19 Feb 2025 00:08:30 +0100
Subject: [PATCH 4/6] feat: add support for plausible, cleanup and refactor
code
---
server/analytics/analytics.js | 44 ++++++++++++++++++++++
server/{ => analytics}/google-analytics.js | 0
server/analytics/plausible-analytics.js | 36 ++++++++++++++++++
server/{ => analytics}/umami-analytics.js | 0
server/model/status_page.js | 14 ++-----
test/e2e/specs/status-page.spec.js | 12 ++++++
6 files changed, 96 insertions(+), 10 deletions(-)
create mode 100644 server/analytics/analytics.js
rename server/{ => analytics}/google-analytics.js (100%)
create mode 100644 server/analytics/plausible-analytics.js
rename server/{ => analytics}/umami-analytics.js (100%)
diff --git a/server/analytics/analytics.js b/server/analytics/analytics.js
new file mode 100644
index 000000000..a5e2c1120
--- /dev/null
+++ b/server/analytics/analytics.js
@@ -0,0 +1,44 @@
+const googleAnalytics = require("./google-analytics");
+const umamiAnalytics = require("./umami-analytics");
+const plausibleAnalytics = require("./plausible-analytics");
+
+/**
+ * Returns a string that represents the javascript that is required to insert the selected Analytics' script
+ * into a webpage.
+ * @param {typeof import("../model/status_page").StatusPage} statusPage Status page populate HTML with
+ * @returns {string} HTML script tags to inject into page
+ */
+function getAnalyticsScript(statusPage) {
+ switch (statusPage.analyticsType) {
+ case "google":
+ return googleAnalytics.getGoogleAnalyticsScript(statusPage.analyticsId);
+ case "umami":
+ return umamiAnalytics.getUmamiAnalyticsScript(statusPage.analyticsDomainUrl, statusPage.analyticsId);
+ case "plausible":
+ return plausibleAnalytics.getPlausibleAnalyticsScript(statusPage.analyticsDomainUrl, statusPage.analyticsId);
+ default:
+ return null;
+ }
+}
+
+/**
+ * Function that checks wether the selected analytics has been configured properly
+ * @param {typeof import("../model/status_page").StatusPage} statusPage Status page populate HTML with
+ * @returns {boolean} Boolean defining if the analytics config is valid
+ */
+function isValidAnalyticsConfig(statusPage) {
+ switch (statusPage.analyticsType) {
+ case "google":
+ return statusPage.analyticsId != null;
+ case "umami":
+ case "plausible":
+ return statusPage.analyticsId != null && statusPage.analyticsDomainUrl != null;
+ default:
+ return false;
+ }
+}
+
+module.exports = {
+ getAnalyticsScript,
+ isValidAnalyticsConfig
+};
diff --git a/server/google-analytics.js b/server/analytics/google-analytics.js
similarity index 100%
rename from server/google-analytics.js
rename to server/analytics/google-analytics.js
diff --git a/server/analytics/plausible-analytics.js b/server/analytics/plausible-analytics.js
new file mode 100644
index 000000000..14df98115
--- /dev/null
+++ b/server/analytics/plausible-analytics.js
@@ -0,0 +1,36 @@
+const jsesc = require("jsesc");
+const { escape } = require("html-escaper");
+
+/**
+ * Returns a string that represents the javascript that is required to insert the Plausible Analytics script
+ * into a webpage.
+ * @param {string} plausibleDomainUrl Domain name with tld to use with the Plausible Analytics script.
+ * @param {string} domainsToMonitor Domains to track seperated by a ',' to add Plausible Analytics script.
+ * @returns {string} HTML script tags to inject into page
+ */
+function getPlausibleAnalyticsScript(plausibleDomainUrl, domainsToMonitor) {
+ let escapedDomainUrlJS = jsesc(plausibleDomainUrl, { isScriptContext: true });
+ let escapedWebsiteIdJS = jsesc(domainsToMonitor, { isScriptContext: true });
+
+ if (escapedDomainUrlJS) {
+ escapedDomainUrlJS = escapedDomainUrlJS.trim();
+ }
+
+ if (escapedWebsiteIdJS) {
+ escapedWebsiteIdJS = escapedWebsiteIdJS.trim();
+ }
+
+ // Escape the domain url for use in an HTML attribute.
+ let escapedDomainUrlHTMLAttribute = escape(escapedDomainUrlJS);
+
+ // Escape the website id for use in an HTML attribute.
+ let escapedWebsiteIdHTMLAttribute = escape(escapedWebsiteIdJS);
+
+ return `
+
+ `;
+}
+
+module.exports = {
+ getPlausibleAnalyticsScript
+};
diff --git a/server/umami-analytics.js b/server/analytics/umami-analytics.js
similarity index 100%
rename from server/umami-analytics.js
rename to server/analytics/umami-analytics.js
diff --git a/server/model/status_page.js b/server/model/status_page.js
index b3cf434cb..32188ffaa 100644
--- a/server/model/status_page.js
+++ b/server/model/status_page.js
@@ -3,8 +3,7 @@ const { R } = require("redbean-node");
const cheerio = require("cheerio");
const { UptimeKumaServer } = require("../uptime-kuma-server");
const jsesc = require("jsesc");
-const googleAnalytics = require("../google-analytics");
-const umamiAnalytics = require("../umami-analytics");
+const analytics = require("../analytics/analytics");
const { marked } = require("marked");
const { Feed } = require("feed");
const config = require("../config");
@@ -121,14 +120,9 @@ class StatusPage extends BeanModel {
const head = $("head");
- if (statusPage.analyticsType === "google" && statusPage.analyticsId) {
- let escapedGoogleAnalyticsScript = googleAnalytics.getGoogleAnalyticsScript(statusPage.analyticsId);
- head.append($(escapedGoogleAnalyticsScript));
- }
-
- if (statusPage.analyticsType === "umami" && statusPage.analyticsDomainUrl && statusPage.analyticsId) {
- let escapedUmamiAnalyticsScript = umamiAnalytics.getUmamiAnalyticsScript(statusPage.analyticsDomainUrl, statusPage.analyticsId);
- head.append($(escapedUmamiAnalyticsScript));
+ if (analytics.isValidAnalyticsConfig(statusPage)) {
+ let escapedAnalyticsScript = analytics.getAnalyticsScript(statusPage);
+ head.append($(escapedAnalyticsScript));
}
// OG Meta Tags
diff --git a/test/e2e/specs/status-page.spec.js b/test/e2e/specs/status-page.spec.js
index 9e5de4a43..43c5d43a6 100644
--- a/test/e2e/specs/status-page.spec.js
+++ b/test/e2e/specs/status-page.spec.js
@@ -20,6 +20,8 @@ test.describe("Status Page", () => {
const googleAnalyticsId = "G-123";
const umamiAnalyticsDomainUrl = "example.com";
const umamiAnalyticsWebsiteId = "606487e2-bc25-45f9-9132-fa8b065aad46";
+ const plausibleAnalyticsDomainUrl = "example.com";
+ const plausibleAnalyticsDomainsUrls = "one.com,two.com";
const customCss = "body { background: rgb(0, 128, 128) !important; }";
const descriptionText = "This is an example status page.";
const incidentTitle = "Example Outage Incident";
@@ -132,6 +134,16 @@ test.describe("Status Page", () => {
expect(await page.locator("head").innerHTML()).toContain(umamiAnalyticsDomainUrl);
expect(await page.locator("head").innerHTML()).toContain(umamiAnalyticsWebsiteId);
+
+ await page.getByTestId("edit-button").click();
+ // Fill in plausible analytics after editing
+ await page.getByTestId("analytics-type-select").selectOption("plausible");
+ await page.getByTestId("analytics-domain-url-input").fill(plausibleAnalyticsDomainUrl);
+ await page.getByTestId("analytics-id-input").fill(plausibleAnalyticsDomainsUrls);
+ await page.getByTestId("save-button").click();
+ await screenshot(testInfo, page);
+ expect(await page.locator("head").innerHTML()).toContain(plausibleAnalyticsDomainUrl);
+ expect(await page.locator("head").innerHTML()).toContain(plausibleAnalyticsDomainsUrls);
});
// @todo Test certificate expiry
From a1e63390ab974c48a2cf6592a60c22a773248868 Mon Sep 17 00:00:00 2001
From: hadestructhor <60148800+hadestructhor@users.noreply.github.com>
Date: Fri, 21 Feb 2025 23:26:44 +0100
Subject: [PATCH 5/6] feat: add Matomo analytics support
---
.../2025-02-17-2142-generalize-analytics.js | 2 +-
server/analytics/analytics.js | 4 ++
server/analytics/matomo-analytics.js | 47 +++++++++++++++++++
src/pages/StatusPage.vue | 4 ++
test/e2e/specs/status-page.spec.js | 12 +++++
5 files changed, 68 insertions(+), 1 deletion(-)
create mode 100644 server/analytics/matomo-analytics.js
diff --git a/db/knex_migrations/2025-02-17-2142-generalize-analytics.js b/db/knex_migrations/2025-02-17-2142-generalize-analytics.js
index 34a52224f..e4924feaf 100644
--- a/db/knex_migrations/2025-02-17-2142-generalize-analytics.js
+++ b/db/knex_migrations/2025-02-17-2142-generalize-analytics.js
@@ -4,7 +4,7 @@ exports.up = function (knex) {
.alterTable("status_page", function (table) {
table.renameColumn("google_analytics_tag_id", "analytics_id");
table.string("analytics_domain_url");
- table.enu("analytics_type", [ "google", "umami", "plausible" ]).defaultTo(null);
+ table.enu("analytics_type", [ "google", "umami", "plausible", "matomo" ]).defaultTo(null);
}).then(() => {
// After a succesful migration, add google as default for previous pages
diff --git a/server/analytics/analytics.js b/server/analytics/analytics.js
index a5e2c1120..79e570b9b 100644
--- a/server/analytics/analytics.js
+++ b/server/analytics/analytics.js
@@ -1,6 +1,7 @@
const googleAnalytics = require("./google-analytics");
const umamiAnalytics = require("./umami-analytics");
const plausibleAnalytics = require("./plausible-analytics");
+const matomoAnalytics = require("./matomo-analytics");
/**
* Returns a string that represents the javascript that is required to insert the selected Analytics' script
@@ -16,6 +17,8 @@ function getAnalyticsScript(statusPage) {
return umamiAnalytics.getUmamiAnalyticsScript(statusPage.analyticsDomainUrl, statusPage.analyticsId);
case "plausible":
return plausibleAnalytics.getPlausibleAnalyticsScript(statusPage.analyticsDomainUrl, statusPage.analyticsId);
+ case "matomo":
+ return matomoAnalytics.getMatomoAnalyticsScript(statusPage.analyticsDomainUrl, statusPage.analyticsId);
default:
return null;
}
@@ -32,6 +35,7 @@ function isValidAnalyticsConfig(statusPage) {
return statusPage.analyticsId != null;
case "umami":
case "plausible":
+ case "matomo":
return statusPage.analyticsId != null && statusPage.analyticsDomainUrl != null;
default:
return false;
diff --git a/server/analytics/matomo-analytics.js b/server/analytics/matomo-analytics.js
new file mode 100644
index 000000000..fdc009e63
--- /dev/null
+++ b/server/analytics/matomo-analytics.js
@@ -0,0 +1,47 @@
+const jsesc = require("jsesc");
+const { escape } = require("html-escaper");
+
+/**
+ * Returns a string that represents the javascript that is required to insert the Matomo Analytics script
+ * into a webpage.
+ * @param {string} matomoUrl Domain name with tld to use with the Matomo Analytics script.
+ * @param {string} siteId Site ID to use with the Matomo Analytics script.
+ * @returns {string} HTML script tags to inject into page
+ */
+function getMatomoAnalyticsScript(matomoUrl, siteId) {
+ let escapedMatomoUrlJS = jsesc(matomoUrl, { isScriptContext: true });
+ let escapedSiteIdJS = jsesc(siteId, { isScriptContext: true });
+
+ if (escapedMatomoUrlJS) {
+ escapedMatomoUrlJS = escapedMatomoUrlJS.trim();
+ }
+
+ if (escapedSiteIdJS) {
+ escapedSiteIdJS = escapedSiteIdJS.trim();
+ }
+
+ // Escape the domain url for use in an HTML attribute.
+ let escapedMatomoUrlHTMLAttribute = escape(escapedMatomoUrlJS);
+
+ // Escape the website id for use in an HTML attribute.
+ let escapedSiteIdHTMLAttribute = escape(escapedSiteIdJS);
+
+ return `
+
+ `;
+}
+
+module.exports = {
+ getMatomoAnalyticsScript,
+};
diff --git a/src/pages/StatusPage.vue b/src/pages/StatusPage.vue
index 983336de3..8a35fef60 100644
--- a/src/pages/StatusPage.vue
+++ b/src/pages/StatusPage.vue
@@ -16,6 +16,10 @@ const analyticsOptions = [
{
name: "Plausible",
value: "plausible"
+ },
+ {
+ name: "Matomo",
+ value: "matomo"
}
];
diff --git a/test/e2e/specs/status-page.spec.js b/test/e2e/specs/status-page.spec.js
index 43c5d43a6..e75f3c993 100644
--- a/test/e2e/specs/status-page.spec.js
+++ b/test/e2e/specs/status-page.spec.js
@@ -22,6 +22,8 @@ test.describe("Status Page", () => {
const umamiAnalyticsWebsiteId = "606487e2-bc25-45f9-9132-fa8b065aad46";
const plausibleAnalyticsDomainUrl = "example.com";
const plausibleAnalyticsDomainsUrls = "one.com,two.com";
+ const matomoUrl = "matomo.com";
+ const matomoSiteId = "123456789";
const customCss = "body { background: rgb(0, 128, 128) !important; }";
const descriptionText = "This is an example status page.";
const incidentTitle = "Example Outage Incident";
@@ -144,6 +146,16 @@ test.describe("Status Page", () => {
await screenshot(testInfo, page);
expect(await page.locator("head").innerHTML()).toContain(plausibleAnalyticsDomainUrl);
expect(await page.locator("head").innerHTML()).toContain(plausibleAnalyticsDomainsUrls);
+
+ await page.getByTestId("edit-button").click();
+ // Fill in matomo analytics after editing
+ await page.getByTestId("analytics-type-select").selectOption("matomo");
+ await page.getByTestId("analytics-domain-url-input").fill(matomoUrl);
+ await page.getByTestId("analytics-id-input").fill(matomoSiteId);
+ await page.getByTestId("save-button").click();
+ await screenshot(testInfo, page);
+ expect(await page.locator("head").innerHTML()).toContain(matomoUrl);
+ expect(await page.locator("head").innerHTML()).toContain(matomoSiteId);
});
// @todo Test certificate expiry
From 28e288db2ca52b28284e1b6f5943b4a5dcd07b4a Mon Sep 17 00:00:00 2001
From: hadestructhor <60148800+hadestructhor@users.noreply.github.com>
Date: Thu, 10 Apr 2025 23:48:46 +0200
Subject: [PATCH 6/6] fix(analytics): fixed issues with db init and refactor of
code and names
---
db/knex_init_db.js | 5 +----
.../2025-02-17-2142-generalize-analytics.js | 4 ++--
server/analytics/analytics.js | 8 ++++----
server/analytics/plausible-analytics.js | 14 +++++++-------
server/analytics/umami-analytics.js | 16 ++++++++--------
server/model/status_page.js | 4 ++--
.../status-page-socket-handler.js | 2 +-
src/lang/en.json | 10 ++++++----
src/pages/StatusPage.vue | 10 +++++-----
test/e2e/specs/status-page.spec.js | 16 ++++++++--------
10 files changed, 44 insertions(+), 45 deletions(-)
diff --git a/db/knex_init_db.js b/db/knex_init_db.js
index de9997dd4..46bff4bfa 100644
--- a/db/knex_init_db.js
+++ b/db/knex_init_db.js
@@ -202,10 +202,7 @@ async function createTables() {
table.text("footer_text");
table.text("custom_css");
table.boolean("show_powered_by").notNullable().defaultTo(true);
- table.string("analytics_id");
- table.string("analytics_domain_url");
- table.enu("analytics_type", [ "google", "umami", "plausible" ]).defaultTo(null);
-
+ table.string("google_analytics_tag_id");
});
// maintenance_status_page
diff --git a/db/knex_migrations/2025-02-17-2142-generalize-analytics.js b/db/knex_migrations/2025-02-17-2142-generalize-analytics.js
index e4924feaf..8c5fda990 100644
--- a/db/knex_migrations/2025-02-17-2142-generalize-analytics.js
+++ b/db/knex_migrations/2025-02-17-2142-generalize-analytics.js
@@ -3,7 +3,7 @@ exports.up = function (knex) {
return knex.schema
.alterTable("status_page", function (table) {
table.renameColumn("google_analytics_tag_id", "analytics_id");
- table.string("analytics_domain_url");
+ table.string("analytics_script_url");
table.enu("analytics_type", [ "google", "umami", "plausible", "matomo" ]).defaultTo(null);
}).then(() => {
@@ -17,7 +17,7 @@ exports.up = function (knex) {
exports.down = function (knex) {
return knex.schema.alterTable("status_page", function (table) {
table.renameColumn("analytics_id", "google_analytics_tag_id");
- table.dropColumn("analytics_domain_url");
+ table.dropColumn("analytics_script_url");
table.dropColumn("analytics_type");
});
};
diff --git a/server/analytics/analytics.js b/server/analytics/analytics.js
index 79e570b9b..229d463e0 100644
--- a/server/analytics/analytics.js
+++ b/server/analytics/analytics.js
@@ -14,11 +14,11 @@ function getAnalyticsScript(statusPage) {
case "google":
return googleAnalytics.getGoogleAnalyticsScript(statusPage.analyticsId);
case "umami":
- return umamiAnalytics.getUmamiAnalyticsScript(statusPage.analyticsDomainUrl, statusPage.analyticsId);
+ return umamiAnalytics.getUmamiAnalyticsScript(statusPage.analyticsScriptUrl, statusPage.analyticsId);
case "plausible":
- return plausibleAnalytics.getPlausibleAnalyticsScript(statusPage.analyticsDomainUrl, statusPage.analyticsId);
+ return plausibleAnalytics.getPlausibleAnalyticsScript(statusPage.analyticsScriptUrl, statusPage.analyticsId);
case "matomo":
- return matomoAnalytics.getMatomoAnalyticsScript(statusPage.analyticsDomainUrl, statusPage.analyticsId);
+ return matomoAnalytics.getMatomoAnalyticsScript(statusPage.analyticsScriptUrl, statusPage.analyticsId);
default:
return null;
}
@@ -36,7 +36,7 @@ function isValidAnalyticsConfig(statusPage) {
case "umami":
case "plausible":
case "matomo":
- return statusPage.analyticsId != null && statusPage.analyticsDomainUrl != null;
+ return statusPage.analyticsId != null && statusPage.analyticsScriptUrl != null;
default:
return false;
}
diff --git a/server/analytics/plausible-analytics.js b/server/analytics/plausible-analytics.js
index 14df98115..131f1136b 100644
--- a/server/analytics/plausible-analytics.js
+++ b/server/analytics/plausible-analytics.js
@@ -4,16 +4,16 @@ const { escape } = require("html-escaper");
/**
* Returns a string that represents the javascript that is required to insert the Plausible Analytics script
* into a webpage.
- * @param {string} plausibleDomainUrl Domain name with tld to use with the Plausible Analytics script.
+ * @param {string} scriptUrl the Plausible Analytics script url.
* @param {string} domainsToMonitor Domains to track seperated by a ',' to add Plausible Analytics script.
* @returns {string} HTML script tags to inject into page
*/
-function getPlausibleAnalyticsScript(plausibleDomainUrl, domainsToMonitor) {
- let escapedDomainUrlJS = jsesc(plausibleDomainUrl, { isScriptContext: true });
+function getPlausibleAnalyticsScript(scriptUrl, domainsToMonitor) {
+ let escapedScriptUrlJS = jsesc(scriptUrl, { isScriptContext: true });
let escapedWebsiteIdJS = jsesc(domainsToMonitor, { isScriptContext: true });
- if (escapedDomainUrlJS) {
- escapedDomainUrlJS = escapedDomainUrlJS.trim();
+ if (escapedScriptUrlJS) {
+ escapedScriptUrlJS = escapedScriptUrlJS.trim();
}
if (escapedWebsiteIdJS) {
@@ -21,13 +21,13 @@ function getPlausibleAnalyticsScript(plausibleDomainUrl, domainsToMonitor) {
}
// Escape the domain url for use in an HTML attribute.
- let escapedDomainUrlHTMLAttribute = escape(escapedDomainUrlJS);
+ let escapedScriptUrlHTMLAttribute = escape(escapedScriptUrlJS);
// Escape the website id for use in an HTML attribute.
let escapedWebsiteIdHTMLAttribute = escape(escapedWebsiteIdJS);
return `
-
+
`;
}
diff --git a/server/analytics/umami-analytics.js b/server/analytics/umami-analytics.js
index 5a4a172f9..48c8b2eca 100644
--- a/server/analytics/umami-analytics.js
+++ b/server/analytics/umami-analytics.js
@@ -4,30 +4,30 @@ const { escape } = require("html-escaper");
/**
* Returns a string that represents the javascript that is required to insert the Umami Analytics script
* into a webpage.
- * @param {string} domainUrl Domain name with tld to use with the Umami Analytics script.
+ * @param {string} scriptUrl the Umami Analytics script url.
* @param {string} websiteId Website ID to use with the Umami Analytics script.
* @returns {string} HTML script tags to inject into page
*/
-function getUmamiAnalyticsScript(domainUrl, websiteId) {
- let escapedDomainUrlJS = jsesc(domainUrl, { isScriptContext: true });
+function getUmamiAnalyticsScript(scriptUrl, websiteId) {
+ let escapedScriptUrlJS = jsesc(scriptUrl, { isScriptContext: true });
let escapedWebsiteIdJS = jsesc(websiteId, { isScriptContext: true });
- if (escapedDomainUrlJS) {
- escapedDomainUrlJS = escapedDomainUrlJS.trim();
+ if (escapedScriptUrlJS) {
+ escapedScriptUrlJS = escapedScriptUrlJS.trim();
}
if (escapedWebsiteIdJS) {
escapedWebsiteIdJS = escapedWebsiteIdJS.trim();
}
- // Escape the domain url for use in an HTML attribute.
- let escapedDomainUrlHTMLAttribute = escape(escapedDomainUrlJS);
+ // Escape the Script url for use in an HTML attribute.
+ let escapedScriptUrlHTMLAttribute = escape(escapedScriptUrlJS);
// Escape the website id for use in an HTML attribute.
let escapedWebsiteIdHTMLAttribute = escape(escapedWebsiteIdJS);
return `
-
+
`;
}
diff --git a/server/model/status_page.js b/server/model/status_page.js
index 32188ffaa..f4af41cfb 100644
--- a/server/model/status_page.js
+++ b/server/model/status_page.js
@@ -408,7 +408,7 @@ class StatusPage extends BeanModel {
footerText: this.footer_text,
showPoweredBy: !!this.show_powered_by,
analyticsId: this.analytics_id,
- analyticsDomainUrl: this.analytics_domain_url,
+ analyticsScriptUrl: this.analytics_script_url,
analyticsType: this.analytics_type,
showCertificateExpiry: !!this.show_certificate_expiry,
};
@@ -433,7 +433,7 @@ class StatusPage extends BeanModel {
footerText: this.footer_text,
showPoweredBy: !!this.show_powered_by,
analyticsId: this.analytics_id,
- analyticsDomainUrl: this.analytics_domain_url,
+ analyticsScriptUrl: this.analytics_script_url,
analyticsType: this.analytics_type,
showCertificateExpiry: !!this.show_certificate_expiry,
};
diff --git a/server/socket-handlers/status-page-socket-handler.js b/server/socket-handlers/status-page-socket-handler.js
index 60957d49d..5d0320e10 100644
--- a/server/socket-handlers/status-page-socket-handler.js
+++ b/server/socket-handlers/status-page-socket-handler.js
@@ -167,7 +167,7 @@ module.exports.statusPageSocketHandler = (socket) => {
statusPage.show_certificate_expiry = config.showCertificateExpiry;
statusPage.modified_date = R.isoDateTime();
statusPage.analytics_id = config.analyticsId;
- statusPage.analytics_domain_url = config.analyticsDomainUrl;
+ statusPage.analytics_script_url = config.analyticsScriptUrl;
statusPage.analytics_type = config.analyticsType;
await R.store(statusPage);
diff --git a/src/lang/en.json b/src/lang/en.json
index 94deb0a81..333e9e56f 100644
--- a/src/lang/en.json
+++ b/src/lang/en.json
@@ -789,9 +789,7 @@
"Google Analytics ID": "Google Analytics ID",
"Analytics Type": "Analytics Type",
"Analytics ID": "Analytics ID",
- "Analytics Domain URL": "Analytics Domain URL",
- "Umami Analytics Domain Url": "Umami Analytics Domain Url",
- "Umami Analytics Website ID": "Umami Analytics Website ID",
+ "Analytics Script URL": "Analytics Script URL",
"Edit Tag": "Edit Tag",
"Server Address": "Server Address",
"Learn More": "Learn More",
@@ -1072,5 +1070,9 @@
"YZJ Robot Token": "YZJ Robot token",
"Plain Text": "Plain Text",
"Message Template": "Message Template",
- "Template Format": "Template Format"
+ "Template Format": "Template Format",
+ "Google": "Google",
+ "Plausible": "Plausible",
+ "Matomo": "Matomo",
+ "Umami": "Umami"
}
diff --git a/src/pages/StatusPage.vue b/src/pages/StatusPage.vue
index 8a35fef60..78e592b36 100644
--- a/src/pages/StatusPage.vue
+++ b/src/pages/StatusPage.vue
@@ -124,19 +124,19 @@ const analyticsOptions = [