pwa-runtime-config.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. /* eslint-disable no-undef */
  2. /* eslint-disable no-restricted-globals */
  3. /* eslint-disable max-lines */
  4. // Workbox RuntimeCaching config: https://developers.google.com/web/tools/workbox/reference-docs/latest/module-workbox-build#.RuntimeCachingEntry
  5. /**
  6. * This is a copy of next-pwa's default runtime cache https://github.com/shadowwalker/next-pwa/blob/master/cache.js
  7. * except for the MP3 config which we are disabling because it seems to be causing an
  8. * exception for cached MP3 files (at least on Firefox):
  9. *
  10. * Failed to load ‘https://download.quranicaudio.com/qdc/{reader}/{readingStyle}/{fileName}.mp3’
  11. * e.g. "https://download.quranicaudio.com/qdc/saud_ash-shuraym/murattal/005.mp3"
  12. * A ServiceWorker intercepted the request and encountered an unexpected error.
  13. */
  14. module.exports = [
  15. {
  16. urlPattern: /^https:\/\/fonts\.(?:gstatic)\.com\/.*/i,
  17. handler: 'CacheFirst',
  18. options: {
  19. cacheName: 'google-fonts-webfonts',
  20. expiration: {
  21. maxEntries: 4,
  22. maxAgeSeconds: 365 * 24 * 60 * 60, // 365 days
  23. },
  24. },
  25. },
  26. {
  27. urlPattern: /^https:\/\/fonts\.(?:googleapis)\.com\/.*/i,
  28. handler: 'StaleWhileRevalidate',
  29. options: {
  30. cacheName: 'google-fonts-stylesheets',
  31. expiration: {
  32. maxEntries: 4,
  33. maxAgeSeconds: 7 * 24 * 60 * 60, // 7 days
  34. },
  35. },
  36. },
  37. {
  38. urlPattern: /\.(?:eot|otf|ttc|ttf|woff|woff2|font.css)$/i,
  39. handler: 'StaleWhileRevalidate',
  40. options: {
  41. cacheName: 'static-font-assets',
  42. expiration: {
  43. maxEntries: 4,
  44. maxAgeSeconds: 7 * 24 * 60 * 60, // 7 days
  45. },
  46. },
  47. },
  48. {
  49. urlPattern: /\.(?:jpg|jpeg|gif|png|svg|ico|webp)$/i,
  50. handler: 'StaleWhileRevalidate',
  51. options: {
  52. cacheName: 'static-image-assets',
  53. expiration: {
  54. maxEntries: 64,
  55. maxAgeSeconds: 24 * 60 * 60, // 24 hours
  56. },
  57. },
  58. },
  59. {
  60. urlPattern: /\/_next\/image\?url=.+$/i,
  61. handler: 'StaleWhileRevalidate',
  62. options: {
  63. cacheName: 'next-image',
  64. expiration: {
  65. maxEntries: 64,
  66. maxAgeSeconds: 24 * 60 * 60, // 24 hours
  67. },
  68. },
  69. },
  70. // {
  71. // urlPattern: /^https:\/\/download.quranicaudio.com\/.*.mp3/i,
  72. // handler: 'CacheFirst',
  73. // options: {
  74. // rangeRequests: true,
  75. // cacheName: 'static-audio-assets',
  76. // cacheableResponse: {
  77. // // workbox by default only caches response with 200 HTTP status
  78. // statuses: [0, 200, 206],
  79. // },
  80. // expiration: {
  81. // maxEntries: 500,
  82. // maxAgeSeconds: 24 * 60 * 60, // 24 hours
  83. // },
  84. // },
  85. // },
  86. {
  87. urlPattern: /\.(?:mp4)$/i,
  88. handler: 'CacheFirst',
  89. options: {
  90. rangeRequests: true,
  91. cacheName: 'static-video-assets',
  92. expiration: {
  93. maxEntries: 32,
  94. maxAgeSeconds: 24 * 60 * 60, // 24 hours
  95. },
  96. },
  97. },
  98. {
  99. urlPattern: /\.(?:js)$/i,
  100. handler: 'StaleWhileRevalidate',
  101. options: {
  102. cacheName: 'static-js-assets',
  103. expiration: {
  104. maxEntries: 32,
  105. maxAgeSeconds: 24 * 60 * 60, // 24 hours
  106. },
  107. },
  108. },
  109. {
  110. urlPattern: /\.(?:css|less)$/i,
  111. handler: 'StaleWhileRevalidate',
  112. options: {
  113. cacheName: 'static-style-assets',
  114. expiration: {
  115. maxEntries: 32,
  116. maxAgeSeconds: 24 * 60 * 60, // 24 hours
  117. },
  118. },
  119. },
  120. {
  121. urlPattern: /\/_next\/data\/.+\/.+\.json$/i,
  122. handler: 'StaleWhileRevalidate',
  123. options: {
  124. cacheName: 'next-data',
  125. expiration: {
  126. maxEntries: 32,
  127. maxAgeSeconds: 24 * 60 * 60, // 24 hours
  128. },
  129. },
  130. },
  131. {
  132. urlPattern: /\.(?:json|xml|csv)$/i,
  133. handler: 'NetworkFirst',
  134. options: {
  135. cacheName: 'static-data-assets',
  136. expiration: {
  137. maxEntries: 32,
  138. maxAgeSeconds: 24 * 60 * 60, // 24 hours
  139. },
  140. },
  141. },
  142. {
  143. urlPattern: ({ url }) => {
  144. const isSameOrigin = self.origin === url.origin;
  145. if (!isSameOrigin) return false;
  146. const { pathname } = url;
  147. // Exclude /api/auth/callback/* to fix OAuth workflow in Safari without impact other environment
  148. // Above route is default for next-auth, you may need to change it if your OAuth workflow has a different callback route
  149. // Issue: https://github.com/shadowwalker/next-pwa/issues/131#issuecomment-821894809
  150. if (pathname.startsWith('/api/auth/')) return false;
  151. if (pathname.startsWith('/api/')) return true;
  152. return false;
  153. },
  154. handler: 'NetworkFirst',
  155. method: 'GET',
  156. options: {
  157. cacheName: 'apis',
  158. expiration: {
  159. maxEntries: 16,
  160. maxAgeSeconds: 24 * 60 * 60, // 24 hours
  161. },
  162. networkTimeoutSeconds: 10, // fall back to cache if api does not response within 10 seconds
  163. },
  164. },
  165. {
  166. urlPattern: ({ url }) => {
  167. const isSameOrigin = self.origin === url.origin;
  168. if (!isSameOrigin) return false;
  169. const { pathname } = url;
  170. if (pathname.startsWith('/api/')) return false;
  171. return true;
  172. },
  173. handler: 'NetworkFirst',
  174. options: {
  175. cacheName: 'others',
  176. expiration: {
  177. maxEntries: 32,
  178. maxAgeSeconds: 24 * 60 * 60, // 24 hours
  179. },
  180. networkTimeoutSeconds: 10,
  181. },
  182. },
  183. {
  184. urlPattern: ({ url }) => {
  185. const { pathname } = url;
  186. const isSameOrigin = self.origin === url.origin;
  187. // cache everything except mp3 files
  188. return !isSameOrigin && !pathname.endsWith('.mp3');
  189. },
  190. handler: 'NetworkFirst',
  191. options: {
  192. cacheName: 'cross-origin',
  193. expiration: {
  194. maxEntries: 32,
  195. maxAgeSeconds: 60 * 60, // 1 hour
  196. },
  197. networkTimeoutSeconds: 10,
  198. },
  199. },
  200. ];