Improve header setup

This commit is contained in:
Eric Bailey
2026-02-19 11:55:26 -06:00
parent 52c2c0ffd3
commit 9cfc5eaa22
4 changed files with 42 additions and 24 deletions
+3
View File
@@ -78,6 +78,7 @@ import {
features,
setupDeviceId,
} from '#/analytics'
import {useSetAnalyticsHeaders} from '#/analytics/useSetAnalyticsHeaders'
import {IS_ANDROID, IS_IOS} from '#/env'
import {
prefetchLiveEvents,
@@ -117,6 +118,8 @@ function InnerApp() {
const {_} = useLingui()
const hasCheckedReferrer = useStarterPackEntry()
useSetAnalyticsHeaders()
// init
useEffect(() => {
async function onLaunch(account?: SessionAccount) {
+3
View File
@@ -68,6 +68,7 @@ import {
features,
setupDeviceId,
} from '#/analytics'
import {useSetAnalyticsHeaders} from '#/analytics/useSetAnalyticsHeaders'
import {
prefetchLiveEvents,
Provider as LiveEventsProvider,
@@ -93,6 +94,8 @@ function InnerApp() {
const {_} = useLingui()
const hasCheckedReferrer = useStarterPackEntry()
useSetAnalyticsHeaders()
// init
useEffect(() => {
async function onLaunch(account?: SessionAccount) {
+36
View File
@@ -0,0 +1,36 @@
import {useAgent} from '#/state/session'
import {getDeviceId, useSessionId} from '#/analytics/identifiers'
import {getIPGeolocationString} from '#/geolocation/util'
/**
* Get anonymous identifiers and construct headers we use for requests that may
* trigger experiment exposures in our backend. These values are used for A/B
* test bucketing, in addition to the user DID, if the request is
* authenticated. They ensure we can consistently deliver beta features to
* users.
*
* This should be mounted as high as possible in the tree, _after_
* `setupDeviceId` has resolved and session context is available.
*
* The setters here are not wrapped in an effect because this hook does not
* render that often, and we want to make sure the headers are set as soon as
* possible after `agent` changes to ensure analytics events are properly
* attributed.
*
* The values here are not specific to an account. If we add new values here in
* the future, we should ensure that they are not account specific and handle
* those separately (and more carefully).
*
* These headers must stay in sync with our appview.
* @see https://github.com/bluesky-social/atproto/blob/39cf199df5847d3fd4a60d8cdeb604a0e07f9784/packages/bsky/src/feature-gates/utils.ts#L7-L8
*/
export function useSetAnalyticsHeaders() {
const agent = useAgent()
const sessionId = useSessionId()
agent.setHeader('X-Bsky-Device-Id', getDeviceId() ?? '')
agent.setHeader('X-Bsky-Session-Id', sessionId)
const geo = getIPGeolocationString()
if (geo) {
agent.setHeader('X-Bsky-IP-Geolocation', geo)
}
}
-24
View File
@@ -2,12 +2,10 @@ import {useMemo} from 'react'
import {BSKY_SERVICE} from '#/lib/constants'
import {type SessionAccount} from '#/state/session'
import {getDeviceId, getSessionId} from '#/analytics/identifiers'
import {
type MergeableMetadata,
type SessionMetadata,
} from '#/analytics/metadata'
import {getIPGeolocationString} from '#/geolocation/util'
/**
* Thin `useMemo` wrapper that marks the metadata as memoized and provides a
@@ -33,25 +31,3 @@ export function accountToSessionMetadata(
}
}
}
/**
* Get anonymous identifiers and construct headers we use for requests that may
* trigger experiment exposures in our backend. These values are used for A/B
* test bucketing, in addition to the user DID, if the request is
* authenticated. They ensure we can consistently deliver beta features to
* users.
*
* These headers must stay in sync with our appview.
* @see https://github.com/bluesky-social/atproto/blob/39cf199df5847d3fd4a60d8cdeb604a0e07f9784/packages/bsky/src/feature-gates/utils.ts#L7-L8
*/
export function getAnalyticsHeaders() {
return {
'X-Bsky-Device-Id': getDeviceId(),
'X-Bsky-Session-Id': getSessionId(),
/**
* This can already be inferred from server requests, but for consistency
* in feature bucketing, we also include it here.
*/
'X-Bsky-IP-Geolocation': getIPGeolocationString(),
}
}