Add Product Galaxy — 3D map of how PostHog products fit together#17019
Draft
rafaeelaudibert wants to merge 1 commit into
Draft
Add Product Galaxy — 3D map of how PostHog products fit together#17019rafaeelaudibert wants to merge 1 commit into
rafaeelaudibert wants to merge 1 commit into
Conversation
Adds a new /products/galaxy app: a force-directed 3D graph rendered with react-force-graph-3d, styled like a 1998-vintage sci-fi terminal. It turns the implicit "which products go well together" relationships in the productData files into something visitors can actually see and play with. How it works: - Each of the 16 main billed products is a wireframe node, coloured by its brand token. Edges are the existing `pairsWith` declarations. - Visitors click nodes to add products to their "fleet" (i.e. "what I already use"). The right rail then scores the remaining products by edge weight, surfacing recommended companions with the original pairsWith marketing copy as supporting bullets. - A custom d3-force pulls fleet nodes one way and pushes other products outward by BFS distance, so a selection visually stratifies the universe into immediate neighbours, two-hop products, and the far-away things. The camera slowly flies to fit the new layout. - Particles flow outward along edges from the fleet (direction is flipped per-link based on BFS depth) so the recommended next steps are obvious from across the room. - Marketing can deep-link via `?using=product_analytics,session_replay`, which prefills the fleet and lands directly in the angled view. Data layer: - All product relationships move into a new `src/hooks/productData/relationships.ts` file — single source of truth for `pairsWith`, `billedWith`, `sharesFreeTier`, and the deprecated `worksWith`. The 16 per-product files no longer carry their own `pairsWith` / `worksWith` arrays; `useProducts` derives the legacy shapes from this file, so `ProductSidebar` and the "Pairs with..." slide keep working unchanged. - Galaxy-specific graph construction (`buildGraph`) and recommendation scoring (`recommend`) live next to their only consumer, in `src/components/ProductGalaxy/graph.ts`. Frontend bits worth noting: - `colors.ts` resolves Tailwind colour tokens against the live DOM (probe span + `getComputedStyle`), caches the result, and feeds the three.js materials. The canvas tracks `tailwind.config.js` / `data-scheme` automatically without a hardcoded hex map. - The HUD/panels use the project's warm grey palette with `orange` as the rare highlight — no neon teal, on theme with the rest of the site. - Crawlable `SSRFallback` lists every product and its pairings so the page has indexable content before the canvas hydrates.
Contributor
Deploy preview
|
Contributor
|
Vale prose linter → found 4 errors, 6 warnings, 0 suggestions in your markdown Full report → Copy the linter results into an LLM to batch-fix issues. Linter being weird? Update the rules!
|
| Line | Severity | Message | Rule |
|---|---|---|---|
| 1:3 | warning | 'ProductGalaxy' heading should be in sentence case, and product names should be capitalized. | PostHogBase.SentenceCase |
| 12:131 | error | Hi, Andy here... use an en dash ( – ) with spaces. On Mac, holding down the Option and hyphen key will give you an en dash. | PostHogBase.EnDash |
| 16:51 | warning | 'starfield' is a possible misspelling. | PostHogBase.Spelling |
| 18:128 | warning | 'pairsWith' is a possible misspelling. | PostHogBase.Spelling |
| 19:52 | error | Hi, Andy here... use an en dash ( – ) with spaces. On Mac, holding down the Option and hyphen key will give you an en dash. | PostHogBase.EnDash |
| 20:32 | warning | 'Crawlable' is a possible misspelling. | PostHogBase.Spelling |
| 44:3 | warning | 'Scanline' is a possible misspelling. | PostHogBase.Spelling |
| 47:149 | error | Hi, Andy here... use an en dash ( – ) with spaces. On Mac, holding down the Option and hyphen key will give you an en dash. | PostHogBase.EnDash |
| 59:4 | warning | 'SSR considerations' heading should be in sentence case, and product names should be capitalized. | PostHogBase.SentenceCase |
| 63:130 | error | Hi, Andy here... use an en dash ( – ) with spaces. On Mac, holding down the Option and hyphen key will give you an en dash. | PostHogBase.EnDash |
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Changes
Adds a new windowed app at
/products/galaxy— a force-directed 3D graph of how PostHog's 16 main products relate to one another, styled like a 1998-vintage sci-fi terminal. It turns the implicitpairsWithrelationships scattered across the product data files into something visitors can actually see and play with.How it works
pairsWithdeclarations.pairsWithmarketing copy as bullets./products/galaxy?using=product_analytics,session_replayto prefill the fleet and land directly in the angled view.Data layer changes
src/hooks/productData/relationships.tsis now the single source of truth forpairsWith/billedWith/sharesFreeTier/worksWith(the last is@deprecated).pairsWith/worksWitharrays.useProductsderives those legacy shapes fromrelationships.tssoProductSidebarand the "Pairs with..." slide keep working unchanged — no other consumers needed to be touched.buildGraph,recommend, result types) lives insrc/components/ProductGalaxy/graph.tsnext to its only consumer, not in the shared data module.Frontend bits worth flagging for review
src/components/ProductGalaxy/colors.tsresolves Tailwind tokens against the live DOM (probe span +getComputedStyle, cached) and feeds the resulting hex values to three.js materials. The canvas trackstailwind.config.js/data-schemeautomatically — no hardcoded hex map drifting out of sync.orangeas a rare highlight. No neon teal anywhere.SSRFallback.tsxlists every product and its pairings as crawlable text so the page has indexable content before the canvas hydrates.GalaxyCanvas.tsxnext to thegraphReadygate (three-forcegraph defers its first_updateSceneby a frame; callingd3ReheatSimulationduring that window crashes the next animation tick — the gate avoids it).Files touched outside the new directories
src/context/App.tsx— registers/products/galaxyinappSettings(size limits, center position).src/hooks/useProducts.tsx— three lines to injectworksWith/pairsWithfromrelationships.ts.src/hooks/productData/*.tsx— removed the now-duplicatedpairsWith/worksWitharrays from each of the 16 product files (billedWith/sharesFreeTierstay — pricing, not relationship, concerns).package.json/pnpm-lock.yaml— addsreact-force-graph-3dandthree. The chunk is lazy-loaded and only hits this route.Checklist
vercel.json🤖 Generated with Claude Code