Skip to content

Commit 5a7bbae

Browse files
abueideclaude
andcommitted
fix(browser): re-read document.referrer when buffered value is empty
On iOS Safari, document.referrer is not yet populated when the snippet captures BufferedPageContext. This causes context.page.referrer to be empty in all Segment calls for the session. Re-read document.referrer in popPageContext() when the buffered value is empty. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 8f10626 commit 5a7bbae

File tree

2 files changed

+53
-1
lines changed

2 files changed

+53
-1
lines changed

packages/browser/src/core/buffer/__tests__/index.test.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
flushAnalyticsCallsInNewTask,
66
PreInitMethodCallBuffer,
77
PreInitMethodName,
8+
popPageContext,
89
} from '..'
910
import { Analytics } from '../../analytics'
1011
import { Context } from '../../context'
@@ -13,6 +14,7 @@ import { User } from '../../user'
1314
import { getBufferedPageCtxFixture } from '../../../test-helpers/fixtures'
1415
import * as GlobalAnalytics from '../../../lib/global-analytics-helper'
1516
import { setVersionType } from '../../../lib/version-type'
17+
import { BufferedPageContextDiscriminant } from '../../page'
1618

1719
describe(PreInitMethodCallBuffer, () => {
1820
beforeEach(() => {
@@ -359,6 +361,47 @@ describe(AnalyticsBuffered, () => {
359361
})
360362
})
361363

364+
describe(popPageContext, () => {
365+
const makeBPC = (referrer: string) => ({
366+
__t: BufferedPageContextDiscriminant,
367+
c: undefined,
368+
p: '/',
369+
u: 'https://example.com/',
370+
s: '',
371+
t: 'Test',
372+
r: referrer,
373+
})
374+
375+
function withDocumentReferrer(value: string, fn: () => void) {
376+
const original = document.referrer
377+
Object.defineProperty(document, 'referrer', { value, configurable: true })
378+
try {
379+
fn()
380+
} finally {
381+
Object.defineProperty(document, 'referrer', {
382+
value: original,
383+
configurable: true,
384+
})
385+
}
386+
}
387+
388+
it('should use fresh document.referrer when buffered referrer is empty', () => {
389+
withDocumentReferrer('https://www.google.com/', () => {
390+
const args: unknown[] = [makeBPC('')]
391+
const result = popPageContext(args)
392+
expect(result!.referrer).toBe('https://www.google.com/')
393+
})
394+
})
395+
396+
it('should not override when both buffered and document.referrer are empty', () => {
397+
withDocumentReferrer('', () => {
398+
const args: unknown[] = [makeBPC('')]
399+
const result = popPageContext(args)
400+
expect(result!.referrer).toBe('')
401+
})
402+
})
403+
})
404+
362405
describe(callAnalyticsMethod, () => {
363406
let ajs!: Analytics
364407
let resolveSpy!: jest.Mock<any, any>

packages/browser/src/core/buffer/index.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,16 @@ export const flushAnalyticsCallsInNewTask = (
107107
export const popPageContext = (args: unknown[]): PageContext | undefined => {
108108
if (hasBufferedPageContextAsLastArg(args)) {
109109
const ctx = args.pop() as BufferedPageContext
110-
return createPageContext(ctx)
110+
const pageCtx = createPageContext(ctx)
111+
// Re-read referrer if the buffered value is empty (iOS Safari timing issue)
112+
if (
113+
!pageCtx.referrer &&
114+
typeof document !== 'undefined' &&
115+
document.referrer
116+
) {
117+
return { ...pageCtx, referrer: document.referrer }
118+
}
119+
return pageCtx
111120
}
112121
}
113122

0 commit comments

Comments
 (0)