Add custom html code to head

With this PR a new text field will be added that allows setting custom
html code to the `<head>` of a status page.
The implementation will be similar to
https://github.com/louislam/uptime-kuma/pull/2567/files, but with a
multi-line text field and without escaping any special chars.

For security reasons the env var `UPTIME_KUMA_ALLOW_CUSTOM_HTML` must be set to `1` to enable this feature.

This will allow tracking with most analytic platforms and has been
requested several times.

Closes #2818
This commit is contained in:
mueller-ma 2024-02-16 08:22:54 +00:00 committed by Frank Elsinga
parent 10ebdcacaa
commit 7f0d3a3043
5 changed files with 33 additions and 0 deletions

View file

@ -0,0 +1,14 @@
exports.up = function (knex) {
// Insert column for custom HTML code
return knex.schema
.alterTable("status_page", function (table) {
table.text("custom_html").nullable().defaultTo(null);
});
};
exports.down = function (knex) {
return knex.schema
.alterTable("status_page", function (table) {
table.dropColumn("custom_html");
});
};

View file

@ -66,6 +66,10 @@ class StatusPage extends BeanModel {
head.append($(escapedGoogleAnalyticsScript)); head.append($(escapedGoogleAnalyticsScript));
} }
if (process.env.UPTIME_KUMA_ALLOW_CUSTOM_HTML === "1") {
head.append(statusPage.customHtml);
}
// OG Meta Tags // OG Meta Tags
let ogTitle = $("<meta property=\"og:title\" content=\"\" />").attr("content", statusPage.title); let ogTitle = $("<meta property=\"og:title\" content=\"\" />").attr("content", statusPage.title);
head.append(ogTitle); head.append(ogTitle);
@ -247,6 +251,7 @@ class StatusPage extends BeanModel {
showPoweredBy: !!this.show_powered_by, showPoweredBy: !!this.show_powered_by,
googleAnalyticsId: this.google_analytics_tag_id, googleAnalyticsId: this.google_analytics_tag_id,
showCertificateExpiry: !!this.show_certificate_expiry, showCertificateExpiry: !!this.show_certificate_expiry,
customHtml: this.custom_html
}; };
} }
@ -270,6 +275,7 @@ class StatusPage extends BeanModel {
showPoweredBy: !!this.show_powered_by, showPoweredBy: !!this.show_powered_by,
googleAnalyticsId: this.google_analytics_tag_id, googleAnalyticsId: this.google_analytics_tag_id,
showCertificateExpiry: !!this.show_certificate_expiry, showCertificateExpiry: !!this.show_certificate_expiry,
customHtml: this.custom_html
}; };
} }

View file

@ -167,6 +167,7 @@ module.exports.statusPageSocketHandler = (socket) => {
statusPage.show_certificate_expiry = config.showCertificateExpiry; statusPage.show_certificate_expiry = config.showCertificateExpiry;
statusPage.modified_date = R.isoDateTime(); statusPage.modified_date = R.isoDateTime();
statusPage.google_analytics_tag_id = config.googleAnalyticsId; statusPage.google_analytics_tag_id = config.googleAnalyticsId;
statusPage.custom_html = config.customHtml;
await R.store(statusPage); await R.store(statusPage);

View file

@ -776,6 +776,9 @@
"wayToGetClickSendSMSToken": "You can get API Username and API Key from {0} .", "wayToGetClickSendSMSToken": "You can get API Username and API Key from {0} .",
"Custom Monitor Type": "Custom Monitor Type", "Custom Monitor Type": "Custom Monitor Type",
"Google Analytics ID": "Google Analytics ID", "Google Analytics ID": "Google Analytics ID",
"Custom HTML": "Custom HTML",
"customHtmlEnvVar1": "The environment variable",
"customHtmlEnvVar2": "must be set to",
"Edit Tag": "Edit Tag", "Edit Tag": "Edit Tag",
"Server Address": "Server Address", "Server Address": "Server Address",
"Learn More": "Learn More", "Learn More": "Learn More",

View file

@ -104,6 +104,15 @@
<prism-editor v-model="config.customCSS" class="css-editor" :highlight="highlighter" line-numbers></prism-editor> <prism-editor v-model="config.customCSS" class="css-editor" :highlight="highlighter" line-numbers></prism-editor>
</div> </div>
<!-- Custom HTML -->
<div class="my-3">
<div class="mb-1">{{ $t("Custom HTML") }}</div>
<prism-editor v-model="config.customHtml" class="css-editor" :highlight="highlighter" line-numbers></prism-editor>
<div class="form-text">
{{ $t("customHtmlEnvVar1") }} <code>UPTIME_KUMA_ALLOW_CUSTOM_HTML</code> {{ $t("customHtmlEnvVar2") }} <code>1</code>.
</div>
</div>
<div class="danger-zone"> <div class="danger-zone">
<button class="btn btn-danger me-2" @click="deleteDialog"> <button class="btn btn-danger me-2" @click="deleteDialog">
<font-awesome-icon icon="trash" /> <font-awesome-icon icon="trash" />