PWA: absolutte stier så dyplenker virker ved kald førstelast

shelter-repository.ts hentet './data/shelters.json' relativt. Under
/shelter/{romnr} løses det til /shelter/data/shelters.json; SPA-fallback
svarer med index.html (200 text/html), response.json() kaster,
refreshData() returnerer false og loadData() avbryter før
handleDeepLink() — førstegangsbesøkende via delt lenke fikk «Fant ikke
tilfluktsrommet» og tom liste.

Samme rotårsak i index.html (manifest.webmanifest, icons/icon-192.png)
og i manifestet (start_url/scope ".", icons "icons/…"): under en
dyplenke-rute ble manifestet index.html og «legg til på startskjerm»
uteble.

- shelter-repository.ts: `${import.meta.env.BASE_URL}data/shelters.json`
- index.html: /manifest.webmanifest, /icons/icon-192.png
- manifest.webmanifest: start_url "/", scope "/", icons "/icons/…"

Verifisert i ny Playwright-kontekst (tom IndexedDB): /shelter/1681 laster
/data/shelters.json (200 application/json), lista fylles og rommet velges.

Forgejo: #19

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FrDGDmN2WAXvNPS85rWJGK
This commit is contained in:
Ole-Morten Duesund 2026-08-17 12:50:56 +02:00
commit 2a0c9b49ce
4 changed files with 15 additions and 8 deletions

View file

@ -15,9 +15,9 @@
<meta http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https://*.tile.openstreetmap.org; connect-src 'self' https://*.tile.openstreetmap.org; font-src 'self'; worker-src 'self'" />
<title>Tilfluktsrom</title>
<link rel="manifest" href="manifest.webmanifest" />
<link rel="icon" type="image/png" sizes="192x192" href="icons/icon-192.png" />
<link rel="apple-touch-icon" href="icons/icon-192.png" />
<link rel="manifest" href="/manifest.webmanifest" />
<link rel="icon" type="image/png" sizes="192x192" href="/icons/icon-192.png" />
<link rel="apple-touch-icon" href="/icons/icon-192.png" />
</head>
<body>
<div id="app">

View file

@ -2,21 +2,21 @@
"name": "Tilfluktsrom",
"short_name": "Tilfluktsrom",
"description": "Find the nearest public shelter in Norway",
"start_url": ".",
"scope": ".",
"start_url": "/",
"scope": "/",
"display": "standalone",
"orientation": "portrait",
"theme_color": "#1A1A2E",
"background_color": "#1A1A2E",
"icons": [
{
"src": "icons/icon-192.png",
"src": "/icons/icon-192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any maskable"
},
{
"src": "icons/icon-512.png",
"src": "/icons/icon-512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "any maskable"

View file

@ -14,7 +14,13 @@ import {
isDataStale,
} from './shelter-db';
const SHELTERS_JSON_PATH = './data/shelters.json';
// Absolute path anchored at Vite's base URL — NOT a relative './data/...'.
// The app is also entered via /shelter/{romnr} deep links, and a relative
// path would resolve to /shelter/data/shelters.json there; the SPA fallback
// answers that with index.html and the JSON parse fails, so a first-time
// visitor following a shared link would see "shelter not found". Using
// BASE_URL keeps this correct even if the app is ever hosted under a prefix.
const SHELTERS_JSON_PATH = `${import.meta.env.BASE_URL}data/shelters.json`;
/** Fetch shelters.json and cache in IndexedDB. Returns success. */
export async function refreshData(): Promise<boolean> {