Compare commits

...

4 Commits

Author SHA1 Message Date
google-labs-jules[bot] 137db18897 feat: dynamically set PWA start_url
This commit fixes an issue where the PWA would always start at the
root of the application, regardless of the page you were on when
you installed it.

This is fixed by:
- Consolidating the two manifest files into a single file.
- Adding a new route to the server that dynamically generates the
  `start_url` in the manifest based on the current route.
- Adding an e2e test to verify the changes.
2025-07-26 14:23:17 +00:00
google-labs-jules[bot] 65e8894cf5 feat: dynamically set PWA start_url
This commit fixes an issue where the PWA would always start at the
root of the application, regardless of the page you were on when
you installed it.

This is fixed by:
- Consolidating the two manifest files into a single file.
- Adding a new route to the server that dynamically generates the
  `start_url` in the manifest based on the current route.
- Adding an e2e test to verify the changes.
2025-07-26 14:22:49 +00:00
google-labs-jules[bot] 2683f1a1e0 feat: dynamically set PWA start_url
This commit fixes an issue where the PWA would always start at the
root of the application, regardless of the page you were on when
you installed it.

This is fixed by:
- Consolidating the two manifest files into a single file.
- Adding a new route to the server that dynamically generates the
  `start_url` in the manifest based on the current route.
- Adding an e2e test to verify the changes.
2025-07-26 14:22:21 +00:00
google-labs-jules[bot] 84459b06e2 feat: dynamically set PWA start_url
This commit fixes an issue where the PWA would always start at the
root of the application, regardless of the page you were on when
you installed it.

This is fixed by:
- Consolidating the two manifest files into a single file.
- Adding a new route to the server that dynamically generates the
  `start_url` in the manifest based on the current route.
- Adding an e2e test to verify the changes.
2025-07-24 17:27:02 +00:00
8 changed files with 80 additions and 32 deletions
+1 -2
View File
@@ -9,8 +9,7 @@
<meta name="ontime" content="ontime - time keeping for live events" />
<link rel="apple-touch-icon" href="/ontime-logo.png" />
<link rel="icon" type="image/png" href="/ontime-logo.png" />
<link rel="manifest" href="/site.webmanifest" />
<link rel="manifest" href="/manifest.json" />
<link rel="manifest" href="/manifest.webmanifest" />
<meta name="robots" content="noindex" />
<title>ontime</title>
<style>
-19
View File
@@ -1,19 +0,0 @@
{
"name": "ontime",
"short_name": "ontime",
"icons": [
{
"src": "favicon.ico",
"type": "image/x-icon"
},
{
"src": "ontime-logo.png",
"type": "image/png"
}
],
"scope": "/",
"start_url": "/",
"display": "",
"theme_color": "#121212",
"background_color": "#ffffff"
}
+15
View File
@@ -0,0 +1,15 @@
{
"name": "ontime",
"short_name": "ontime",
"icons": [
{
"src": "/ontime-logo.png",
"sizes": "295x295",
"type": "image/png"
}
],
"scope": "/",
"display": "standalone",
"theme_color": "#2B5ABC",
"background_color": "#101010"
}
-10
View File
@@ -1,10 +0,0 @@
{
"name": "",
"short_name": "",
"icons": [
{ "src": "/ontime-logo.png", "sizes": "295x295", "type": "image/png" }
],
"theme_color": "#2B5ABC",
"background_color": "#101010",
"display": "standalone"
}
+19
View File
@@ -8,6 +8,8 @@ import serverTiming from 'server-timing';
import cookieParser from 'cookie-parser';
// import utils
import { readFileSync } from 'node:fs';
import { join } from 'node:path';
import { publicDir, srcDir } from './setup/index.js';
import { environment, isProduction } from './setup/environment.js';
import { updateRouterPrefix } from './externals.js';
@@ -98,6 +100,23 @@ app.use(`${prefix}/user`, express.static(publicDir.userDir, { etag: false, lastM
// Base route for static files
app.use(`${prefix}`, authenticateAndRedirect, compressedStatic);
app.get(`${prefix}/manifest.webmanifest`, (req, res) => {
// get the referer, if it doesnt exist, we send the default manifest
const referer = req.headers.referer || '/';
// read the manifest file
const manifest = JSON.parse(
readFileSync(join(publicDir.root, 'manifest.webmanifest'), 'utf-8'),
);
// set the start_url to the referer
manifest.start_url = referer;
// send the manifest
res.json(manifest);
});
app.use(`${prefix}/*splat`, authenticateAndRedirect, compressedStatic);
// Implement catch all
@@ -0,0 +1,37 @@
import { test, expect } from '@playwright/test';
test('manifest start_url is correct for cuesheet', async ({ page }) => {
await page.goto('/cuesheet');
const manifestUrl = await page.evaluate(() => {
const link = document.querySelector('link[rel="manifest"]');
if (!link) {
return null;
}
return (link as HTMLLinkElement).href;
});
expect(manifestUrl).not.toBeNull();
const response = await page.request.get(manifestUrl!);
const manifest = await response.json();
expect(manifest.start_url).toContain('/cuesheet');
});
test('manifest start_url is correct for op', async ({ page }) => {
await page.goto('/op');
const manifestUrl = await page.evaluate(() => {
const link = document.querySelector('link[rel="manifest"]');
if (!link) {
return null;
}
return (link as HTMLLinkElement).href;
});
expect(manifestUrl).not.toBeNull();
const response = await page.request.get(manifestUrl!);
const manifest = await response.json();
expect(manifest.start_url).toContain('/op');
});
+4 -1
View File
@@ -51,5 +51,8 @@
"turbo": "^2.3.3",
"typescript": "catalog:"
},
"packageManager": "pnpm@10.11.0+sha512.6540583f41cc5f628eb3d9773ecee802f4f9ef9923cc45b69890fb47991d4b092964694ec3a4f738a420c918a333062c8b925d312f42e4f0c263eb603551f977"
"packageManager": "pnpm@10.11.0+sha512.6540583f41cc5f628eb3d9773ecee802f4f9ef9923cc45b69890fb47991d4b092964694ec3a4f738a420c918a333062c8b925d312f42e4f0c263eb603551f977",
"dependencies": {
"tsx": "^4.20.3"
}
}
+4
View File
@@ -37,6 +37,10 @@ catalogs:
importers:
.:
dependencies:
tsx:
specifier: ^4.20.3
version: 4.20.3
devDependencies:
'@playwright/test':
specifier: ^1.51.1