cache.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. 'use strict'
  2. // Workbox RuntimeCaching config: https://developers.google.com/web/tools/workbox/reference-docs/latest/module-workbox-build#.RuntimeCachingEntry
  3. module.exports = [
  4. {
  5. urlPattern: /^https:\/\/fonts\.(?:gstatic)\.com\/.*/i,
  6. handler: 'CacheFirst',
  7. options: {
  8. cacheName: 'google-fonts-webfonts',
  9. expiration: {
  10. maxEntries: 4,
  11. maxAgeSeconds: 365 * 24 * 60 * 60 // 365 days
  12. }
  13. }
  14. },
  15. {
  16. urlPattern: /^https:\/\/fonts\.(?:googleapis)\.com\/.*/i,
  17. handler: 'StaleWhileRevalidate',
  18. options: {
  19. cacheName: 'google-fonts-stylesheets',
  20. expiration: {
  21. maxEntries: 4,
  22. maxAgeSeconds: 7 * 24 * 60 * 60 // 7 days
  23. }
  24. }
  25. },
  26. {
  27. urlPattern: /\.(?:eot|otf|ttc|ttf|woff|woff2|font.css)$/i,
  28. handler: 'StaleWhileRevalidate',
  29. options: {
  30. cacheName: 'static-font-assets',
  31. expiration: {
  32. maxEntries: 4,
  33. maxAgeSeconds: 7 * 24 * 60 * 60 // 7 days
  34. }
  35. }
  36. },
  37. {
  38. urlPattern: /\.(?:jpg|jpeg|gif|png|svg|ico|webp)$/i,
  39. handler: 'StaleWhileRevalidate',
  40. options: {
  41. cacheName: 'static-image-assets',
  42. expiration: {
  43. maxEntries: 64,
  44. maxAgeSeconds: 24 * 60 * 60 // 24 hours
  45. }
  46. }
  47. },
  48. {
  49. urlPattern: /\/_next\/image\?url=.+$/i,
  50. handler: 'StaleWhileRevalidate',
  51. options: {
  52. cacheName: 'next-image',
  53. expiration: {
  54. maxEntries: 64,
  55. maxAgeSeconds: 24 * 60 * 60 // 24 hours
  56. }
  57. }
  58. },
  59. {
  60. urlPattern: /\.(?:mp3|wav|ogg)$/i,
  61. handler: 'CacheFirst',
  62. options: {
  63. rangeRequests: true,
  64. cacheName: 'static-audio-assets',
  65. expiration: {
  66. maxEntries: 32,
  67. maxAgeSeconds: 24 * 60 * 60 // 24 hours
  68. }
  69. }
  70. },
  71. {
  72. urlPattern: /\.(?:mp4)$/i,
  73. handler: 'CacheFirst',
  74. options: {
  75. rangeRequests: true,
  76. cacheName: 'static-video-assets',
  77. expiration: {
  78. maxEntries: 32,
  79. maxAgeSeconds: 24 * 60 * 60 // 24 hours
  80. }
  81. }
  82. },
  83. {
  84. urlPattern: /\.(?:js)$/i,
  85. handler: 'StaleWhileRevalidate',
  86. options: {
  87. cacheName: 'static-js-assets',
  88. expiration: {
  89. maxEntries: 32,
  90. maxAgeSeconds: 24 * 60 * 60 // 24 hours
  91. }
  92. }
  93. },
  94. {
  95. urlPattern: /\.(?:css|less)$/i,
  96. handler: 'StaleWhileRevalidate',
  97. options: {
  98. cacheName: 'static-style-assets',
  99. expiration: {
  100. maxEntries: 32,
  101. maxAgeSeconds: 24 * 60 * 60 // 24 hours
  102. }
  103. }
  104. },
  105. {
  106. urlPattern: /\/_next\/data\/.+\/.+\.json$/i,
  107. handler: 'StaleWhileRevalidate',
  108. options: {
  109. cacheName: 'next-data',
  110. expiration: {
  111. maxEntries: 32,
  112. maxAgeSeconds: 24 * 60 * 60 // 24 hours
  113. }
  114. }
  115. },
  116. {
  117. urlPattern: /\.(?:json|xml|csv)$/i,
  118. handler: 'NetworkFirst',
  119. options: {
  120. cacheName: 'static-data-assets',
  121. expiration: {
  122. maxEntries: 32,
  123. maxAgeSeconds: 24 * 60 * 60 // 24 hours
  124. }
  125. }
  126. },
  127. {
  128. urlPattern: ({ url }) => {
  129. const isSameOrigin = self.origin === url.origin
  130. if (!isSameOrigin) return false
  131. const pathname = url.pathname
  132. // Exclude /api/auth/callback/* to fix OAuth workflow in Safari without impact other environment
  133. // Above route is default for next-auth, you may need to change it if your OAuth workflow has a different callback route
  134. // Issue: https://github.com/shadowwalker/next-pwa/issues/131#issuecomment-821894809
  135. if (pathname.startsWith('/api/auth/')) return false
  136. if (pathname.startsWith('/api/')) return true
  137. return false
  138. },
  139. handler: 'NetworkFirst',
  140. method: 'GET',
  141. options: {
  142. cacheName: 'apis',
  143. expiration: {
  144. maxEntries: 16,
  145. maxAgeSeconds: 24 * 60 * 60 // 24 hours
  146. },
  147. networkTimeoutSeconds: 10 // fall back to cache if api does not response within 10 seconds
  148. }
  149. },
  150. {
  151. urlPattern: ({ url }) => {
  152. const isSameOrigin = self.origin === url.origin
  153. if (!isSameOrigin) return false
  154. const pathname = url.pathname
  155. if (pathname.startsWith('/api/')) return false
  156. return true
  157. },
  158. handler: 'NetworkFirst',
  159. options: {
  160. cacheName: 'others',
  161. expiration: {
  162. maxEntries: 32,
  163. maxAgeSeconds: 24 * 60 * 60 // 24 hours
  164. },
  165. networkTimeoutSeconds: 10
  166. }
  167. },
  168. {
  169. urlPattern: ({ url }) => {
  170. const isSameOrigin = self.origin === url.origin
  171. return !isSameOrigin
  172. },
  173. handler: 'NetworkFirst',
  174. options: {
  175. cacheName: 'cross-origin',
  176. expiration: {
  177. maxEntries: 32,
  178. maxAgeSeconds: 60 * 60 // 1 hour
  179. },
  180. networkTimeoutSeconds: 10
  181. }
  182. }
  183. ]