MessagingCard
MessagingCard displays promotional or informational content with two variants: 'upsell' for promoting features with a primary background, and 'nudge' for encouraging actions with an alternate background. It replaces the deprecated NudgeCard and UpsellCard components.@coinbase/cds-web@8.38.5
import { MessagingCard } from '@coinbase/cds-web/cards/MessagingCard'
Related components
MessagingCard provides two card types for promotional and informational content. It replaces the deprecated NudgeCard and UpsellCard components.
Basic Types
Use type to set the card variant:
upsell: Primary background, used for promoting features or productsnudge: Alternate background, used for encouraging user actions
Loading...
Live Code<VStack gap={2}> <MessagingCard type="upsell" title="Upsell Card" description="This is an upsell card with primary background" height={100} width={320} media={ <RemoteImage alt="Media" height={100} resizeMode="cover" shape="rectangle" source={coinbaseOneLogo} /> } mediaPlacement="end" /> <MessagingCard type="nudge" title="Nudge Card" description="This is a nudge card with alternate background" width={320} media={<Pictogram dimension="48x48" name="addToWatchlist" />} mediaPlacement="end" /> </VStack>
Media Placement
Use mediaPlacement to control the position of media content.
Loading...
Live Code<VStack gap={2}> <MessagingCard type="upsell" title="Media End" description="Media placed at the end (right)" height={100} width={320} media={ <RemoteImage alt="Media" height={100} resizeMode="cover" shape="rectangle" source={coinbaseOneLogo} /> } mediaPlacement="end" /> <MessagingCard type="upsell" background="accentBoldRed" title="Media Start" description="Media placed at the start (left)" height={100} width={320} media={ <RemoteImage alt="Media" height={100} resizeMode="cover" shape="rectangle" source={svgs[0]} /> } mediaPlacement="start" /> </VStack>
Features
Dismissible Cards
Use onDismiss to add a dismiss button.
Loading...
Live Code<MessagingCard type="upsell" title="Dismissible Card" description="Card with dismiss button" width={320} height={100} media={ <RemoteImage alt="Media" height={100} resizeMode="cover" shape="rectangle" source={coinbaseOneLogo} /> } mediaPlacement="end" onDismiss={() => alert('Card dismissed!')} dismissButtonAccessibilityLabel="Close card" />
Tags
Use tag to add a label badge.
Loading...
Live Code<MessagingCard type="upsell" title="Tagged Card" description="Card with a tag" width={320} height={108} tag="New" media={ <RemoteImage alt="Media" height={108} resizeMode="cover" shape="rectangle" source={coinbaseOneLogo} /> } mediaPlacement="end" />
Actions
Use actions to add action buttons.
Loading...
Live Code<VStack gap={2}> <MessagingCard type="upsell" title="Upsell with Action" description="Upsell card with action button" width={320} height={156} actions={ <Button compact variant="secondary"> Action </Button> } media={ <RemoteImage alt="Media" height={156} resizeMode="cover" shape="rectangle" source={coinbaseOneLogo} /> } mediaPlacement="end" /> <MessagingCard type="nudge" title="Nudge with Action" description="Nudge card with action button" width={320} actions={ <Button compact variant="tertiary"> Learn More </Button> } media={<Pictogram dimension="64x64" name="addToWatchlist" />} mediaPlacement="end" /> </VStack>
Complete Example
Combine all features in a complete card.
Loading...
Live Code<MessagingCard type="upsell" title="Complete Upsell Card" description="Complete upsell card with all features" width={360} height={184} tag="New" actions={ <Button compact variant="secondary"> Get Started </Button> } onDismiss={() => alert('Dismissed')} dismissButtonAccessibilityLabel="Dismiss" media={ <RemoteImage alt="Media" height={184} resizeMode="cover" shape="rectangle" source={coinbaseOneLogo} /> } mediaPlacement="end" />
Polymorphic and Interactive
MessagingCard supports polymorphic rendering with as and can be made interactive with renderAsPressable.
Loading...
Live Code<VStack gap={2}> <MessagingCard as="article" type="upsell" title="Title" description="Description" width={320} height={100} media={ <RemoteImage alt="Media" height={100} resizeMode="cover" shape="rectangle" source={coinbaseOneLogo} /> } mediaPlacement="end" /> <MessagingCard renderAsPressable as="a" href="https://www.coinbase.com" target="_blank" type="upsell" title="Interactive Card" description="Clickable card with href" width={320} height={100} media={ <RemoteImage alt="Media" height={100} resizeMode="cover" shape="rectangle" source={coinbaseOneLogo} /> } mediaPlacement="end" /> <MessagingCard renderAsPressable as="button" onClick={() => alert('Card clicked!')} type="upsell" title="Interactive Card" description="Clickable card with onClick handler" width={320} height={100} media={ <RemoteImage alt="Media" height={100} resizeMode="cover" shape="rectangle" source={coinbaseOneLogo} /> } mediaPlacement="end" /> </VStack>
Custom Content
Use React nodes for custom styled content.
Loading...
Live Code<VStack gap={2}> <MessagingCard type="upsell" title="This is a very long title text that demonstrates text wrapping" description="This is a very long description text that demonstrates how the card handles longer content and wraps appropriately within the card layout" width={320} height={150} media={ <RemoteImage alt="Media" height={150} resizeMode="cover" shape="rectangle" source={coinbaseOneLogo} /> } mediaPlacement="end" /> <MessagingCard type="upsell" width={320} height={130} title={ <Text color="fgInverse" font="title3"> Custom Title </Text> } tag={ <Text color="fgInverse" font="label2"> Custom Tag </Text> } description={ <Text color="fgInverse" font="label2"> Custom description with <strong>bold text</strong> and <em>italic text</em> </Text> } media={ <RemoteImage alt="Media" height={130} resizeMode="cover" shape="rectangle" source={coinbaseOneLogo} /> } mediaPlacement="end" /> </VStack>
Multiple Cards
Display multiple cards in a carousel.
Loading...
Live Code<Carousel styles={{ carousel: { gap: 16 } }}> <CarouselItem id="card1"> <MessagingCard as="article" type="upsell" title="Card 1" description="Non-interactive card" width={320} height={100} media={ <RemoteImage alt="Media" height={100} resizeMode="cover" shape="rectangle" source={coinbaseOneLogo} /> } mediaPlacement="end" /> </CarouselItem> <CarouselItem id="card2"> <MessagingCard renderAsPressable as="a" href="https://www.coinbase.com" target="_blank" type="nudge" title="Card 2" description="Clickable card with href" tag="Link" media={<Pictogram dimension="64x64" name="addToWatchlist" />} mediaPlacement="end" /> </CarouselItem> <CarouselItem id="card3"> <MessagingCard renderAsPressable as="button" onClick={() => console.log('clicked')} type="upsell" title="Card 3" description="Card with onClick handler" tag="Action" height={108} media={ <RemoteImage alt="Media" height={108} resizeMode="cover" shape="rectangle" source={coinbaseOneLogo} /> } mediaPlacement="end" /> </CarouselItem> </Carousel>
Migration from Deprecated Components
Migrating from NudgeCard
Replace NudgeCard with MessagingCard using type="nudge".
// Before
<NudgeCard
title="Title"
description="Description"
pictogram="addToWatchlist"
action="Learn more"
onActionPress={handleAction}
onDismissPress={handleDismiss}
/>
// After
<MessagingCard
type="nudge"
title="Title"
description="Description"
media={<Pictogram dimension="48x48" name="addToWatchlist" />}
actions={<Button compact variant="tertiary" onClick={handleAction}>Learn more</Button>}
onDismiss={handleDismiss}
mediaPlacement="end"
/>
Migrating from UpsellCard
Replace UpsellCard with MessagingCard using type="upsell".
// Before
<UpsellCard
title="Title"
description="Description"
media={<RemoteImage ... />}
action="Get Started"
onActionPress={handleAction}
onDismissPress={handleDismiss}
/>
// After
<MessagingCard
type="upsell"
title="Title"
description="Description"
media={<RemoteImage ... />}
actions={<Button compact variant="secondary" onClick={handleAction}>Get Started</Button>}
onDismiss={handleDismiss}
mediaPlacement="end"
/>