起きたこと
ダッシュボードで成果物ページを開いた状態(/app/index.html#/<slug>)からブラウザの「戻る」を押すと、画面が真っ白になります。
一覧には戻らず、URLは #/<slug> のまま、ページ枠だけが残って中身が消えます。macOS Safari で確認しましたが、原理上ブラウザは選びません。
原因
select() が成果物を表示するとき、iframe の src へ代入しています。
// web/app/index.html
} else {
home.classList.remove('on');
frame.hidden = false;
frame.src = current.href; // ← ここ
iframe の src への代入は、そのたびにブラウザの履歴にエントリを積みます。
そのため「戻る」を押すと、親フレームより先に iframe の中身だけが1つ前(=空)へ戻ります。親は #/<slug> のままなので hashchange も発火せず、枠だけが残って真っ白に見えます。
ページを何枚か開いてから戻ると、開いた枚数ぶん「戻る」を押さないと一覧へ到達しない状態にもなります。
修正案
履歴を積まない location.replace() に変えると解消しました。
// iframe の src への代入は履歴を積むため、「戻る」で iframe だけが空へ戻る。
// location.replace は履歴を積まず、クロスオリジンでも呼べる。
// 読み取り(location.href の取得)はクロスオリジンで例外になるため行わない。
function loadFrame(url) {
const view = frame.contentWindow;
if (!view) { frame.src = url; return; }
try {
view.location.replace(url);
} catch {
frame.src = url; // 想定外の環境では従来どおりに倒す
}
}
呼び出し側は2箇所です。
if (!current) {
frame.hidden = true;
loadFrame('about:blank'); // 旧: frame.removeAttribute('src')
…
} else {
frame.hidden = false;
loadFrame(current.href); // 旧: frame.src = current.href
Location インターフェースの replace() はクロスオリジンでも呼び出せるため、成果物が別オリジン(contentDomain)でも動作します。
再現手順
- ダッシュボードで任意の成果物ページを開く(URLが
#/<slug> になる)
- ブラウザの「戻る」を押す
- 一覧へ戻らず、画面が真っ白になる
確認したこと
手元で上記の修正を当てて html-share publish し、実機の Safari で「戻る」が一覧へ正しく戻ることを確認しました。
環境
- macOS Safari
- Node.js 24
main ブランチ相当(2026-08-17 時点)
起きたこと
ダッシュボードで成果物ページを開いた状態(
/app/index.html#/<slug>)からブラウザの「戻る」を押すと、画面が真っ白になります。一覧には戻らず、URLは
#/<slug>のまま、ページ枠だけが残って中身が消えます。macOS Safari で確認しましたが、原理上ブラウザは選びません。原因
select()が成果物を表示するとき、iframe のsrcへ代入しています。iframe の
srcへの代入は、そのたびにブラウザの履歴にエントリを積みます。そのため「戻る」を押すと、親フレームより先に iframe の中身だけが1つ前(=空)へ戻ります。親は
#/<slug>のままなのでhashchangeも発火せず、枠だけが残って真っ白に見えます。ページを何枚か開いてから戻ると、開いた枚数ぶん「戻る」を押さないと一覧へ到達しない状態にもなります。
修正案
履歴を積まない
location.replace()に変えると解消しました。呼び出し側は2箇所です。
Locationインターフェースのreplace()はクロスオリジンでも呼び出せるため、成果物が別オリジン(contentDomain)でも動作します。再現手順
#/<slug>になる)確認したこと
手元で上記の修正を当てて
html-share publishし、実機の Safari で「戻る」が一覧へ正しく戻ることを確認しました。環境
mainブランチ相当(2026-08-17 時点)