-
Notifications
You must be signed in to change notification settings - Fork 264
WS-1838: Add PWA Offline page tracking #13545
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
elvinasv
merged 110 commits into
ws-1837-service-worker-changes
from
feature/WS-1838-pwa-offline-flag
Jan 9, 2026
Merged
Changes from all commits
Commits
Show all changes
110 commits
Select commit
Hold shift + click to select a range
a80f734
WS-1838 adding tracking flag
DmitryGron 8649365
WS-1838 adding tracking flag
DmitryGron 3f89eb2
Merge branch 'ws-1837-service-worker-changes' into feature/WS-1838-pw…
DmitryGron 6548df5
Merge branch 'ws-1837-service-worker-changes' into feature/WS-1838-pw…
DmitryGron 5a1cdf7
Merge branch 'ws-1837-service-worker-changes' into feature/WS-1838-pw…
elvinasv 02a40fc
updating due to comments
DmitryGron 14508da
Merge branch 'ws-1837-service-worker-changes' into feature/WS-1838-pw…
DmitryGron 56b0671
small update for offline hooks
DmitryGron a73f35f
updating hooks offline tracking
DmitryGron c5cd73d
Merge branch 'ws-1837-service-worker-changes' into feature/WS-1838-pw…
elvinasv bc8c4c4
update offline flag to work properly
DmitryGron e58e685
removing nextjs static assets to avoid loop reloadand some other fixes
jinidev d5746f2
WS-1826-collapsible-nav-for-seo
SantaZena dfc23cd
Updating unit tests
SantaZena 84d8a04
Updating unit tests nr2
SantaZena 05f499b
Updating unit tests nr3
SantaZena 0d2c345
Removing right line in top nav
SantaZena 574424b
Fix onload condition for promo images & add blurred bg
DmitryGron 55bfd7a
Add isPortraitImage condition back
hotinglok beb1dcb
Move css into separate component, apply changes to MAPs
hotinglok e5a6c30
Add changes to hierarchical grid & billboard, update selectors
hotinglok d67f6eb
Make blurred background image src smaller
hotinglok 58be086
Fix invalid ichef image size
hotinglok 7f73b3a
Prevent any fetching on lite site pages
hotinglok 1425a86
Add stories, add isLite condition to LatestMediaSection
hotinglok 12cb6ba
Add aria-hidden to BlurredBackground
hotinglok dd3157c
Remove onLoad fix
DmitryGron 03a5daa
Linting
hotinglok 30d0a40
Add fallback if ichef url fails
hotinglok 9e77ae5
Update curations test
hotinglok 021670f
Update integration test snapshots
hotinglok a0d3aed
Revert mundo fixture
hotinglok f102a75
Remove isLite prop drilling, add RequestContext to BlurredBackround c…
hotinglok e99bb0b
Linting
hotinglok 4c4c63d
Fix stories
hotinglok af07b81
Fix src url
hotinglok 58694d2
Fix LatestMediaSection styles
hotinglok c1c4c8b
Add dark filter over background to make image stand out more
hotinglok cc4acad
WS-1882 - Remove hover/focus colour on TopicTags (#13553)
amoore108 5c403f3
WS-NA: Removes trailing comma if final contibutor has no role or loca…
Isabella-Mitchell 30f934f
added route for homepages as well as condition for page type header
DmitryGron c10fac2
added unit tests
Nabeel1276 fcec076
updated structure of data fetch
Nabeel1276 3e72ac6
called Homepage component to render it
DmitryGron e1be759
renamed folder to homepage and homepage return in derived page type
Nabeel1276 e1a633b
removed toggles
Nabeel1276 d198029
added variant support to derivePageType utility [copilot]
Nabeel1276 2cf4cdf
added unit tests for homepage derived type
Nabeel1276 dc4d691
removed unneccessary keys
Nabeel1276 48e0e4c
moved shouldRender function into utilites folder and updated imports
Nabeel1276 5dc4dec
removed redundant props
Nabeel1276 432c37f
updated shouldRender imports
Nabeel1276 d7e3b4b
fixed imports again
Nabeel1276 2dd0851
updated imports again
Nabeel1276 235a544
removed unused props
Nabeel1276 7743d12
reinstated required props
Nabeel1276 500f45d
updated cache control
Nabeel1276 d4070e7
updated unit tests
Nabeel1276 e074bf9
removed amp as it is not supported in home pages
Nabeel1276 7f66610
Add test
amoore108 b8e933d
updated readme
Nabeel1276 62cb94d
WS-1175: Removes optimizely dependency from article readtime
Isabella-Mitchell ff0e204
WS-1175: Refactor ReadTime component
Isabella-Mitchell d33ca26
WS-1175: Fix react issue
Isabella-Mitchell b4cc30a
WS-1175: Move translations check higher up the tree
Isabella-Mitchell a82cac6
WS-1175: Reverts passing translations as prop
Isabella-Mitchell d7d1e30
WS-1175: Tidy up code labelled with experiment comments
Isabella-Mitchell 5f3bbb2
WS-1175: Fix stories and styles
Isabella-Mitchell 93ac0fe
WS-1175: Tidies
Isabella-Mitchell 48b8017
cache was missing
jinidev 0f8261f
adding tests
DmitryGron fe4c417
Merge branch 'ws-1837-service-worker-changes' into feature/WS-1838-pw…
DmitryGron 1b42ee9
Update index.tsx
DmitryGron e0b3d5f
Fix onload condition for promo images & add blurred bg
DmitryGron 35c170a
Move css into separate component, apply changes to MAPs
DmitryGron 622a621
added route for homepages as well as condition for page type header
DmitryGron 8fbd336
renamed folder to homepage and homepage return in derived page type
DmitryGron 9c3783a
removing unrelated
DmitryGron a6ddf13
removing unrelated
DmitryGron 81614e5
removing unrelated
DmitryGron 0db80e1
removing unrelated
DmitryGron 02d6104
removing unrelated
DmitryGron edab507
updating audit
DmitryGron 2529ceb
Merge branch 'ws-1837-service-worker-changes' into feature/WS-1838-pw…
DmitryGron 78d336d
removing ref
DmitryGron b5383a6
Merge branch 'ws-1837-service-worker-changes' into feature/WS-1838-pw…
jinidev 8f5bd54
simplefying offline tracking logic
DmitryGron 6ec847a
upgraded the cachename in sw to see updated offlinepage
jinidev b03ca3f
putting logs and removed isONline check from useOfflinePageFlag hook
jinidev 9b1cde5
sw changes for nextjs bundling/cache resorucing
jinidev d81aba2
updating test
DmitryGron 0a72b7d
revert sw.js to original
jinidev 2aa1f46
update testds
DmitryGron ee21809
Merge branch 'ws-1837-service-worker-changes' into feature/WS-1838-pw…
jinidev 64fd026
Update src/app/hooks/usePWAOfflineTracking/index.test.tsx
DmitryGron d840930
updates due to comments
DmitryGron 9ee5583
updates due to comments
DmitryGron 07ad90d
updates due to comments
DmitryGron af8a64d
updates due to comments
DmitryGron f129d1d
Merge branch 'ws-1837-service-worker-changes' into feature/WS-1838-pw…
jinidev 5c6fb54
Adding console logs to help debug event tracking issues
jinidev ca20f88
prefetching offline page in client side for js chunks pre-caching
jinidev 52e6aa0
revert prefetch , remove filtering in cache of resources
jinidev 8c7d64c
revert sw changes, removed logs
jinidev a9a165e
Merge branch 'ws-1837-service-worker-changes' into feature/WS-1838-pw…
elvinasv 95ff827
Merge branch 'ws-1837-service-worker-changes' into feature/WS-1838-pw…
elvinasv eef7277
EffectiveNetworkType import issue fix
jinidev 18c0709
Merge branch 'ws-1837-service-worker-changes' into feature/WS-1838-pw…
elvinasv fd5a658
Merge branch 'ws-1837-service-worker-changes' into feature/WS-1838-pw…
elvinasv 2af8ada
fix: undefined variable
elvinasv File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| import { renderHook } from '@testing-library/react'; | ||
| import { renderHook as renderSSRHook } from '@testing-library/react-hooks/server'; | ||
| import { useOfflinePageFlag, OFFLINE_VISIT_FLAG } from './index'; | ||
|
|
||
| describe('useOfflinePageFlag', () => { | ||
| beforeEach(() => { | ||
| Storage.prototype.setItem = jest.fn(); | ||
| Storage.prototype.getItem = jest.fn(); | ||
| Storage.prototype.removeItem = jest.fn(); | ||
| jest.clearAllMocks(); | ||
| }); | ||
|
|
||
| it('should set offline flag when rendered', () => { | ||
| renderHook(() => useOfflinePageFlag()); | ||
|
|
||
| expect(localStorage.setItem).toHaveBeenCalledWith( | ||
| OFFLINE_VISIT_FLAG, | ||
| 'true', | ||
| ); | ||
| }); | ||
|
|
||
| it('should handle localStorage errors gracefully', () => { | ||
| const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(); | ||
|
|
||
| Storage.prototype.setItem = jest.fn().mockImplementation(() => { | ||
| throw new Error('localStorage is full'); | ||
| }); | ||
|
|
||
| expect(() => renderHook(() => useOfflinePageFlag())).not.toThrow(); | ||
| expect(consoleWarnSpy).toHaveBeenCalledWith( | ||
| 'useOfflinePageFlag', | ||
| expect.any(Error), | ||
| ); | ||
| }); | ||
|
|
||
| it('should not set flag on server side', () => { | ||
| renderSSRHook(() => useOfflinePageFlag()); | ||
|
|
||
| expect(localStorage.setItem).not.toHaveBeenCalled(); | ||
| }); | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| import { useEffect } from 'react'; | ||
|
|
||
| const OFFLINE_VISIT_FLAG = 'offline_page_visit'; | ||
|
|
||
| /** | ||
| * Sets a flag in localStorage when user visits the offline page. | ||
| * Note: Offline page is only accessible in PWA mode (via service worker), | ||
| * so no need to check isPWA - if this hook runs, we're already in PWA. | ||
| */ | ||
| const useOfflinePageFlag = () => { | ||
| useEffect(() => { | ||
| if (typeof window === 'undefined') return; | ||
| try { | ||
| localStorage.setItem(OFFLINE_VISIT_FLAG, 'true'); | ||
| } catch (error) { | ||
| // eslint-disable-next-line no-console | ||
| console.warn('useOfflinePageFlag', error); | ||
| } | ||
| }, []); | ||
| }; | ||
|
|
||
| export { useOfflinePageFlag, OFFLINE_VISIT_FLAG }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,247 @@ | ||
| import { renderHook } from '@testing-library/react'; | ||
| import { renderHook as renderSSRHook } from '@testing-library/react-hooks/server'; | ||
| import { EffectiveNetworkType } from '#app/models/types/global'; | ||
| import usePWAOfflineTracking from './index'; | ||
| import useNetworkStatusTracker from '../useNetworkStatusTracker'; | ||
| import useCustomEventTracker from '../useCustomEventTracker'; | ||
|
|
||
| jest.mock('../useNetworkStatusTracker'); | ||
| jest.mock('../useCustomEventTracker'); | ||
|
|
||
| describe('usePWAOfflineTracking', () => { | ||
| const mockTrackOfflinePageViewEvent = jest.fn(); | ||
| const mockUseNetworkStatusTracker = | ||
| useNetworkStatusTracker as jest.MockedFunction< | ||
| typeof useNetworkStatusTracker | ||
| >; | ||
| const mockUseCustomEventTracker = | ||
| useCustomEventTracker as jest.MockedFunction<typeof useCustomEventTracker>; | ||
|
|
||
| beforeEach(() => { | ||
| jest.clearAllMocks(); | ||
| Storage.prototype.getItem = jest.fn(); | ||
| Storage.prototype.setItem = jest.fn(); | ||
| Storage.prototype.removeItem = jest.fn(); | ||
|
|
||
| mockUseCustomEventTracker.mockReturnValue(mockTrackOfflinePageViewEvent); | ||
| }); | ||
|
|
||
| afterEach(() => { | ||
| jest.restoreAllMocks(); | ||
| }); | ||
|
|
||
| it('should not fire event when offline flag is not set', () => { | ||
| mockUseNetworkStatusTracker.mockReturnValue({ | ||
| isOnline: true, | ||
| networkType: '4g', | ||
| }); | ||
| Storage.prototype.getItem = jest.fn().mockReturnValue(null); | ||
|
|
||
| renderHook(() => usePWAOfflineTracking()); | ||
|
|
||
| expect(mockTrackOfflinePageViewEvent).not.toHaveBeenCalled(); | ||
| }); | ||
|
|
||
| it('should fire event when online and flag is set', () => { | ||
| mockUseNetworkStatusTracker.mockReturnValue({ | ||
| isOnline: true, | ||
| networkType: '4g', | ||
| }); | ||
| Storage.prototype.getItem = jest.fn().mockReturnValue('true'); | ||
|
|
||
| renderHook(() => usePWAOfflineTracking()); | ||
|
|
||
| expect(mockTrackOfflinePageViewEvent).toHaveBeenCalledTimes(1); | ||
| expect(mockTrackOfflinePageViewEvent).toHaveBeenCalledWith('4g'); | ||
| expect(localStorage.removeItem).toHaveBeenCalledWith('offline_page_visit'); | ||
| }); | ||
|
|
||
| it('should fire event on offline→online transition', () => { | ||
| Storage.prototype.getItem = jest.fn().mockReturnValue('true'); | ||
|
|
||
| mockUseNetworkStatusTracker.mockReturnValue({ | ||
| isOnline: false, | ||
| networkType: 'unknown', | ||
| }); | ||
|
|
||
| const { rerender } = renderHook(() => usePWAOfflineTracking()); | ||
|
|
||
| expect(mockTrackOfflinePageViewEvent).not.toHaveBeenCalled(); | ||
|
|
||
| mockUseNetworkStatusTracker.mockReturnValue({ | ||
| isOnline: true, | ||
| networkType: '4g', | ||
| }); | ||
|
|
||
| rerender(); | ||
|
|
||
| expect(mockTrackOfflinePageViewEvent).toHaveBeenCalledTimes(1); | ||
| expect(mockTrackOfflinePageViewEvent).toHaveBeenCalledWith('4g'); | ||
| expect(localStorage.removeItem).toHaveBeenCalledWith('offline_page_visit'); | ||
| }); | ||
|
|
||
| it('should not fire event again without flag being set', () => { | ||
| mockUseNetworkStatusTracker.mockReturnValue({ | ||
| isOnline: true, | ||
| networkType: '4g', | ||
| }); | ||
| const mockGetItem = jest | ||
| .fn() | ||
| .mockReturnValueOnce('true') | ||
| .mockReturnValue(null); | ||
| Storage.prototype.getItem = mockGetItem; | ||
|
|
||
| const { rerender } = renderHook(() => usePWAOfflineTracking()); | ||
|
|
||
| expect(mockTrackOfflinePageViewEvent).toHaveBeenCalledTimes(1); | ||
|
|
||
| rerender(); | ||
|
|
||
| expect(mockTrackOfflinePageViewEvent).toHaveBeenCalledTimes(1); | ||
| }); | ||
|
|
||
| it('should fire event again after flag is set again on next offline visit', () => { | ||
| const mockGetItem = jest | ||
| .fn() | ||
| .mockReturnValueOnce('true') | ||
| .mockReturnValueOnce('true'); | ||
| Storage.prototype.getItem = mockGetItem; | ||
|
|
||
| mockUseNetworkStatusTracker.mockReturnValue({ | ||
| isOnline: false, | ||
| networkType: 'unknown', | ||
| }); | ||
|
|
||
| const { rerender } = renderHook(() => usePWAOfflineTracking()); | ||
|
|
||
| mockUseNetworkStatusTracker.mockReturnValue({ | ||
| isOnline: true, | ||
| networkType: '4g', | ||
| }); | ||
|
|
||
| rerender(); | ||
|
|
||
| expect(mockTrackOfflinePageViewEvent).toHaveBeenCalledTimes(1); | ||
| expect(localStorage.removeItem).toHaveBeenCalledWith('offline_page_visit'); | ||
|
|
||
| mockUseNetworkStatusTracker.mockReturnValue({ | ||
| isOnline: false, | ||
| networkType: 'unknown', | ||
| }); | ||
|
|
||
| rerender(); | ||
|
|
||
| mockUseNetworkStatusTracker.mockReturnValue({ | ||
| isOnline: true, | ||
| networkType: '5g', | ||
| }); | ||
|
|
||
| rerender(); | ||
|
|
||
| expect(mockTrackOfflinePageViewEvent).toHaveBeenCalledTimes(2); | ||
| expect(mockTrackOfflinePageViewEvent).toHaveBeenLastCalledWith('5g'); | ||
| expect(localStorage.removeItem).toHaveBeenCalledTimes(2); | ||
| }); | ||
|
|
||
| it('should remove flag after firing event', () => { | ||
| Storage.prototype.getItem = jest.fn().mockReturnValue('true'); | ||
|
|
||
| mockUseNetworkStatusTracker.mockReturnValue({ | ||
| isOnline: false, | ||
| networkType: 'unknown', | ||
| }); | ||
|
|
||
| const { rerender } = renderHook(() => usePWAOfflineTracking()); | ||
|
|
||
| mockUseNetworkStatusTracker.mockReturnValue({ | ||
| isOnline: true, | ||
| networkType: '4g', | ||
| }); | ||
|
|
||
| rerender(); | ||
|
|
||
| expect(mockTrackOfflinePageViewEvent).toHaveBeenCalledTimes(1); | ||
| expect(localStorage.removeItem).toHaveBeenCalledWith('offline_page_visit'); | ||
| }); | ||
|
|
||
| it('should not fire when offline even if flag is set', () => { | ||
| mockUseNetworkStatusTracker.mockReturnValue({ | ||
| isOnline: false, | ||
| networkType: 'unknown', | ||
| }); | ||
| Storage.prototype.getItem = jest.fn().mockReturnValue('true'); | ||
|
|
||
| renderHook(() => usePWAOfflineTracking()); | ||
|
|
||
| expect(mockTrackOfflinePageViewEvent).not.toHaveBeenCalled(); | ||
| }); | ||
|
|
||
| it('should handle localStorage errors gracefully', () => { | ||
| mockUseNetworkStatusTracker.mockReturnValue({ | ||
| isOnline: true, | ||
| networkType: '4g', | ||
| }); | ||
|
|
||
| const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(); | ||
| Storage.prototype.getItem = jest.fn().mockImplementation(() => { | ||
| throw new Error('localStorage access denied'); | ||
| }); | ||
|
|
||
| expect(() => renderHook(() => usePWAOfflineTracking())).not.toThrow(); | ||
| expect(consoleErrorSpy).toHaveBeenCalledWith( | ||
| 'usePWAOfflineTracking', | ||
| expect.any(Error), | ||
| ); | ||
| expect(mockTrackOfflinePageViewEvent).not.toHaveBeenCalled(); | ||
| }); | ||
|
|
||
| it('should not track on server side', () => { | ||
| mockUseNetworkStatusTracker.mockReturnValue({ | ||
| isOnline: true, | ||
| networkType: '4g', | ||
| }); | ||
| Storage.prototype.getItem = jest.fn().mockReturnValue('true'); | ||
|
|
||
| renderSSRHook(() => usePWAOfflineTracking()); | ||
|
|
||
| expect(mockTrackOfflinePageViewEvent).not.toHaveBeenCalled(); | ||
| }); | ||
|
|
||
| it.each(['slow-2g', '2g', '3g', '4g', '5g', 'unknown'])( | ||
| 'should pass correct network type to tracking function: %s', | ||
| networkType => { | ||
| Storage.prototype.getItem = jest.fn().mockReturnValue('true'); | ||
|
|
||
| mockUseNetworkStatusTracker.mockReturnValue({ | ||
| isOnline: true, | ||
| networkType: networkType as EffectiveNetworkType, | ||
| }); | ||
|
|
||
| renderHook(() => usePWAOfflineTracking()); | ||
|
|
||
| expect(mockTrackOfflinePageViewEvent).toHaveBeenCalledWith(networkType); | ||
| }, | ||
| ); | ||
|
|
||
| it('should only fire on actual offline→online transition, not online→offline', () => { | ||
| Storage.prototype.getItem = jest.fn().mockReturnValue('true'); | ||
|
|
||
| mockUseNetworkStatusTracker.mockReturnValue({ | ||
| isOnline: true, | ||
| networkType: '4g', | ||
| }); | ||
|
|
||
| const { rerender } = renderHook(() => usePWAOfflineTracking()); | ||
|
|
||
| expect(mockTrackOfflinePageViewEvent).toHaveBeenCalledTimes(1); | ||
|
|
||
| mockUseNetworkStatusTracker.mockReturnValue({ | ||
| isOnline: false, | ||
| networkType: 'unknown', | ||
| }); | ||
|
|
||
| rerender(); | ||
|
|
||
| expect(mockTrackOfflinePageViewEvent).toHaveBeenCalledTimes(1); | ||
| }); | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| import { useEffect } from 'react'; | ||
| import useNetworkStatusTracker from '../useNetworkStatusTracker'; | ||
| import useCustomEventTracker from '../useCustomEventTracker'; | ||
| import { OFFLINE_VISIT_FLAG } from '../useOfflinePageFlag'; | ||
|
|
||
| const OFFLINE_PAGE_VIEW_EVENT_NAME = 'pwa-offline-page-view'; | ||
|
|
||
| /** | ||
| * Tracks offline→online transitions after user has visited offline page. | ||
| * Fires when network comes back online while flag is set. | ||
| * | ||
| * Flag can only be set in PWA mode (offline page requires service worker). | ||
| * By not checking isPWA at dispatch time, we track each offline session separately | ||
| * even if user switches between PWA/browser modes during reconnection. | ||
| * This prevents data loss and ensures accurate analytics. | ||
| */ | ||
| const usePWAOfflineTracking = () => { | ||
| const { isOnline, networkType } = useNetworkStatusTracker(); | ||
|
|
||
| const trackOfflinePageViewEvent = useCustomEventTracker({ | ||
| eventName: OFFLINE_PAGE_VIEW_EVENT_NAME, | ||
| }); | ||
|
|
||
| useEffect(() => { | ||
| if (typeof window === 'undefined' || !isOnline) { | ||
| return; | ||
| } | ||
| try { | ||
| const offlineVisitFlag = localStorage.getItem(OFFLINE_VISIT_FLAG); | ||
|
|
||
| if (offlineVisitFlag !== 'true') { | ||
| return; | ||
| } | ||
| trackOfflinePageViewEvent(networkType); | ||
| localStorage.removeItem(OFFLINE_VISIT_FLAG); | ||
| } catch (error) { | ||
| // eslint-disable-next-line no-console | ||
| console.error('usePWAOfflineTracking', error); | ||
| } | ||
| }, [isOnline, networkType, trackOfflinePageViewEvent]); | ||
| }; | ||
|
|
||
| export default usePWAOfflineTracking; | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.