@@ -29,7 +29,21 @@ globalThis.addEventListener('activate', ev => {
2929} ) ;
3030
3131async function offlineContentHTML ( ) {
32- const i18n = await ( swLang . i18n ?? swLang . fetchLocale ( ) ) as Partial < I18n < Locale > > ;
32+ const controller = new AbortController ( ) ;
33+ const timeout = globalThis . setTimeout ( ( ) => {
34+ controller . abort ( 'i18n-timeout' ) ;
35+ } , 3000 ) ;
36+
37+ let i18n : Partial < I18n < Locale > > ;
38+
39+ try {
40+ i18n = await ( swLang . i18n ?? swLang . fetchLocale ( ) ) as Partial < I18n < Locale > > ;
41+ } catch {
42+ i18n = { } ;
43+ } finally {
44+ globalThis . clearTimeout ( timeout ) ;
45+ }
46+
3347 const messages = {
3448 title : i18n . ts ?. _offlineScreen . title ?? 'Offline - Could not connect to server' ,
3549 header : i18n . ts ?. _offlineScreen . header ?? 'Could not connect to server' ,
@@ -50,20 +64,37 @@ globalThis.addEventListener('fetch', ev => {
5064 }
5165
5266 if ( ! isHTMLRequest ) return ;
53- ev . respondWith (
54- fetch ( ev . request )
55- . catch ( async ( ) => {
56- const html = await offlineContentHTML ( ) ;
57- return new Response ( html , {
58- status : 200 ,
59- headers : {
60- 'content-type' : 'text/html' ,
61- } ,
62- } ) ;
63- } ) ,
64- ) ;
67+ ev . respondWith ( respondToNavigation ( ev . request ) ) ;
6568} ) ;
6669
70+ async function respondToNavigation ( request : Request ) : Promise < Response > {
71+ const controller = new AbortController ( ) ;
72+ const timeout = globalThis . setTimeout ( ( ) => {
73+ controller . abort ( 'navigation-timeout' ) ;
74+ } , 5000 ) ;
75+
76+ try {
77+ const response = await fetch ( request , { signal : controller . signal } ) ;
78+
79+ if ( response ?. status && response . status < 400 ) return response ;
80+ if ( response ?. type === 'opaqueredirect' ) return response ;
81+ } catch ( error ) {
82+ if ( _DEV_ ) {
83+ console . warn ( 'navigation fetch failed; showing offline page' , error ) ;
84+ }
85+ } finally {
86+ globalThis . clearTimeout ( timeout ) ;
87+ }
88+
89+ const html = await offlineContentHTML ( ) ;
90+ return new Response ( html , {
91+ status : 200 ,
92+ headers : {
93+ 'content-type' : 'text/html' ,
94+ } ,
95+ } ) ;
96+ }
97+
6798globalThis . addEventListener ( 'push' , ev => {
6899 // クライアント取得
69100 ev . waitUntil ( globalThis . clients . matchAll ( {
0 commit comments