diff --git a/config/vite.config.js b/config/vite.config.js
index a9701d426..f384e95c3 100644
--- a/config/vite.config.js
+++ b/config/vite.config.js
@@ -7,6 +7,7 @@ const postcssRTLCSS = require("postcss-rtlcss");
// https://vitejs.dev/config/
export default defineConfig({
+ base: "./",
plugins: [
vue(),
legacy({
diff --git a/index.html b/index.html
index 6a5525fb4..6d3c73c9e 100644
--- a/index.html
+++ b/index.html
@@ -1,17 +1,18 @@
+
-
-
-
+
+
+
Uptime Kuma
-
+
diff --git a/public/manifest.json b/public/manifest.json
index 38e1d17da..6be46ad73 100644
--- a/public/manifest.json
+++ b/public/manifest.json
@@ -1,7 +1,7 @@
{
"name": "Uptime Kuma",
"short_name": "Uptime Kuma",
- "start_url": "/",
+ "start_url": "./",
"background_color": "#fff",
"display": "standalone",
"icons": [
diff --git a/server/server.js b/server/server.js
index 868bbd5ef..958aba691 100644
--- a/server/server.js
+++ b/server/server.js
@@ -76,6 +76,8 @@ if (hostname) {
const port = parseInt(process.env.UPTIME_KUMA_PORT || process.env.PORT || args.port || 3001);
+const basePath = process.env.UPTIME_KUMA_BASE_PATH || process.env.BASE_PATH || '/'
+
// SSL
const sslKey = process.env.UPTIME_KUMA_SSL_KEY || process.env.SSL_KEY || args["ssl-key"] || undefined;
const sslCert = process.env.UPTIME_KUMA_SSL_CERT || process.env.SSL_CERT || args["ssl-cert"] || undefined;
@@ -113,7 +115,7 @@ if (sslKey && sslCert) {
server = http.createServer(app);
}
-const io = new Server(server);
+const io = new Server(server, {path: basePath + '/socket.io'});
module.exports.io = io;
// Must be after io instantiation
@@ -165,6 +167,7 @@ let indexHTML = "";
try {
indexHTML = fs.readFileSync("./dist/index.html").toString();
+ indexHTML = indexHTML.replace(/\/, ``);
} catch (e) {
// "dist/index.html" is not necessary for development
if (process.env.NODE_ENV !== "development") {
@@ -180,6 +183,8 @@ exports.entryPage = "dashboard";
await initDatabase(testMode);
exports.entryPage = await setting("entryPage");
+
+ const mainRouter = express.Router();
console.log("Adding route");
@@ -188,16 +193,16 @@ exports.entryPage = "dashboard";
// ***************************
// Entry Page
- app.get("/", async (_request, response) => {
+ mainRouter.get("/", async (_request, response) => {
if (exports.entryPage === "statusPage") {
- response.redirect("/status");
+ response.redirect("status");
} else {
- response.redirect("/dashboard");
+ response.redirect("dashboard");
}
});
// Robots.txt
- app.get("/robots.txt", async (_request, response) => {
+ mainRouter.get("/robots.txt", async (_request, response) => {
let txt = "User-agent: *\nDisallow:";
if (! await setting("searchEngineIndex")) {
txt += " /";
@@ -210,29 +215,31 @@ exports.entryPage = "dashboard";
// Prometheus API metrics /metrics
// With Basic Auth using the first user's username/password
- app.get("/metrics", basicAuth, prometheusAPIMetrics());
+ mainRouter.get("/metrics", basicAuth, prometheusAPIMetrics());
- app.use("/", express.static("dist"));
+ mainRouter.use("/", express.static("dist"));
// ./data/upload
- app.use("/upload", express.static(Database.uploadDir));
+ mainRouter.use("/upload", express.static(Database.uploadDir));
- app.get("/.well-known/change-password", async (_, response) => {
+ mainRouter.get("/.well-known/change-password", async (_, response) => {
response.redirect("https://github.com/louislam/uptime-kuma/wiki/Reset-Password-via-CLI");
});
// API Router
const apiRouter = require("./routers/api-router");
- app.use(apiRouter);
+ mainRouter.use(apiRouter);
// Universal Route Handler, must be at the end of all express routes.
- app.get("*", async (_request, response) => {
+ mainRouter.get("*", async (_request, response) => {
if (_request.originalUrl.startsWith("/upload/")) {
response.status(404).send("File not found.");
} else {
response.send(indexHTML);
}
});
+
+ app.use(basePath, mainRouter);
console.log("Adding socket handler");
io.on("connection", async (socket) => {
diff --git a/server/socket-handlers/status-page-socket-handler.js b/server/socket-handlers/status-page-socket-handler.js
index 5826277c7..2ed727bc5 100644
--- a/server/socket-handlers/status-page-socket-handler.js
+++ b/server/socket-handlers/status-page-socket-handler.js
@@ -90,7 +90,7 @@ module.exports.statusPageSocketHandler = (socket) => {
// Convert to file
await ImageDataURI.outputFile(imgDataUrl, Database.uploadDir + "logo.png");
- config.logo = "/upload/logo.png?t=" + Date.now();
+ config.logo = "./upload/logo.png?t=" + Date.now();
} else {
config.icon = imgDataUrl;
diff --git a/src/layouts/Layout.vue b/src/layouts/Layout.vue
index 75173e1fc..e1536a0d9 100644
--- a/src/layouts/Layout.vue
+++ b/src/layouts/Layout.vue
@@ -19,9 +19,9 @@
-
-
+
{{ $t("Status Page") }}
-
+
-
diff --git a/src/mixins/socket.js b/src/mixins/socket.js
index affac4f82..dc0459938 100644
--- a/src/mixins/socket.js
+++ b/src/mixins/socket.js
@@ -67,8 +67,11 @@ export default {
wsHost = protocol + location.host;
}
+ const urlBase = document.querySelector("head base").getAttribute("href");
+
socket = io(wsHost, {
transports: ["websocket"],
+ path: urlBase + "/socket.io"
});
socket.on("info", (info) => {
diff --git a/vue.config.js b/vue.config.js
new file mode 100644
index 000000000..20ae687d2
--- /dev/null
+++ b/vue.config.js
@@ -0,0 +1,3 @@
+module.exports = {
+ publicPath: './',
+}