diff --git a/webui/native/dist/index.html b/webui/native/dist/index.html
index 6902014d..0e958324 100644
--- a/webui/native/dist/index.html
+++ b/webui/native/dist/index.html
@@ -31,15 +31,15 @@
diff --git a/webui/native/svelte.config.js b/webui/native/svelte.config.js
index a5ce70d0..8a17ed9c 100644
--- a/webui/native/svelte.config.js
+++ b/webui/native/svelte.config.js
@@ -1,5 +1,21 @@
+import { readFileSync } from 'node:fs';
+
import adapter from '@sveltejs/adapter-static';
+// SvelteKit defaults kit.version.name to Date.now(), and derives the
+// __sveltekit_ global it embeds in dist/index.html from it. That makes the
+// built bundle different on every run, and dist/index.html is committed -- so
+// any two branches that rebuild the web UI conflict in it, whether or not their
+// source changes overlap.
+//
+// The package version is stable for a given source tree, so the bundle is
+// reproducible, while still changing when the version is bumped -- which is
+// what SvelteKit's client-side "app has been updated" check needs to keep
+// working across releases.
+const { version } = JSON.parse(
+ readFileSync(new URL('./package.json', import.meta.url), 'utf8')
+);
+
/** @type {import('@sveltejs/kit').Config} */
const config = {
kit: {
@@ -17,6 +33,9 @@ const config = {
},
paths: {
relative: true
+ },
+ version: {
+ name: version
}
}
};