diff --git a/src/components/DocsLayout.tsx b/src/components/DocsLayout.tsx index 50ea2fde..bf4fec98 100644 --- a/src/components/DocsLayout.tsx +++ b/src/components/DocsLayout.tsx @@ -599,10 +599,7 @@ export function DocsLayout({ const [isFullWidth, setIsFullWidth] = useLocalStorage('docsFullWidth', false) - const activePartners = partners.filter( - (d) => - d.status === 'active' && d.name !== 'Nozzle.io' && d.id !== 'fireship', - ) + const activePartners = partners.filter((d) => d.status === 'active') const groupInitialOpenState = React.useMemo(() => { return menuConfig.reduce>((acc, group, index) => { @@ -937,31 +934,14 @@ export function DocsLayout({ {!isLandingPage && ( -
- - { - trackEvent('become_partner_clicked', { - framework: currentFramework.framework, - library_id: libraryId, - placement: 'docs_right_rail', - }) - }} - > - Become a Partner - -
+
diff --git a/src/components/Gam.tsx b/src/components/Gam.tsx index c444bc09..ee1bd872 100644 --- a/src/components/Gam.tsx +++ b/src/components/Gam.tsx @@ -59,7 +59,10 @@ export function GamVrec1({ return (
{promos.map((promo) => ( = { + gold: { + flexBasis: 'basis-full sm:basis-1/2', + minHeight: 'min-h-[220px]', + logoMaxWidth: 'max-w-[400px]', + logoMaxHeight: 'max-h-[120px]', + padding: 'p-12', + }, + silver: { + flexBasis: 'basis-full sm:basis-1/3 lg:basis-1/4', + minHeight: 'min-h-[130px]', + logoMaxWidth: 'max-w-[180px]', + logoMaxHeight: 'max-h-[56px]', + padding: 'p-6', + }, + bronze: { + flexBasis: 'basis-1/2 sm:basis-1/4 lg:basis-1/5 xl:basis-1/6', + minHeight: 'min-h-[100px]', + logoMaxWidth: 'max-w-[110px]', + logoMaxHeight: 'max-h-[36px]', + padding: 'p-4', + }, +} + function PartnerGridItem({ analyticsPlacement, analyticsProperties, @@ -33,7 +73,7 @@ function PartnerGridItem({ }, }) - const width = Math.max(Math.round(120 + 280 * partner.score), 150) + const layout = tierLayout[partner.tier ?? 'bronze'] return ( { trackEvent('partner_card_clicked', { partner_id: partner.id, @@ -56,7 +96,15 @@ function PartnerGridItem({ }) }} > - +
+ +
) } @@ -70,22 +118,56 @@ export function PartnersGrid({ (partner) => partner.status === 'active', ) - // Sort by score descending so larger partners come first - const sortedItems = [...items].sort((a, b) => b.score - a.score) + const tiers: Array = ['gold', 'silver', 'bronze'] + + const tiersWithPartners = tiers + .map((tier) => ({ + tier, + partners: items + .filter((partner) => (partner.tier ?? 'bronze') === tier) + .sort((a, b) => b.score - a.score), + })) + .filter((row) => row.partners.length > 0) + .sort((a, b) => partnerTierOrder[a.tier] - partnerTierOrder[b.tier]) + + let slotIndex = 0 return ( - -
- {sortedItems.map((partner, index) => ( - - ))} -
-
+
+ {tiersWithPartners.map((row) => { + const flare = partnerTierFlares[row.tier] + return ( + +
+
+ {flare.icon} + + {partnerTierLabels[row.tier]} + +
+
+ {row.partners.map((partner) => { + const index = slotIndex++ + return ( + + ) + })} +
+
+
+ ) + })} +
) } diff --git a/src/components/RightRail.tsx b/src/components/RightRail.tsx index 85057d9c..92bca950 100644 --- a/src/components/RightRail.tsx +++ b/src/components/RightRail.tsx @@ -1,7 +1,13 @@ import * as React from 'react' import { Link } from '@tanstack/react-router' import { twMerge } from 'tailwind-merge' -import { PartnerImage } from '~/utils/partners' +import { + PartnerImage, + partnerTierFlares, + partnerTierLabels, + partnerTierOrder, + type PartnerTier, +} from '~/utils/partners' import { trackEvent, useTrackedImpression } from '~/utils/analytics' type RailPartner = { @@ -9,6 +15,7 @@ type RailPartner = { name: string href: string score: number + tier?: PartnerTier image: Parameters[0]['config'] } @@ -38,7 +45,7 @@ export function RightRail({
*]:shrink-0', )} > {children} @@ -47,6 +54,39 @@ export function RightRail({ ) } +const railTierLayout: Record< + PartnerTier, + { + flexBasis: string + minHeight: string + logoMaxWidth: string + logoMaxHeight: string + padding: string + } +> = { + gold: { + flexBasis: 'basis-full', + minHeight: 'min-h-[72px]', + logoMaxWidth: 'max-w-[180px]', + logoMaxHeight: 'max-h-[40px]', + padding: 'px-4 py-3', + }, + silver: { + flexBasis: 'basis-1/2', + minHeight: 'min-h-[60px]', + logoMaxWidth: 'max-w-[100px]', + logoMaxHeight: 'max-h-[26px]', + padding: 'px-2.5 py-2.5', + }, + bronze: { + flexBasis: 'basis-1/3', + minHeight: 'min-h-[56px]', + logoMaxWidth: 'max-w-[70px]', + logoMaxHeight: 'max-h-[22px]', + padding: 'px-2 py-2', + }, +} + export function PartnersRail({ analyticsPlacement = 'partners_rail', analyticsProperties, @@ -60,25 +100,77 @@ export function PartnersRail({ title?: string titleTo?: '/partners' }) { + const tiers: Array = ['gold', 'silver', 'bronze'] + + const rowsByTier = tiers + .map((tier) => ({ + tier, + partners: partners + .filter((partner) => (partner.tier ?? 'bronze') === tier) + .sort((a, b) => b.score - a.score), + })) + .filter((row) => row.partners.length > 0) + .sort((a, b) => partnerTierOrder[a.tier] - partnerTierOrder[b.tier]) + + let slotIndex = 0 + return ( -
-
+
+ - {partners.map((partner, index) => ( - - ))} + {rowsByTier.map((row) => { + const flare = partnerTierFlares[row.tier] + return ( +
+ {/* Tier-colored top line */} +
+ {/* Absolute top-left tier label */} +
+ {flare.icon} + {partnerTierLabels[row.tier]} +
+ {row.partners.map((partner) => { + const index = slotIndex++ + return ( + + ) + })} +
+ ) + })}
) } @@ -94,7 +186,7 @@ function PartnersRailItem({ index: number partner: RailPartner }) { - const widthPercent = Math.round(partner.score * 100) + const layout = railTierLayout[partner.tier ?? 'bronze'] const ref = useTrackedImpression({ event: 'partner_impression', properties: { @@ -112,12 +204,12 @@ function PartnersRailItem({ href={partner.href} target="_blank" rel="noreferrer" - className="flex items-center justify-center px-3 py-2 border-r border-b border-gray-500/20 hover:bg-gray-500/10 transition-colors duration-150 ease-out" - style={{ - flexBasis: `${widthPercent}%`, - flexGrow: 1, - flexShrink: 0, - }} + className={twMerge( + 'flex items-center justify-center overflow-hidden border-r border-b border-gray-500/20 hover:bg-gray-500/10 transition-colors duration-150 ease-out', + layout.flexBasis, + layout.minHeight, + layout.padding, + )} onClick={() => { trackEvent('partner_click', { partner_id: partner.id, @@ -130,11 +222,16 @@ function PartnersRailItem({ }} >
- +
) diff --git a/src/routes/blog.$.tsx b/src/routes/blog.$.tsx index e09ebc78..6c79f427 100644 --- a/src/routes/blog.$.tsx +++ b/src/routes/blog.$.tsx @@ -113,13 +113,7 @@ function BlogPost() { const repo = 'tanstack/tanstack.com' const branch = 'main' const activePartners = React.useMemo( - () => - partners.filter( - (d) => - d.status === 'active' && - d.name !== 'Nozzle.io' && - d.id !== 'fireship', - ), + () => partners.filter((d) => d.status === 'active'), [], ) diff --git a/src/routes/blog.index.tsx b/src/routes/blog.index.tsx index ef4a7dce..cbf4ea02 100644 --- a/src/routes/blog.index.tsx +++ b/src/routes/blog.index.tsx @@ -70,16 +70,13 @@ export const Route = createFileRoute('/blog/')({ function BlogIndex() { const frontMatters = Route.useLoaderData() as BlogFrontMatter[] - const activePartners = partners.filter( - (d) => - d.status === 'active' && d.name !== 'Nozzle.io' && d.id !== 'fireship', - ) + const activePartners = partners.filter((d) => d.status === 'active') return ( -
-
-
-
+
+
+
+

Blog

@@ -153,19 +150,19 @@ function BlogIndex() { )}
- - -
- -
- - - -
+ + +
+ +
+ + + +
diff --git a/src/routes/partners.index.tsx b/src/routes/partners.index.tsx index 511a983a..78cc7f7c 100644 --- a/src/routes/partners.index.tsx +++ b/src/routes/partners.index.tsx @@ -1,14 +1,20 @@ import { createFileRoute } from '@tanstack/react-router' import { Footer } from '~/components/Footer' import { Card } from '~/components/Card' -import { partners, PartnerImage } from '~/utils/partners' +import { + partners, + PartnerImage, + partnerTierFlares, + partnerTierLabels, + partnerTierOrder, + type PartnerTier, +} from '~/utils/partners' import { seo } from '~/utils/seo' import { Library } from '~/libraries' import { useState } from 'react' import * as React from 'react' import { ListFilter, X } from 'lucide-react' import { Button } from '~/ui' -import { NetlifyImage } from '~/components/NetlifyImage' import { startProject } from '~/libraries/start' import { routerProject } from '~/libraries/router' import { queryProject } from '~/libraries/query' @@ -301,16 +307,60 @@ function getFilteredPartners(search: PartnersSearch) { }) } +type CardSize = 'gold' | 'silver' | 'bronze' | 'flat' + +const cardSizeLayout: Record< + CardSize, + { + padding: string + logoFrame: string + logoMaxHeight: string + titleSize: string + showDescription: boolean + } +> = { + gold: { + padding: 'p-8', + logoFrame: 'h-32', + logoMaxHeight: 'max-h-24', + titleSize: 'text-2xl', + showDescription: true, + }, + silver: { + padding: 'p-6', + logoFrame: 'h-24', + logoMaxHeight: 'max-h-16', + titleSize: 'text-lg', + showDescription: true, + }, + bronze: { + padding: 'p-4', + logoFrame: 'h-16', + logoMaxHeight: 'max-h-10', + titleSize: 'text-sm', + showDescription: false, + }, + flat: { + padding: 'p-6', + logoFrame: 'h-24', + logoMaxHeight: 'max-h-16', + titleSize: 'text-xl', + showDescription: true, + }, +} + function PartnerDirectoryCard({ filters, isShowingPrevious, partner, slotIndex, + size = 'flat', }: { filters: PartnersSearch isShowingPrevious: boolean partner: (typeof partners)[number] slotIndex: number + size?: CardSize }) { const ref = useTrackedImpression({ event: 'partner_impression', @@ -329,6 +379,8 @@ function PartnerDirectoryCard({ ? `${partner.startDate} - ${partner.endDate}` : null + const layout = cardSizeLayout[size] + return ( -
-
- +
+
+
-

+

{partner.name}

{partner.tagline && ( -

+

{partner.tagline}

)} -
- {isShowingPrevious ? ( - <> - {duration && ( -

- {duration} -

- )} - {partner.libraries && partner.libraries.length > 0 && ( -
- {partner.libraries.map((library) => ( - - {library} - - ))} -
- )} - - ) : ( -

- {partner.llmDescription} -

- )} -
+ {layout.showDescription && ( +
+ {isShowingPrevious ? ( + <> + {duration && ( +

+ {duration} +

+ )} + {partner.libraries && partner.libraries.length > 0 && ( +
+ {partner.libraries.map((library) => ( + + {library} + + ))} +
+ )} + + ) : ( +

+ {partner.llmDescription} +

+ )} +
+ )}
) } +const tierGridCols: Record = { + gold: 'grid grid-cols-1 lg:grid-cols-2 gap-6', + silver: 'grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6', + bronze: 'grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-4', +} + +function TierSectionHeader({ tier }: { tier: PartnerTier }) { + const flare = partnerTierFlares[tier] + return ( +
+
+
+ {flare.icon} + + {partnerTierLabels[tier]} + +
+
+
+ ) +} + +function TieredPartnerSections({ + partners: allPartners, + filters, +}: { + partners: Array<(typeof partners)[number]> + filters: PartnersSearch +}) { + const tiers: Array = ['gold', 'silver', 'bronze'] + + const sections = tiers + .map((tier) => ({ + tier, + partners: allPartners + .filter((partner) => (partner.tier ?? 'bronze') === tier) + .sort((a, b) => b.score - a.score), + })) + .filter((section) => section.partners.length > 0) + .sort((a, b) => partnerTierOrder[a.tier] - partnerTierOrder[b.tier]) + + let slotIndex = 0 + + return ( +
+ {sections.map((section) => ( +
+ +
+ {section.partners.map((partner) => { + const index = slotIndex++ + return ( + + ) + })} +
+
+ ))} +
+ ) +} + function PartnersIndexPage() { const search = normalizePartnersSearch(Route.useSearch()) const navigate = Route.useNavigate() @@ -488,17 +623,24 @@ function PartnersIndexPage() {

)} -
- {filteredPartners.map((partner, slotIndex) => ( - - ))} -
+ {isShowingActive && !hasLibraryFilter ? ( + + ) : ( +
+ {filteredPartners.map((partner, slotIndex) => ( + + ))} +
+ )}
) : (
@@ -540,34 +682,6 @@ function PartnersIndexPage() { Get in Touch
- -
- -

- Lifetime Support Share -

-
-

- This chart is a percentage-based visualization of the lifetime - support each partner has rendered to TanStack. It is updated every 6 - months. -

-
- -
-
diff --git a/src/utils/partners.tsx b/src/utils/partners.tsx index 4f24309a..56be336d 100644 --- a/src/utils/partners.tsx +++ b/src/utils/partners.tsx @@ -59,6 +59,77 @@ type PartnerApplicationStarterIcon = { type ApplicationStarterPartnerTier = 1 | 2 | 3 +export const partnerTiers = ['gold', 'silver', 'bronze'] as const +export type PartnerTier = (typeof partnerTiers)[number] + +export const partnerTierLabels: Record = { + gold: 'Gold', + silver: 'Silver', + bronze: 'Bronze', +} + +export const partnerTierOrder: Record = { + gold: 0, + silver: 1, + bronze: 2, +} + +const partnerTierToBuilderTier: Record< + PartnerTier, + ApplicationStarterPartnerTier +> = { + gold: 1, + silver: 2, + bronze: 3, +} + +export const partnerTierFlares: Record< + PartnerTier, + { + gradientStops: string + iconColor: string + labelColor: string + icon: React.ReactNode + } +> = { + gold: { + gradientStops: + 'from-yellow-400 via-amber-500 to-orange-600 dark:from-yellow-300 dark:via-amber-400 dark:to-orange-400', + iconColor: 'text-amber-500 dark:text-amber-300', + labelColor: 'text-amber-600 dark:text-amber-300', + // 5-point star + icon: ( + + + + ), + }, + silver: { + gradientStops: + 'from-slate-200 via-zinc-400 to-slate-300 dark:from-slate-300 dark:via-zinc-400 dark:to-slate-400', + iconColor: 'text-slate-400 dark:text-slate-300', + labelColor: 'text-slate-500 dark:text-slate-300', + // 4-point sparkle + icon: ( + + + + ), + }, + bronze: { + gradientStops: + 'from-amber-700 via-amber-800 to-amber-950 dark:from-amber-600 dark:via-amber-800 dark:to-amber-950', + iconColor: 'text-amber-800 dark:text-amber-600', + labelColor: 'text-amber-800 dark:text-amber-600', + // diamond + icon: ( + + + + ), + }, +} + export function PartnerImage({ className, config, @@ -162,6 +233,7 @@ export type Partner = { startDate?: string endDate?: string score: number + tier?: PartnerTier brandColor?: string // Primary brand color for game elements tagline?: string // Short tagline for game info cards } @@ -175,7 +247,6 @@ export type ApplicationStarterPartnerSuggestion = { iconSrc?: string image: Partner['image'] label: string - sortOrder: number tags: Array tier: ApplicationStarterPartnerTier } @@ -259,6 +330,7 @@ const neon = (() => { libraries: ['start', 'router'], status: 'active' as const, score: 0.297, + tier: 'silver' as const, href, brandColor: '#00E599', tagline: 'Serverless Postgres', @@ -328,12 +400,13 @@ const clerk = (() => { libraries: ['start', 'router'], status: 'active' as const, score: 0.286, + tier: 'silver' as const, brandColor: '#6C47FF', tagline: 'Authentication', image: { light: clerkLightSvg, dark: clerkDarkSvg, - scale: 0.85, + scale: 0.72, }, llmDescription: 'Authentication and user management platform with prebuilt UI, sessions, organizations, and MFA. Clerk has official SDKs and quickstarts for TanStack React Start and React Router.', @@ -363,6 +436,7 @@ const workos = (() => { libraries: ['start', 'router'] as const, status: 'active' as const, score: 0.314, + tier: 'silver' as const, brandColor: '#6363F1', tagline: 'Enterprise Auth', applicationStarterIcon: { @@ -400,6 +474,7 @@ const agGrid = (() => { libraries: ['table'] as const, status: 'active' as const, score: 0.497, + tier: 'silver' as const, href, brandColor: '#FF8C00', tagline: 'Enterprise Data Grid', @@ -452,6 +527,7 @@ const netlify = (() => { libraries: ['start', 'router'], status: 'active' as const, score: 0.343, + tier: 'silver' as const, href, brandColor: '#00C7B7', tagline: 'Web Deployment', @@ -462,6 +538,7 @@ const netlify = (() => { image: { light: netlifyLightSvg, dark: netlifyDarkSvg, + scale: 1.25, }, llmDescription: 'Deployment platform for web applications with Deploy Previews, Functions, Edge Functions, and an official TanStack Start integration guide.', @@ -491,6 +568,7 @@ const cloudflare = (() => { libraries: libraries.map((l) => l.id), status: 'active' as const, score: 0.857, + tier: 'gold' as const, startDate: 'Sep 2025', brandColor: '#F6821F', tagline: 'Edge Deployment', @@ -523,6 +601,7 @@ const sentry = (() => { libraries: ['start', 'router'], status: 'active' as const, score: 0.229, + tier: 'bronze' as const, href, brandColor: '#362D59', tagline: 'Error Monitoring', @@ -554,7 +633,7 @@ const fireship = (() => { name: 'Fireship', id: 'fireship', libraries: [], - status: 'active' as const, + status: 'inactive' as const, score: 0.014, href, tagline: 'Dev Education', @@ -610,7 +689,7 @@ const nozzle = (() => { name: 'Nozzle.io', id: 'nozzle', href, - status: 'active' as const, + status: 'inactive' as const, score: 0.014, tagline: 'Enterprise SEO', image: { @@ -677,6 +756,7 @@ const unkey = (() => { libraries: ['pacer'] as const, status: 'active' as const, score: 0.051, + tier: 'bronze' as const, href, brandColor: '#222222', tagline: 'API Key Management', @@ -716,6 +796,7 @@ const serpApi = (() => { libraries: libraries.map((l) => l.id), status: 'active' as const, score: 0.41, + tier: 'silver' as const, href, brandColor: '#6361EC', tagline: 'Real-time SERP API', @@ -755,6 +836,7 @@ const electric = (() => { libraries: ['db'] as const, status: 'active' as const, score: 0.283, + tier: 'bronze' as const, href, brandColor: '#7e78db', tagline: 'Sync Engine', @@ -828,6 +910,7 @@ const prisma = (() => { libraries: ['db', 'start'] as const, startDate: 'Aug 2025', score: 0.143, + tier: 'bronze' as const, brandColor: '#2D3748', tagline: 'Database ORM', image: { @@ -863,6 +946,7 @@ const codeRabbit = (() => { libraries: libraries.map((l) => l.id), startDate: 'Aug 2025', score: 1, + tier: 'gold' as const, brandColor: '#FF6B2B', tagline: 'AI Code Review', applicationStarterPromptInstructions: [ @@ -900,6 +984,7 @@ const strapi = (() => { libraries: ['start', 'router'] as const, status: 'active' as const, score: 0.069, + tier: 'bronze' as const, href, brandColor: '#4945FF', tagline: 'Headless CMS', @@ -936,6 +1021,7 @@ const powerSync = (() => { status: 'active' as const, startDate: 'Jan 2026', score: 0.143, + tier: 'bronze' as const, href, tagline: 'Offline-first Sync', applicationStarterPromptInstructions: [ @@ -946,6 +1032,7 @@ const powerSync = (() => { image: { light: powersyncBlackSvg, dark: powersyncWhiteSvg, + scale: 1.2, }, llmDescription: 'Sync engine that keeps backend databases in sync with embedded client-side SQLite for offline-first and realtime applications. Postgres and MongoDB are supported, with MySQL and SQL Server in beta.', @@ -974,6 +1061,7 @@ const railway = (() => { libraries: libraries.map((l) => l.id), status: 'active' as const, score: 0.145, + tier: 'bronze' as const, href, brandColor: '#0B0D0E', tagline: 'Instant Deployment', @@ -1010,6 +1098,7 @@ const openRouter = (() => { status: 'active' as const, startDate: 'Mar 2026', score: 0.344, + tier: 'silver' as const, brandColor: '#7C3AED', tagline: 'Unified LLM API', applicationStarterPromptInstructions: [ @@ -1020,6 +1109,7 @@ const openRouter = (() => { image: { light: openrouterBlackSvg, dark: openrouterWhiteSvg, + scale: 1.25, }, llmDescription: 'Unified API for accessing hundreds of AI models from dozens of providers through a single OpenAI-compatible endpoint, with routing, fallbacks, and privacy controls.', @@ -1070,30 +1160,6 @@ export const partners: Partner[] = [ speakeasy, ] as Partner[] -const applicationStarterPartnerTierOrder = new Map< - string, - { sortOrder: number; tier: ApplicationStarterPartnerTier } ->([ - ['coderabbit', { tier: 1, sortOrder: 0 }], - ['cloudflare', { tier: 1, sortOrder: 1 }], - ['aggrid', { tier: 2, sortOrder: 0 }], - ['supabase', { tier: 2, sortOrder: 1 }], - ['serpapi', { tier: 2, sortOrder: 2 }], - ['netlify', { tier: 2, sortOrder: 3 }], - ['openrouter', { tier: 2, sortOrder: 4 }], - ['workos', { tier: 2, sortOrder: 5 }], - ['clerk', { tier: 2, sortOrder: 6 }], - ['electric', { tier: 2, sortOrder: 7 }], - ['railway', { tier: 2, sortOrder: 8 }], - ['sentry', { tier: 3, sortOrder: 0 }], - ['prisma', { tier: 3, sortOrder: 1 }], - ['powersync', { tier: 3, sortOrder: 2 }], - ['neon', { tier: 3, sortOrder: 3 }], - ['strapi', { tier: 3, sortOrder: 4 }], - ['unkey', { tier: 3, sortOrder: 5 }], - ['uidev', { tier: 3, sortOrder: 6 }], -]) - const applicationStarterBrandColorOverrides = new Map([ ['powersync', '#00D5FF'], ['prisma', '#10B981'], @@ -1193,19 +1259,9 @@ function normalizeApplicationStarterPartnerKey(value: string) { } function getApplicationStarterPartnerTier( - partner: Pick, -) { - return ( - applicationStarterPartnerTierOrder.get( - normalizeApplicationStarterPartnerKey(partner.id), - ) ?? - applicationStarterPartnerTierOrder.get( - normalizeApplicationStarterPartnerKey(partner.name), - ) ?? { - tier: 3 as const, - sortOrder: Number.MAX_SAFE_INTEGER, - } - ) + partner: Pick, +): ApplicationStarterPartnerTier { + return partner.tier ? partnerTierToBuilderTier[partner.tier] : 3 } function getApplicationStarterPartnerFaviconUrl(href: string) { @@ -1294,14 +1350,13 @@ export function getInferredApplicationStarterPartnerIdsFromUserInput( const applicationStarterPartnerSuggestions: Array = [...partners] .filter((partner) => partner.status === 'active') - .filter((partner) => partner.id !== 'fireship' && partner.id !== 'nozzle') .map((partner) => { - const tierConfig = getApplicationStarterPartnerTier(partner) + const tier = getApplicationStarterPartnerTier(partner) const normalizedPartnerKey = normalizeApplicationStarterPartnerKey( partner.id, ) const iconMode: ApplicationStarterPartnerSuggestion['iconMode'] = - tierConfig.tier === 2 + tier === 2 ? (partner.applicationStarterIcon?.mode ?? 'contain') : undefined @@ -1312,7 +1367,7 @@ const applicationStarterPartnerSuggestions: Array partner)