Skip to content

Commit 9c5055d

Browse files
committed
fix: preserve clean home routing under subpaths
1 parent e5c4765 commit 9c5055d

5 files changed

Lines changed: 21 additions & 5 deletions

File tree

404.html

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@
1515
var routeIndex = segments.findIndex(function (segment) {
1616
return segment === 'editor' || segment === 'exam' || segment === 'study' || segment === 'privacy-and-storage' || segment === 'roadmaps';
1717
});
18-
var base = '/' + (routeIndex > 0 ? segments.slice(0, routeIndex).join('/') + '/' : '');
18+
var baseSegments = routeIndex > 0
19+
? segments.slice(0, routeIndex)
20+
: (routeIndex === -1 ? segments.slice(0, -1) : []);
21+
var base = '/' + (baseSegments.length ? baseSegments.join('/') + '/' : '');
1922
var route = routeIndex >= 0 ? segments[routeIndex] : '';
2023
var params = new URLSearchParams(window.location.search);
2124
var target = '';

assets/js/router.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,10 @@
4444

4545
// The hosted homepage always resolves at the base path, even before a
4646
// service worker controls the page. Keep index.html only for file mode.
47-
if (!isFileMode() && page === 'home') return withBase('');
47+
if (!isFileMode() && page === 'home') {
48+
const homeUrl = withBase('');
49+
return queryString ? `${homeUrl}?${queryString}` : homeUrl;
50+
}
4851

4952
if (!cleanRoutesSupported()) {
5053
const fileMap = {

tests/browser-smoke.mjs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,10 +320,15 @@ try {
320320
const labsHomeHrefs = await labsPage.locator('a[data-route="home"]').evaluateAll(
321321
(links) => links.map((link) => link.getAttribute('href'))
322322
);
323+
const siteRootUrl = new URL('/', labsPage.url());
323324
assert.equal(labsHomeHrefs.length, 2, 'The labs page must expose both Home actions through the router.');
324325
for (const href of labsHomeHrefs) {
325326
assert.ok(href, 'A labs Home action must have a destination.');
326-
assert.doesNotMatch(href, /index\.html/, 'Hosted labs Home actions must not expose index.html.');
327+
assert.equal(
328+
new URL(href, labsPage.url()).href,
329+
siteRootUrl.href,
330+
'Hosted labs Home actions must route to the clean site root.'
331+
);
327332
}
328333
const importedLabHrefs = await labsPage.locator('.lab-refs a').evaluateAll(
329334
(links) => links.map((link) => link.href)

tests/test_phase1_2_foundations.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ def test_localhost_requires_an_active_service_worker_for_clean_routes(self):
225225
226226
vm.runInNewContext(source, sandbox);
227227
const router = sandbox.window.ExamApp.router;
228-
const homeWithoutController = router.buildUrl('home');
228+
const homeWithoutController = router.buildUrl('home', { utm_source: 'labs' });
229229
sandbox.window.location.pathname = '/examplar/labs.html';
230230
const labsHomeWithoutController = router.buildUrl('home');
231231
sandbox.window.location.pathname = '/examplar/index.html';
@@ -239,7 +239,7 @@ def test_localhost_requires_an_active_service_worker_for_clean_routes(self):
239239
"""
240240
payload = run_node_snippet(script_path, node_script)
241241

242-
self.assertEqual("/examplar/", payload["homeWithoutController"])
242+
self.assertEqual("/examplar/?utm_source=labs", payload["homeWithoutController"])
243243
self.assertEqual("/examplar/", payload["labsHomeWithoutController"])
244244
self.assertEqual("roadmaps.html", payload["withoutController"])
245245
self.assertEqual("/examplar/roadmaps", payload["withController"])

tests/test_server_routes.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ def test_roadmaps_fallback_preserves_hosted_base_and_query(self):
139139
140140
console.log(JSON.stringify({
141141
home: resolve('/missing-page', '?utm_source=linkedin&empty='),
142+
projectHome: resolve('/examplar/missing-page', '?utm_campaign=refresh'),
142143
root: resolve('/roadmaps', '?utm_source=linkedin&empty='),
143144
project: resolve('/examplar/roadmaps', '?utm_campaign=refresh')
144145
}));
@@ -156,6 +157,10 @@ def test_roadmaps_fallback_preserves_hosted_base_and_query(self):
156157
"/?utm_source=linkedin&empty=",
157158
payload["home"],
158159
)
160+
self.assertEqual(
161+
"/examplar/?utm_campaign=refresh",
162+
payload["projectHome"],
163+
)
159164
self.assertEqual(
160165
"/roadmaps.html?utm_source=linkedin&empty=",
161166
payload["root"],

0 commit comments

Comments
 (0)