fix(settings): make the project token findable as a project API key - #96865
Conversation
Integration guides ask for a "project API key", which is the public project token. Settings stopped using that phrase for the token and the flag-gated project secret API keys section started using it, so the phrase pointed only at a section most organizations cannot open. Name the token as the project API key on its settings entry and next to the token itself, add the synonyms integrations use to the search keywords, and make the secret key copy always say "project secret API key". Generated-By: PostHog Desktop Task-Id: ea4bdcc5-98f5-4033-ab00-b1e56b0fe7de
|
😎 Merged successfully - details. |
🤖 CI report✅ Trunk lane — non-backend laneThis PR is assigned to the non-backend lane. It does not run backend Python tests and may merge in parallel with PRs in other lanes. ✅ Complexity (TypeScript) — cleanCyclomatic complexity above the limit in changed typescript files (10 for production files, 15 for test files). Warn only: worth simplifying when you next touch these functions.
|
| File | Size | Δ vs base |
|---|---|---|
posthog-app/src/scenes/AuthenticatedShell.js |
239.6 KiB | 🔺 +25.1 KiB (+11.7%) |
render-query/src/render-query/render-query.js |
21.93 MiB | 🔺 +13.1 KiB (+0.1%) |
posthog-app/src/scenes/experiments/Experiment.js |
275.1 KiB | 🔺 +5.3 KiB (+2.0%) |
posthog-app/_parent/products/tracing/frontend/TracingScene.js |
126.6 KiB | 🔺 +1.2 KiB (+1.0%) |
posthog-app/_parent/products/posthog_ai/frontend/scenes/TaskTracker/components/SidePanelRunnerImpl.js |
21.9 KiB | 🔺 +1.1 KiB (+5.4%) |
Posted automatically by build-bundle-size-report · uncompressed bytes from dist-report
✅ Eager graph — within budget
How much code each root ships on the eager path — downloaded and parsed before the surface is interactive. Measured from the esbuild output chunks (post-tree-shake, static imports only); lazy import() / React.lazy chunks are not counted.
| Root | Eager (shipped) | Δ vs base | Budget |
|---|---|---|---|
entry (logged-out pages, app bootstrap)src/index.tsx |
1.50 MiB · 22 files | 🔺 +57 B (+0.0%) | ███░░░░░░░ 33.2% of 4.51 MiB |
logged-out boot: index + App + bootApp (preloaded by every page, including /login)src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts |
5.24 MiB · 668 files | 🔺 +267 B (+0.0%) | █████████░ 93.1% of 5.63 MiB |
authenticated shell (every logged-in page)src/scenes/AuthenticatedShell.tsx |
7.67 MiB · 2,680 files | 🔺 +11.9 KiB (+0.2%) | █████████░ 87.4% of 8.77 MiB |
🟢 node_modules/monaco-editor/ stays out of src/index.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/index.tsx
🟢 [object Object] stays out of src/index.tsx
🟢 [object Object] stays out of src/index.tsx
🟢 node_modules/monaco-editor/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/layout/navigation-3000/navigationLogic.tsx stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/scenes/dashboard/dashboardLogic.tsx stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 node_modules/monaco-editor/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/scenes/AuthenticatedShell.tsx
🟢 [object Object] stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/scenes/session-recordings/player/sessionRecordingPlayerLogic.ts stays out of src/scenes/AuthenticatedShell.tsx
🟢 [object Object] stays out of src/scenes/AuthenticatedShell.tsx
🟢 [object Object] stays out of src/scenes/AuthenticatedShell.tsx
Largest files eagerly shipped from src/index.tsx
| Size | File |
|---|---|
| 126.8 KiB | ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js |
| 24.6 KiB | ../node_modules/.pnpm/buffer@6.0.3/node_modules/buffer/index.js |
| 6.3 KiB | ../node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react.production.min.js |
| 4.5 KiB | ../node_modules/.pnpm/@jspm+core@2.1.0/node_modules/@jspm/core/nodelibs/browser/process.js |
| 3.9 KiB | ../node_modules/.pnpm/scheduler@0.23.2/node_modules/scheduler/cjs/scheduler.production.min.js |
| 1.4 KiB | ../node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.js |
| 1.3 KiB | src/RootErrorBoundary.tsx |
| 1.0 KiB | src/index.tsx |
| 912 B | ../node_modules/.pnpm/ieee754@1.2.1/node_modules/ieee754/index.js |
| 854 B | src/scenes/ChunkLoadErrorBoundary.tsx |
Largest files eagerly shipped from src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
| Size | File |
|---|---|
| 281.8 KiB | ../node_modules/.pnpm/posthog-js@1.428.6_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs |
| 267.7 KiB | ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js |
| 255.4 KiB | src/taxonomy/core-filter-definitions-by-group.json |
| 126.8 KiB | ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js |
| 104.2 KiB | src/lib/api.ts |
| 79.0 KiB | src/products.tsx |
| 68.8 KiB | src/lib/lemon-ui/icons/icons.tsx |
| 62.8 KiB | src/lib/utils/eventUsageLogic.ts |
| 38.8 KiB | ../node_modules/.pnpm/@dnd-kit+core@6.0.8_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@dnd-kit/core/dist/core.esm.js |
| 33.9 KiB | ../node_modules/.pnpm/kea@4.0.0-pre.6_patch_hash=139b8d1f1304f9d9da452a9a1244c94ea679dbcb85687d8999563146879fb6f5_react@18.3.1/node_modules/kea/lib/index.cjs.js |
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx
| Size | File |
|---|---|
| 281.8 KiB | ../node_modules/.pnpm/posthog-js@1.428.6_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs |
| 267.7 KiB | ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js |
| 255.4 KiB | src/taxonomy/core-filter-definitions-by-group.json |
| 153.8 KiB | ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js |
| 126.8 KiB | ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js |
| 104.2 KiB | src/lib/api.ts |
| 95.8 KiB | ../packages/quill/packages/quill/dist/index.js |
| 93.3 KiB | ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js |
| 90.6 KiB | ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/dist/index.js |
| 79.0 KiB | src/products.tsx |
Posted automatically by check-eager-graph · sizes are eager output bytes (shipped, post-tree-shake) from the esbuild metafile · part of #32479
✅ Toolbar bundle — eager 2.29 MiB within budget
What the toolbar ships to customer pages, measured from the esbuild output (minified, post-tree-shake). The eager set is the entry plus everything statically imported from it — fetched before any feature runs; deferred chunks load lazily. The eager guardrail is 5.72 MiB. Each output file must also stay below 10 MB, where CloudFront stops compressing it. The module boundary is enforced separately by check-toolbar-graph.
| Metric | Size | Δ vs base | Budget |
|---|---|---|---|
| Eager (shipped) entry + static imports |
2.29 MiB · 18 files | 🔺 +117 B (+0.0%) | ████░░░░░░ 40.0% of 5.72 MiB |
| Deferred (lazy) | 2.11 MiB · 45 files | 🟢 -34 B (-0.0%) | n/a — loads on demand |
Loader dist/toolbar.js |
1.1 KiB | no change | █░░░░░░░░░ 5.8% of 19.5 KiB |
Largest eagerly-shipped chunks
| Size | File |
|---|---|
| 756.5 KiB | dist/toolbar/toolbar-app-OTV6KLUI.css |
| 608.8 KiB | dist/toolbar/chunk-chunk-B2Q7O6V6.js |
| 484.7 KiB | dist/toolbar/chunk-chunk-22SLQ6CJ.js |
| 136.6 KiB | dist/toolbar/chunk-chunk-36NNHCHT.js |
| 131.8 KiB | dist/toolbar/chunk-chunk-FDH2IBXT.js |
| 72.2 KiB | dist/toolbar/toolbar-app-DTSCUVCI.js |
| 69.0 KiB | dist/toolbar/chunk-chunk-TSAL54PB.js |
| 35.6 KiB | dist/toolbar/chunk-chunk-M5ROW2YT.js |
| 21.0 KiB | dist/toolbar/chunk-chunk-XEJG47OJ.js |
| 6.8 KiB | dist/toolbar/chunk-chunk-DV7IWQNF.js |
Posted automatically by check-toolbar-size · sizes are toolbar output bytes (shipped, post-tree-shake) from the esbuild metafile
✅ Dist folder size — 🔺 +513.1 KiB (+0.0%)
Total size of the built frontend/dist folder (all assets), compared against the base branch.
Total: 1458.68 MiB · 🔺 +513.1 KiB (+0.0%)
Rendering the settings page showed the same sentence in the section description and in the token field text, about 300 pixels apart. Keep the description, which is also what the settings search indexes. Generated-By: PostHog Desktop Task-Id: ea4bdcc5-98f5-4033-ab00-b1e56b0fe7de
|
✅ Visual changes approved by @rafaeelaudibert — baseline updated in 4 changed. Changed |
4 updated Run: d579a7dc-1e99-4e7b-ad17-00afe9924901 Co-authored-by: rafaeelaudibert <32079912+rafaeelaudibert@users.noreply.github.com>
Problem
A person following a third-party integration guide that asks for a "project API key" cannot find one in project settings.
The public write token they need is there, under "Project token & ID", but nothing on that page uses the phrase the guide asked for.
The one place in settings named "project API key" is the project secret API keys section, which sits behind a beta flag most organizations do not have.
So the search ends on a beta they cannot open, and support answers the same question again.
The phrase moved in two steps.
#48480 renamed the token's settings entry from "Project API key & ID" to "Project token & ID".
The project secret API keys work then used "project API key" for its own key in toasts and dialogs.
Changes
The token's title stays "Project token & ID" rather than reverting to the old name.
Two settings entries both called "project API key" would rebuild the collision from the other side, and "project token" is the name the docs and the SDKs use.
Before
After
How did you test this code?
Three cases were added to
settingsSearch.test.tsx, searching the shippedSETTINGS_MAPrather than the file's fixture.They catch the regression where someone trims the synonym keywords off the token entry: "client api key", "public api key" and "write key" then rank personal API keys first, and "write key" drops the token out of the top five entirely.
All three fail against the pre-change keywords and pass after, verified locally.
The secret-key copy changes are string edits with no branch to cover.
The screenshots above come from the
Scenes-App/Settings/ProjectStorybook story, rendered headlessly. The same story at a 900px viewport wraps the new sentence onto a second line with no clipping.Not run: the dev stack, and any manual click-through of the secret key dialogs.
Automatic notifications
Docs update
None.
🤖 Agent context
Autonomy: Fully autonomous
Claude Code implemented the recommended step from a PostHog Signals inbox report. No human directed the work in this session, so the PR is unassigned.
Skills invoked:
/writing-user-facing-copy,/writing-tests,/writing-pr-descriptions.Three findings changed the shape of the work.
The report asked for the phrase to go back on the token's title; the title kept its current name for the reason given under Changes, and the phrase went on the description instead.
The first draft of the test asserted that a search for "project api key" finds the token, which passed before the change too, because the existing
api keyandproject idkeywords already satisfy the word-by-word matcher. It was replaced with the three synonyms the change actually fixes.The first draft also put the sentence on both the section description and the token field text. Rendering the page showed the two about 300 pixels apart, so the second commit drops the duplicate.
Public artifact: the report drew on customer support tickets. Nothing from them reaches this PR. The committed strings and test terms are the product's own vocabulary, and the screenshots show Storybook's mock project.