fix: the build runs under a subpath, not only at the domain root

base './' emits relative asset URLs; the manifest, the service-worker
registration and sw.js's precache resolve against their own location;
the four hardcoded /image literals turn relative. Verified headless
under a simulated /edentext/ subpath: boots, types, SW scope correct.
This commit is contained in:
Steffen Becker committed 2026-08-17 18:59:48 +02:00
1 parent b37261375a
commit 3ae8d27b26
7 files changed
+21 -17

No files matched your search

+8 -8
View File
@@ -2,23 +2,23 @@
"name": "EdenText",
"short_name": "EdenText",
"description": "A word processor that runs in the browser and saves .odt and .docx. No account, no server: the document never leaves the machine.",
"id": "/",
"start_url": "/",
"scope": "/",
"id": "./",
"start_url": "./",
"scope": "./",
"display": "standalone",
"orientation": "any",
"background_color": "#e6e9eb",
"theme_color": "#52748b",
"categories": ["productivity", "utilities"],
"icons": [
{ "src": "/favicon.svg", "sizes": "any", "type": "image/svg+xml" },
{ "src": "/icon-192.png", "sizes": "192x192", "type": "image/png" },
{ "src": "/icon-512.png", "sizes": "512x512", "type": "image/png" },
{ "src": "/icon-512.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable" }
{ "src": "favicon.svg", "sizes": "any", "type": "image/svg+xml" },
{ "src": "icon-192.png", "sizes": "192x192", "type": "image/png" },
{ "src": "icon-512.png", "sizes": "512x512", "type": "image/png" },
{ "src": "icon-512.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable" }
],
"file_handlers": [
{
"action": "/",
"action": "./",
"accept": {
"application/vnd.oasis.opendocument.text": [".odt"],
"application/vnd.oasis.opendocument.text-template": [".ott"],
+5 -4
View File
@@ -3,8 +3,9 @@
// fonts and the WASM speller included, each kept the first time it is asked for.
const CACHE = 'edentext-v1';
// The entry document under one key, whichever path asked for it.
const SHELL = '/';
// The entry document under one key, whichever path asked for it. Relative, so it
// resolves against this script's own directory — the app root under any base path.
const SHELL = './';
// The build's asset names carry a content hash, and the entry document is the only
// place they are written down — so reading them out of it precaches the shell with no
@@ -15,8 +16,8 @@ async function precache(cache) {
const response = await fetch(SHELL, { cache: 'reload' });
await cache.put(SHELL, response.clone());
const html = await response.text();
const assets = [...html.matchAll(/(?:src|href)="(\/assets\/[^"]+)"/g)].map((m) => m[1]);
await cache.addAll([...new Set(assets), '/favicon.svg', '/manifest.webmanifest']);
const assets = [...html.matchAll(/(?:src|href)="(\.?\/assets\/[^"]+)"/g)].map((m) => m[1]);
await cache.addAll([...new Set(assets), './favicon.svg', './manifest.webmanifest']);
}
self.addEventListener('install', (event) => {
+1 -1
View File
@@ -1130,7 +1130,7 @@
<div class="toolbar-stack" bind:this={toolbarStackEl} style="transform: translateX(-{tbScroll}px);">
<header class:expanded={toolbarExpanded}>
<button class="logo-btn" onclick={() => (aboutOpen = true)} aria-label={t().about.label} title={t().about.label}>
<img src="/EdenText.png" alt="EdenText" class="app-logo" />
<img src="EdenText.png" alt="EdenText" class="app-logo" />
</button>
<Toolbar editor={activeEditor} tick={activeTick} onManageStyles={openStyleManager} />
<div class="header-actions">
+2 -2
View File
@@ -40,9 +40,9 @@
</svg>
</button>
<img class="icon" src="/favicon.svg" alt="" aria-hidden="true" />
<img class="icon" src="favicon.svg" alt="" aria-hidden="true" />
<img class="logo" src="/EdenText.png" alt="EdenText" />
<img class="logo" src="EdenText.png" alt="EdenText" />
<p class="tagline">{t().about.tagline}</p>
+1 -1
View File
@@ -330,7 +330,7 @@
<UiLanguagePicker />
<button class="rb-logo-btn" onclick={() => run(onAbout)} title={t().about.label} aria-label={t().about.label}>
<img src="/favicon.svg" alt="" aria-hidden="true" />
<img src="favicon.svg" alt="" aria-hidden="true" />
</button>
</div>
+1 -1
View File
@@ -19,7 +19,7 @@ window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', ()
// build over the one being edited.
if (import.meta.env.PROD && 'serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/sw.js').catch(() => {});
navigator.serviceWorker.register(`${import.meta.env.BASE_URL}sw.js`).catch(() => {});
});
}
+3
View File
@@ -4,6 +4,9 @@ import { svelte } from '@sveltejs/vite-plugin-svelte';
import pkg from './package.json' with { type: 'json' };
export default defineConfig({
// Relative asset URLs, so the same build works at the domain root and under a
// subpath (GitHub Pages project site). sw.js and the manifest are relative too.
base: './',
plugins: [svelte()],
define: { __APP_VERSION__: JSON.stringify(pkg.version) },
// hunspell-asm's ESM chain calls CJS/UMD deps as functions that a bundler