Skip to content

Commit 4c447f2

Browse files
Deploy 56ed434: fix: rewrite legacy hash URLs with replaceState, not a navigation
1 parent bc74816 commit 4c447f2

96 files changed

Lines changed: 2016 additions & 1440 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎404.html‎

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,31 @@
66
<meta name="viewport" content="width=device-width, initial-scale=1" />
77
<script>
88
// The site was hash-routed until mid-2026, so old links look like
9-
// gpu.rocks/#/learn/1-2/3. Rewrite them onto real paths before anything
10-
// else loads (zero app boot on the wrong URL). Plain in-page anchors
11-
// don't start with "#/" and are left alone.
9+
// gpu.rocks/#/learn/1-2/3. Rewrite them onto real paths before the app
10+
// boots. replaceState only — never location.replace: a real navigation
11+
// here loops forever in webviews that re-open the originally requested
12+
// URL on instant redirects (seen in Telegram's in-app browser). Every
13+
// path serves this same shell, so the SPA boots correctly on the
14+
// rewritten URL with no network round-trip at all. Plain in-page
15+
// anchors don't start with "#/" and are left alone.
1216
(function () {
1317
var hash = window.location.hash;
18+
var path = window.location.pathname;
19+
var target = null;
1420
if (hash.length > 1 && hash.charAt(1) === '/') {
15-
window.location.replace(hash.slice(1) + window.location.search);
16-
return;
21+
target = hash.slice(1) + window.location.search;
22+
} else if (path.length > 1 && path.charAt(path.length - 1) === '/') {
23+
// GitHub Pages 301-redirects directory URLs to a trailing slash
24+
// (/learn → /learn/). Strip it so the address bar shows the
25+
// canonical path.
26+
target = path.replace(/\/+$/, '') + window.location.search + hash;
1727
}
18-
// GitHub Pages 301-redirects directory URLs to a trailing slash
19-
// (/learn → /learn/). Strip it so the address bar always shows the
20-
// canonical path; replaceState costs no request and no reload.
21-
var path = window.location.pathname;
22-
if (path.length > 1 && path.charAt(path.length - 1) === '/') {
23-
window.history.replaceState(
24-
null,
25-
'',
26-
path.replace(/\/+$/, '') + window.location.search
27-
);
28+
if (target !== null) {
29+
try {
30+
window.history.replaceState(null, '', target);
31+
} catch (e) {
32+
// sandboxed webview without history access — boot on the URL as-is
33+
}
2834
}
2935
})();
3036
</script>

‎benchmark/index.html‎

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,31 @@
66
<meta name="viewport" content="width=device-width, initial-scale=1" />
77
<script>
88
// The site was hash-routed until mid-2026, so old links look like
9-
// gpu.rocks/#/learn/1-2/3. Rewrite them onto real paths before anything
10-
// else loads (zero app boot on the wrong URL). Plain in-page anchors
11-
// don't start with "#/" and are left alone.
9+
// gpu.rocks/#/learn/1-2/3. Rewrite them onto real paths before the app
10+
// boots. replaceState only — never location.replace: a real navigation
11+
// here loops forever in webviews that re-open the originally requested
12+
// URL on instant redirects (seen in Telegram's in-app browser). Every
13+
// path serves this same shell, so the SPA boots correctly on the
14+
// rewritten URL with no network round-trip at all. Plain in-page
15+
// anchors don't start with "#/" and are left alone.
1216
(function () {
1317
var hash = window.location.hash;
18+
var path = window.location.pathname;
19+
var target = null;
1420
if (hash.length > 1 && hash.charAt(1) === '/') {
15-
window.location.replace(hash.slice(1) + window.location.search);
16-
return;
21+
target = hash.slice(1) + window.location.search;
22+
} else if (path.length > 1 && path.charAt(path.length - 1) === '/') {
23+
// GitHub Pages 301-redirects directory URLs to a trailing slash
24+
// (/learn → /learn/). Strip it so the address bar shows the
25+
// canonical path.
26+
target = path.replace(/\/+$/, '') + window.location.search + hash;
1727
}
18-
// GitHub Pages 301-redirects directory URLs to a trailing slash
19-
// (/learn → /learn/). Strip it so the address bar always shows the
20-
// canonical path; replaceState costs no request and no reload.
21-
var path = window.location.pathname;
22-
if (path.length > 1 && path.charAt(path.length - 1) === '/') {
23-
window.history.replaceState(
24-
null,
25-
'',
26-
path.replace(/\/+$/, '') + window.location.search
27-
);
28+
if (target !== null) {
29+
try {
30+
window.history.replaceState(null, '', target);
31+
} catch (e) {
32+
// sandboxed webview without history access — boot on the URL as-is
33+
}
2834
}
2935
})();
3036
</script>

‎examples/index.html‎

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,31 @@
66
<meta name="viewport" content="width=device-width, initial-scale=1" />
77
<script>
88
// The site was hash-routed until mid-2026, so old links look like
9-
// gpu.rocks/#/learn/1-2/3. Rewrite them onto real paths before anything
10-
// else loads (zero app boot on the wrong URL). Plain in-page anchors
11-
// don't start with "#/" and are left alone.
9+
// gpu.rocks/#/learn/1-2/3. Rewrite them onto real paths before the app
10+
// boots. replaceState only — never location.replace: a real navigation
11+
// here loops forever in webviews that re-open the originally requested
12+
// URL on instant redirects (seen in Telegram's in-app browser). Every
13+
// path serves this same shell, so the SPA boots correctly on the
14+
// rewritten URL with no network round-trip at all. Plain in-page
15+
// anchors don't start with "#/" and are left alone.
1216
(function () {
1317
var hash = window.location.hash;
18+
var path = window.location.pathname;
19+
var target = null;
1420
if (hash.length > 1 && hash.charAt(1) === '/') {
15-
window.location.replace(hash.slice(1) + window.location.search);
16-
return;
21+
target = hash.slice(1) + window.location.search;
22+
} else if (path.length > 1 && path.charAt(path.length - 1) === '/') {
23+
// GitHub Pages 301-redirects directory URLs to a trailing slash
24+
// (/learn → /learn/). Strip it so the address bar shows the
25+
// canonical path.
26+
target = path.replace(/\/+$/, '') + window.location.search + hash;
1727
}
18-
// GitHub Pages 301-redirects directory URLs to a trailing slash
19-
// (/learn → /learn/). Strip it so the address bar always shows the
20-
// canonical path; replaceState costs no request and no reload.
21-
var path = window.location.pathname;
22-
if (path.length > 1 && path.charAt(path.length - 1) === '/') {
23-
window.history.replaceState(
24-
null,
25-
'',
26-
path.replace(/\/+$/, '') + window.location.search
27-
);
28+
if (target !== null) {
29+
try {
30+
window.history.replaceState(null, '', target);
31+
} catch (e) {
32+
// sandboxed webview without history access — boot on the URL as-is
33+
}
2834
}
2935
})();
3036
</script>

‎index.html‎

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,31 @@
66
<meta name="viewport" content="width=device-width, initial-scale=1" />
77
<script>
88
// The site was hash-routed until mid-2026, so old links look like
9-
// gpu.rocks/#/learn/1-2/3. Rewrite them onto real paths before anything
10-
// else loads (zero app boot on the wrong URL). Plain in-page anchors
11-
// don't start with "#/" and are left alone.
9+
// gpu.rocks/#/learn/1-2/3. Rewrite them onto real paths before the app
10+
// boots. replaceState only — never location.replace: a real navigation
11+
// here loops forever in webviews that re-open the originally requested
12+
// URL on instant redirects (seen in Telegram's in-app browser). Every
13+
// path serves this same shell, so the SPA boots correctly on the
14+
// rewritten URL with no network round-trip at all. Plain in-page
15+
// anchors don't start with "#/" and are left alone.
1216
(function () {
1317
var hash = window.location.hash;
18+
var path = window.location.pathname;
19+
var target = null;
1420
if (hash.length > 1 && hash.charAt(1) === '/') {
15-
window.location.replace(hash.slice(1) + window.location.search);
16-
return;
21+
target = hash.slice(1) + window.location.search;
22+
} else if (path.length > 1 && path.charAt(path.length - 1) === '/') {
23+
// GitHub Pages 301-redirects directory URLs to a trailing slash
24+
// (/learn → /learn/). Strip it so the address bar shows the
25+
// canonical path.
26+
target = path.replace(/\/+$/, '') + window.location.search + hash;
1727
}
18-
// GitHub Pages 301-redirects directory URLs to a trailing slash
19-
// (/learn → /learn/). Strip it so the address bar always shows the
20-
// canonical path; replaceState costs no request and no reload.
21-
var path = window.location.pathname;
22-
if (path.length > 1 && path.charAt(path.length - 1) === '/') {
23-
window.history.replaceState(
24-
null,
25-
'',
26-
path.replace(/\/+$/, '') + window.location.search
27-
);
28+
if (target !== null) {
29+
try {
30+
window.history.replaceState(null, '', target);
31+
} catch (e) {
32+
// sandboxed webview without history access — boot on the URL as-is
33+
}
2834
}
2935
})();
3036
</script>

‎install/index.html‎

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,31 @@
66
<meta name="viewport" content="width=device-width, initial-scale=1" />
77
<script>
88
// The site was hash-routed until mid-2026, so old links look like
9-
// gpu.rocks/#/learn/1-2/3. Rewrite them onto real paths before anything
10-
// else loads (zero app boot on the wrong URL). Plain in-page anchors
11-
// don't start with "#/" and are left alone.
9+
// gpu.rocks/#/learn/1-2/3. Rewrite them onto real paths before the app
10+
// boots. replaceState only — never location.replace: a real navigation
11+
// here loops forever in webviews that re-open the originally requested
12+
// URL on instant redirects (seen in Telegram's in-app browser). Every
13+
// path serves this same shell, so the SPA boots correctly on the
14+
// rewritten URL with no network round-trip at all. Plain in-page
15+
// anchors don't start with "#/" and are left alone.
1216
(function () {
1317
var hash = window.location.hash;
18+
var path = window.location.pathname;
19+
var target = null;
1420
if (hash.length > 1 && hash.charAt(1) === '/') {
15-
window.location.replace(hash.slice(1) + window.location.search);
16-
return;
21+
target = hash.slice(1) + window.location.search;
22+
} else if (path.length > 1 && path.charAt(path.length - 1) === '/') {
23+
// GitHub Pages 301-redirects directory URLs to a trailing slash
24+
// (/learn → /learn/). Strip it so the address bar shows the
25+
// canonical path.
26+
target = path.replace(/\/+$/, '') + window.location.search + hash;
1727
}
18-
// GitHub Pages 301-redirects directory URLs to a trailing slash
19-
// (/learn → /learn/). Strip it so the address bar always shows the
20-
// canonical path; replaceState costs no request and no reload.
21-
var path = window.location.pathname;
22-
if (path.length > 1 && path.charAt(path.length - 1) === '/') {
23-
window.history.replaceState(
24-
null,
25-
'',
26-
path.replace(/\/+$/, '') + window.location.search
27-
);
28+
if (target !== null) {
29+
try {
30+
window.history.replaceState(null, '', target);
31+
} catch (e) {
32+
// sandboxed webview without history access — boot on the URL as-is
33+
}
2834
}
2935
})();
3036
</script>

‎learn/1-1/1/index.html‎

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,31 @@
66
<meta name="viewport" content="width=device-width, initial-scale=1" />
77
<script>
88
// The site was hash-routed until mid-2026, so old links look like
9-
// gpu.rocks/#/learn/1-2/3. Rewrite them onto real paths before anything
10-
// else loads (zero app boot on the wrong URL). Plain in-page anchors
11-
// don't start with "#/" and are left alone.
9+
// gpu.rocks/#/learn/1-2/3. Rewrite them onto real paths before the app
10+
// boots. replaceState only — never location.replace: a real navigation
11+
// here loops forever in webviews that re-open the originally requested
12+
// URL on instant redirects (seen in Telegram's in-app browser). Every
13+
// path serves this same shell, so the SPA boots correctly on the
14+
// rewritten URL with no network round-trip at all. Plain in-page
15+
// anchors don't start with "#/" and are left alone.
1216
(function () {
1317
var hash = window.location.hash;
18+
var path = window.location.pathname;
19+
var target = null;
1420
if (hash.length > 1 && hash.charAt(1) === '/') {
15-
window.location.replace(hash.slice(1) + window.location.search);
16-
return;
21+
target = hash.slice(1) + window.location.search;
22+
} else if (path.length > 1 && path.charAt(path.length - 1) === '/') {
23+
// GitHub Pages 301-redirects directory URLs to a trailing slash
24+
// (/learn → /learn/). Strip it so the address bar shows the
25+
// canonical path.
26+
target = path.replace(/\/+$/, '') + window.location.search + hash;
1727
}
18-
// GitHub Pages 301-redirects directory URLs to a trailing slash
19-
// (/learn → /learn/). Strip it so the address bar always shows the
20-
// canonical path; replaceState costs no request and no reload.
21-
var path = window.location.pathname;
22-
if (path.length > 1 && path.charAt(path.length - 1) === '/') {
23-
window.history.replaceState(
24-
null,
25-
'',
26-
path.replace(/\/+$/, '') + window.location.search
27-
);
28+
if (target !== null) {
29+
try {
30+
window.history.replaceState(null, '', target);
31+
} catch (e) {
32+
// sandboxed webview without history access — boot on the URL as-is
33+
}
2834
}
2935
})();
3036
</script>

‎learn/1-1/2/index.html‎

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,31 @@
66
<meta name="viewport" content="width=device-width, initial-scale=1" />
77
<script>
88
// The site was hash-routed until mid-2026, so old links look like
9-
// gpu.rocks/#/learn/1-2/3. Rewrite them onto real paths before anything
10-
// else loads (zero app boot on the wrong URL). Plain in-page anchors
11-
// don't start with "#/" and are left alone.
9+
// gpu.rocks/#/learn/1-2/3. Rewrite them onto real paths before the app
10+
// boots. replaceState only — never location.replace: a real navigation
11+
// here loops forever in webviews that re-open the originally requested
12+
// URL on instant redirects (seen in Telegram's in-app browser). Every
13+
// path serves this same shell, so the SPA boots correctly on the
14+
// rewritten URL with no network round-trip at all. Plain in-page
15+
// anchors don't start with "#/" and are left alone.
1216
(function () {
1317
var hash = window.location.hash;
18+
var path = window.location.pathname;
19+
var target = null;
1420
if (hash.length > 1 && hash.charAt(1) === '/') {
15-
window.location.replace(hash.slice(1) + window.location.search);
16-
return;
21+
target = hash.slice(1) + window.location.search;
22+
} else if (path.length > 1 && path.charAt(path.length - 1) === '/') {
23+
// GitHub Pages 301-redirects directory URLs to a trailing slash
24+
// (/learn → /learn/). Strip it so the address bar shows the
25+
// canonical path.
26+
target = path.replace(/\/+$/, '') + window.location.search + hash;
1727
}
18-
// GitHub Pages 301-redirects directory URLs to a trailing slash
19-
// (/learn → /learn/). Strip it so the address bar always shows the
20-
// canonical path; replaceState costs no request and no reload.
21-
var path = window.location.pathname;
22-
if (path.length > 1 && path.charAt(path.length - 1) === '/') {
23-
window.history.replaceState(
24-
null,
25-
'',
26-
path.replace(/\/+$/, '') + window.location.search
27-
);
28+
if (target !== null) {
29+
try {
30+
window.history.replaceState(null, '', target);
31+
} catch (e) {
32+
// sandboxed webview without history access — boot on the URL as-is
33+
}
2834
}
2935
})();
3036
</script>

‎learn/1-1/3/index.html‎

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,31 @@
66
<meta name="viewport" content="width=device-width, initial-scale=1" />
77
<script>
88
// The site was hash-routed until mid-2026, so old links look like
9-
// gpu.rocks/#/learn/1-2/3. Rewrite them onto real paths before anything
10-
// else loads (zero app boot on the wrong URL). Plain in-page anchors
11-
// don't start with "#/" and are left alone.
9+
// gpu.rocks/#/learn/1-2/3. Rewrite them onto real paths before the app
10+
// boots. replaceState only — never location.replace: a real navigation
11+
// here loops forever in webviews that re-open the originally requested
12+
// URL on instant redirects (seen in Telegram's in-app browser). Every
13+
// path serves this same shell, so the SPA boots correctly on the
14+
// rewritten URL with no network round-trip at all. Plain in-page
15+
// anchors don't start with "#/" and are left alone.
1216
(function () {
1317
var hash = window.location.hash;
18+
var path = window.location.pathname;
19+
var target = null;
1420
if (hash.length > 1 && hash.charAt(1) === '/') {
15-
window.location.replace(hash.slice(1) + window.location.search);
16-
return;
21+
target = hash.slice(1) + window.location.search;
22+
} else if (path.length > 1 && path.charAt(path.length - 1) === '/') {
23+
// GitHub Pages 301-redirects directory URLs to a trailing slash
24+
// (/learn → /learn/). Strip it so the address bar shows the
25+
// canonical path.
26+
target = path.replace(/\/+$/, '') + window.location.search + hash;
1727
}
18-
// GitHub Pages 301-redirects directory URLs to a trailing slash
19-
// (/learn → /learn/). Strip it so the address bar always shows the
20-
// canonical path; replaceState costs no request and no reload.
21-
var path = window.location.pathname;
22-
if (path.length > 1 && path.charAt(path.length - 1) === '/') {
23-
window.history.replaceState(
24-
null,
25-
'',
26-
path.replace(/\/+$/, '') + window.location.search
27-
);
28+
if (target !== null) {
29+
try {
30+
window.history.replaceState(null, '', target);
31+
} catch (e) {
32+
// sandboxed webview without history access — boot on the URL as-is
33+
}
2834
}
2935
})();
3036
</script>

0 commit comments

Comments
 (0)