{"_id":"@atlaskit/ufo-experience-key","_rev":"3-2b3541858204ddc5c675534d26ef1507","name":"@atlaskit/ufo-experience-key","dist-tags":{"latest":"1.0.0"},"versions":{"0.2.0":{"name":"@atlaskit/ufo-experience-key","version":"0.2.0","_id":"@atlaskit/ufo-experience-key@0.2.0","maintainers":[{"name":"atlassianartifactteam","email":"eng-development-tooling-secrets-and-artifacts@atlassian.com"}],"dist":{"shasum":"88deb25357982ef7b68fcef8ad3d6664f7d64020","tarball":"https://registry.npmjs.org/@atlaskit/ufo-experience-key/-/ufo-experience-key-0.2.0.tgz","fileCount":8,"integrity":"sha512-1T/8YLo35ILup1aG0IGTvTAGV5CztIeRaCJs43Vw8WQ6gyW65bvnyQsL5vC3W8+Vv/RVH8Li5wgOycFFb1qUXA==","signatures":[{"sig":"MEYCIQDt5GF9r3gidUP5k2h1CNjJ0dbzPbXRjtH5K8eqhz1LpwIhAN5UlAZPoF+CNwChAROescHzYxmEXd94Ro2NWhKBzaDL","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":23782},"_from":"file:/tmp/package-1-69af1695-8bce2b6d14d956b6911efbcd-1.tgz","scripts":{"test":"npx jest"},"_npmUser":{"name":"atlassianartifactteam","email":"eng-development-tooling-secrets-and-artifacts@atlassian.com"},"_resolved":"/tmp/package-1-69af1695-8bce2b6d14d956b6911efbcd-1.tgz","atlassian":{"team":"AGG-Platform"},"_integrity":"sha512-1T/8YLo35ILup1aG0IGTvTAGV5CztIeRaCJs43Vw8WQ6gyW65bvnyQsL5vC3W8+Vv/RVH8Li5wgOycFFb1qUXA==","_npmVersion":"10.8.2","description":"Utility for generating UFO experience key headers for GraphQL and HTTP requests across AFM","directories":{},"_nodeVersion":"20.20.0","atlaskit:src":"src/index.tsx","dependencies":{"@atlaskit/react-ufo":"^5.4.0"},"publishConfig":{"registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/ufo-experience-key_0.2.0_1773082264583_0.8724671659719674","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@atlaskit/ufo-experience-key","version":"0.2.1","_id":"@atlaskit/ufo-experience-key@0.2.1","maintainers":[{"name":"atlassianartifactteam","email":"eng-development-tooling-artifacts@atlassian.com"}],"dist":{"shasum":"9ff4a29ab83e9ede64651e21f0585bbfcfc94920","tarball":"https://registry.npmjs.org/@atlaskit/ufo-experience-key/-/ufo-experience-key-0.2.1.tgz","fileCount":8,"integrity":"sha512-O9+NuAl/47VzF4NZiKfafvl2Cu3vFqwN37QI5Xre4mZlR1DNKv3pmIFTTJvCA+kF2S40/plf7dkAolehbODdqA==","signatures":[{"sig":"MEUCIQCK6Hd84QjFv/s+18IbA/bgJgIIzXUoyWlZ4LeNpmupKwIgEup45KIdeFkOO4Kj8pbLNHBMdi0rY3mslLOlrtDtn4o=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":23880},"_from":"file:/tmp/package-1-6a0ee5bb-a55cf63f4fce4a80336e532d-1.tgz","scripts":{"test":"npx jest"},"_npmUser":{"name":"atlassianartifactteam","email":"eng-development-tooling-artifacts@atlassian.com"},"_resolved":"/tmp/package-1-6a0ee5bb-a55cf63f4fce4a80336e532d-1.tgz","atlassian":{"team":"AGG-Platform"},"_integrity":"sha512-O9+NuAl/47VzF4NZiKfafvl2Cu3vFqwN37QI5Xre4mZlR1DNKv3pmIFTTJvCA+kF2S40/plf7dkAolehbODdqA==","_npmVersion":"10.8.2","description":"Utility for generating UFO experience key headers for GraphQL and HTTP requests across AFM","directories":{},"_nodeVersion":"20.20.2","atlaskit:src":"src/index.tsx","dependencies":{"@atlaskit/react-ufo":"^6.0.0"},"publishConfig":{"registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/ufo-experience-key_0.2.1_1779361214782_0.9625174714160343","host":"s3://npm-registry-packages-npm-production"}},"1.0.0":{"name":"@atlaskit/ufo-experience-key","version":"1.0.0","description":"Utility for generating UFO experience key headers for GraphQL and HTTP requests across AFM","publishConfig":{"registry":"https://registry.npmjs.org/"},"atlaskit:src":"src/index.tsx","scripts":{"test":"npx jest"},"atlassian":{"team":"AGG-Platform"},"dependencies":{"@atlaskit/react-ufo":"^7.0.0"},"_id":"@atlaskit/ufo-experience-key@1.0.0","_integrity":"sha512-9OQt9809d5iPthhBLGWYij7Dcum+YPCz3itQkptwWhYcHTST/PQL3/FyaRwir9w0vmk86g2OvCykLJieRS/rKQ==","_resolved":"/tmp/package-1-6a30e25c-2d2986787986ece03fe61349-1.tgz","_from":"file:/tmp/package-1-6a30e25c-2d2986787986ece03fe61349-1.tgz","_nodeVersion":"20.20.2","_npmVersion":"10.8.2","dist":{"integrity":"sha512-9OQt9809d5iPthhBLGWYij7Dcum+YPCz3itQkptwWhYcHTST/PQL3/FyaRwir9w0vmk86g2OvCykLJieRS/rKQ==","shasum":"83f373277f9671bd36dfa80d84e67f573e4893e7","tarball":"https://registry.npmjs.org/@atlaskit/ufo-experience-key/-/ufo-experience-key-1.0.0.tgz","fileCount":8,"unpackedSize":24516,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDMrAEzcO8jhJ98ObSj+CBBohvJm3czywdekNoInnPLGAIhAPcVdmLCk3RMBLPf7A7jmAm0eeeI5WYCgnvRg/4WtBn0"}]},"_npmUser":{"name":"atlassianartifactteam","email":"eng-development-tooling-artifacts@atlassian.com"},"directories":{},"maintainers":[{"name":"atlassianartifactteam","email":"eng-development-tooling-artifacts@atlassian.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/ufo-experience-key_1.0.0_1781588575223_0.6514671840772892"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-09T18:51:04.454Z","modified":"2026-06-16T05:42:55.485Z","0.2.0":"2026-03-09T18:51:04.743Z","0.2.1":"2026-05-21T11:00:14.953Z","1.0.0":"2026-06-16T05:42:55.376Z"},"description":"Utility for generating UFO experience key headers for GraphQL and HTTP requests across AFM","maintainers":[{"name":"atlassianartifactteam","email":"eng-development-tooling-artifacts@atlassian.com"}],"readme":"# UFO Experience Key\n\nUtility for generating UFO experience key headers for GraphQL and HTTP requests across Atlassian\nFrontend Monorepo (AFM).\n\n## Purpose\n\nThis package provides utilities to capture and generate experience key headers for GraphQL and HTTP\nrequests. Experience keys represent feature names registered in Glance (formerly PerfPortal) and are\nused to track which frontend features initiated requests.\n\n## Installation\n\n```bash\nnpm install @atlaskit/ufo-experience-key\n```\n\n## Exports\n\n### `PRODUCT_NAMES`\n\nConstants for product names to ensure consistency across the codebase.\n\n```typescript\nimport { PRODUCT_NAMES } from '@atlaskit/ufo-experience-key';\n\nexport const PRODUCT_NAMES = {\n\tJIRA: 'jira',\n\tCONFLUENCE: 'confluence',\n\tMERCURY: 'mercury',\n\tSOFTWARE: 'software',\n\tSERVICE_DESK: 'serviceDesk',\n\tCORE: 'core',\n\tPRODUCT_DISCOVERY: 'product-discovery',\n\tCUSTOMER_SERVICE: 'customer-service',\n} as const;\n```\n\n### `getUfoExperienceKey(product: string): string`\n\nBuilds the UFO experience key in the format: `product.fe.loadType.featureName`\n\n**Parameters:**\n\n- `product` (string): The product name - use `PRODUCT_NAMES` constants for type safety\n\n**Returns:** Experience key string (always returns a value, never undefined)\n\n**Example:**\n\n```typescript\nimport { getUfoExperienceKey, PRODUCT_NAMES } from '@atlaskit/ufo-experience-key';\n\nconst key = getUfoExperienceKey(PRODUCT_NAMES.JIRA);\n// Returns: \"jira.fe.page-load.issueView\" (if active interaction exists)\n// Returns: \"jira.fe.feature-type-absent.feature-name-absent\" (if no active interaction)\n```\n\n### `getUfoExperienceKeyHeader(product: string)`\n\nReturns the header object to be included in GraphQL/HTTP requests.\n\n**Parameters:**\n\n- `product` (string): The product name - use `PRODUCT_NAMES` constants for type safety\n\n**Returns:** \n- When active interaction exists: `{ 'atl-paas-cnsmr-ctx-experience-key': string }`\n- When no active interaction: `{ 'atl-paas-missing-experience-key-product': string }`\n\nAlways returns a value object, never undefined or null.\n\n**Example:**\n\n```typescript\nimport { getUfoExperienceKeyHeader, PRODUCT_NAMES } from '@atlaskit/ufo-experience-key';\n\n// In GraphQL middleware/headers layer\nconst headers = {\n\t'Content-Type': 'application/json',\n\t...getUfoExperienceKeyHeader(PRODUCT_NAMES.JIRA),\n\t// ... other headers\n};\n\n// With active interaction:\n// {\n//   'atl-paas-cnsmr-ctx-experience-key': 'jira.fe.page-load.issueView'\n// }\n\n// Without active interaction:\n// {\n//   'atl-paas-missing-experience-key-product': 'jira'\n// }\n```\n\n### `mergeUfoExperienceKeyHeaders(product: string, existingHeaders?: Record<string, string>)`\n\nConvenience utility for merging UFO experience key headers into an existing headers object.\nUseful for code that constructs headers manually (e.g., raw `fetch()` calls).\n\n**Parameters:**\n\n- `product` (string): The product name - use `PRODUCT_NAMES` constants for type safety\n- `existingHeaders` (optional): Existing headers to merge with\n\n**Returns:** Headers object with UFO experience key headers merged in\n\n**Example:**\n\n```typescript\nimport { mergeUfoExperienceKeyHeaders, PRODUCT_NAMES } from '@atlaskit/ufo-experience-key';\n\nconst headers = mergeUfoExperienceKeyHeaders(PRODUCT_NAMES.JIRA, {\n\t'Content-Type': 'application/json',\n\t'Authorization': 'Bearer token'\n});\n\nfetch('/gateway/api/graphql', {\n\tmethod: 'POST',\n\theaders,\n\tbody: JSON.stringify(...)\n});\n```\n\n## Constants\n\nThe following constants are exported for use in type definitions and code:\n\n### `EXPERIENCE_KEY_HEADER_NAME`\n\nHeader name used when an active interaction exists.\n\n```typescript\nimport { EXPERIENCE_KEY_HEADER_NAME } from '@atlaskit/ufo-experience-key';\n// Value: 'atl-paas-cnsmr-ctx-experience-key'\n```\n\n### `MISSING_EXPERIENCE_KEY_HEADER_NAME`\n\nHeader name used when no active interaction exists.\n\n```typescript\nimport { MISSING_EXPERIENCE_KEY_HEADER_NAME } from '@atlaskit/ufo-experience-key';\n// Value: 'atl-paas-missing-experience-key-product'\n```\n\n## Experience Key Format\n\n### With Active Interaction\nFormat: `product.fe.loadType.featureName`\n\nExample: `jira.fe.page-load.issueView`\n\n### Without Active Interaction\nFormat: `product.fe.feature-type-absent.feature-name-absent`\n\nExample: `jira.fe.feature-type-absent.feature-name-absent`\n\n## Load Type Mapping\n\nUFO interaction types are mapped to load types as follows:\n\n| Interaction Type | Load Type           |\n| ---------------- | ------------------- |\n| `page_load`      | `page-load`         |\n| `transition`     | `page-load`         |\n| `segment`        | `page-segment-load` |\n| Other/undefined  | `inline-result`     |\n\n## Architecture & Design Principles\n\nThis utility is designed to be called from centralized middleware/headers layers (e.g., Relay fetch\nlayer, HTTP fetch layer) rather than at individual component/hook call sites.\n\n**Benefits:**\n\n- **Single source of truth** for experience key generation\n- **Automatic application** to all requests from a single location\n- **Simplified maintenance** and updates across all products\n- **No performance overhead** from repeated calls\n- **Clear separation of concerns** - infrastructure layer handles header injection\n\n**Design:**\n\n- Pure functions with no side effects\n- Constants extracted for maintainability (`EXPERIENCE_KEY_HEADER_NAME`, `MISSING_EXPERIENCE_KEY_HEADER_NAME`)\n- Helper functions for clarity (`buildActiveExperienceKey`, `buildAbsentExperienceKey`, `deriveLoadType`)\n- Always returns a value - no undefined/null returns\n- Optional chaining for safe null checks\n\n## Usage in Different Products\n\n### Jira\n\n```typescript\nimport { getUfoExperienceKeyHeader, PRODUCT_NAMES } from '@atlaskit/ufo-experience-key';\n\n// In jira/src/packages/platform/fetch/src/utils/observability-headers.tsx\nconst experienceKeyHeader = getUfoExperienceKeyHeader(PRODUCT_NAMES.JIRA);\n```\n\n### Confluence\n\n```typescript\nimport { getUfoExperienceKeyHeader, PRODUCT_NAMES } from '@atlaskit/ufo-experience-key';\n\n// In confluence/next/packages/graphql/src/createWrappedFetch.ts\nconst experienceKeyHeader = getUfoExperienceKeyHeader(PRODUCT_NAMES.CONFLUENCE);\n```\n\n### Mercury\n\n```typescript\nimport { getUfoExperienceKeyHeader, PRODUCT_NAMES } from '@atlaskit/ufo-experience-key';\n\n// In mercury/src/clients/apolloClient.ts\nconst experienceKeyHeader = getUfoExperienceKeyHeader(PRODUCT_NAMES.MERCURY);\n```\n\n## Related\n\n- [@atlaskit/react-ufo](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/src/master/platform/packages/ufo/react-ufo/) -\n  UFO interaction metrics\n","readmeFilename":"README.md"}