- Accordion
- Avatar
- Badge
- Breadcrumb
- Button
- Calendar
- Checkbox
- Combobox
- Container
- CurrencyInput
- DistributionSlider
- Drawer
- Dropdown
- Grid
- Heading
- Image
- Input
- InputGroup
- Label
- Logo
- MapPin
- Modal
- NativeSelect
- NumberInput
- OtpInput
- PhoneInput
- Popover
- Progress
- PropertyCalendar
- RadioGroup
- RadioGroupCards
- ResponsiveModal
- ScrollArea
- SearchBar
- SearchBarFallback
- SearchInput
- Select
- Separator
- Spinner
- Switch
- Tabs
- Text
- Textarea
- Toast
- Toggle
- ToggleGroup
- Tooltip
Emails
Typed email templates for Wander marketplace and WanderOS, built with React Email
pnpm add @wandercom/design-system-emailsRequires react and react-dom as peer dependencies. The package also installs @react-email/render, @react-email/components, and @react-email/tailwind as dependencies.
The package exports a single composeEmail function that renders any template to HTML and plain text:
import { composeEmail } from '@wandercom/design-system-emails';
const { html, text } = await composeEmail('os.transactional.guest.booking-confirmed', {
propertyName: 'Desert Modern Retreat',
propertyImageUrl: 'https://assets.wander.com/p/listing-hero.jpg',
bookingDates: 'Mar 15 – Mar 20, 2026',
bookingGuests: '2 guests',
bookingUrl: 'https://example.com/bookings/abc123',
unitAddress: '1234 Desert View Dr, Joshua Tree, CA 92252',
mapsUrl: 'https://maps.google.com/?q=...',
checkInInstructions: 'Lockbox code is 1234. Check-in after 4pm.',
companyName: 'Desert Modern Retreat',
unsubscribeUrl: 'https://example.com/unsubscribe',
logoSrc: 'https://wander-ds.vercel.app/assets/wander-logomark.png',
logoDarkSrc: 'https://wander-ds.vercel.app/assets/wander-logomark-dark.png',
});The function is fully generic — TypeScript infers the correct props type from the template name, so you get autocomplete on both template keys and their required props.
Templates use dot-notation keys: {domain}.{category}.{audience}.{template-name}
Guest
| Template | Key |
|---|---|
| Booking cancelled | marketplace.transactional.guest.booking-cancelled |
| Email code | marketplace.transactional.guest.email-code |
| Payment charged | marketplace.transactional.guest.payment-charged |
| Payment failed | marketplace.transactional.guest.payment-failed |
| Pre-reserve confirmed | marketplace.transactional.guest.pre-reserve-confirmed |
| Pre-reserve expired | marketplace.transactional.guest.pre-reserve-expired |
| Pre-reserve launched | marketplace.transactional.guest.pre-reserve-launched |
| Receipt | marketplace.transactional.guest.receipt |
| Trip confirmed | marketplace.transactional.guest.trip-confirmed |
| Upcoming payment | marketplace.transactional.guest.upcoming-payment |
| Upcoming stay | marketplace.transactional.guest.upcoming-stay |
| Verify identity | marketplace.transactional.guest.verify-identity |
Operator
| Template | Key |
|---|---|
| Agreement signed | marketplace.transactional.operator.agreement-signed |
| Booking conflict | marketplace.transactional.operator.booking-conflict |
| Monthly statement | marketplace.transactional.operator.monthly-statement |
| New booking | marketplace.transactional.operator.new-booking |
| New booking offer | marketplace.transactional.operator.new-booking-offer |
| New review | marketplace.transactional.operator.new-review |
| Onboarding invite | marketplace.transactional.operator.onboarding-invite |
| Owner chat message | marketplace.transactional.operator.owner-chat-message |
| Payout sent | marketplace.transactional.operator.payout-sent |
| Post-trip feedback | marketplace.transactional.operator.post-trip-feedback |
| Sign agreement | marketplace.transactional.operator.sign-agreement |
| Upcoming booking | marketplace.transactional.operator.upcoming-booking |
| W-9 approved | marketplace.transactional.operator.w9-approved |
| W-9 received | marketplace.transactional.operator.w9-received |
| Weekly chat report | marketplace.transactional.operator.weekly-chat-report |
Services
| Template | Key |
|---|---|
| New task assigned | marketplace.transactional.services.new-task-assigned |
| Overdue task | marketplace.transactional.services.overdue-task |
| Owner dashboard invite | marketplace.transactional.services.owner-dashboard-invite |
| Vendor portal invite | marketplace.transactional.services.vendor-portal-invite |
| Vendor task completed | marketplace.transactional.services.vendor-task-completed |
Guest
| Template | Key |
|---|---|
| Abandoned cart | os.marketing.guest.abandoned-cart |
| Extend stay | os.marketing.guest.extend-stay |
| Flash rebook | os.marketing.guest.flash-rebook |
| Launch day | os.marketing.guest.launch-day |
| Stay again | os.marketing.guest.stay-again |
| Welcome | os.marketing.guest.welcome |
Guest
| Template | Key |
|---|---|
| Booking cancelled | os.transactional.guest.booking-cancelled |
| Booking confirmed | os.transactional.guest.booking-confirmed |
| Booking updated | os.transactional.guest.booking-updated |
| Check-in day | os.transactional.guest.check-in-day |
| Payment failed | os.transactional.guest.payment-failed |
| Payment method updated | os.transactional.guest.payment-method-updated |
| Payment received | os.transactional.guest.payment-received |
| Pre-trip | os.transactional.guest.pre-trip |
| RTB received | os.transactional.guest.rtb-received |
| RTB rejected | os.transactional.guest.rtb-rejected |
| Upcoming payment | os.transactional.guest.upcoming-payment |
| Verify email | os.transactional.guest.verify-email |
Operator
| Template | Key |
|---|---|
| Booking review | os.transactional.operator.booking-review |
| Confirm domain removal | os.transactional.operator.confirm-domain-removal |
| Confirm listing deletion | os.transactional.operator.confirm-listing-deletion |
| Contact us form | os.transactional.operator.contact-us-form |
| Custom domain active | os.transactional.operator.custom-domain-active |
| Custom domain expiring | os.transactional.operator.custom-domain-expiring |
| Custom domain removed | os.transactional.operator.custom-domain-removed |
| Email code | os.transactional.operator.email-code |
| Form submission | os.transactional.operator.form |
| List with us form | os.transactional.operator.list-with-us-form |
| New booking | os.transactional.operator.new-booking |
| Org invite | os.transactional.operator.org-invite |
| PMS sync complete | os.transactional.operator.pms-sync-complete |
| RTB received | os.transactional.operator.rtb-received |
| Website audit | os.transactional.operator.website-audit |
| Website live | os.transactional.operator.website-live |
The generic template is a flexible template for ad-hoc emails that don't need a dedicated template:
const { html, text } = await composeEmail('generic', {
heading: 'Your settings have been updated',
body: [
'We wanted to let you know that your account settings have been updated successfully.',
'If you did not make this change, please contact our support team immediately.',
],
buttonText: 'View settings',
buttonHref: 'https://wander.com/settings',
footer: 'wander',
logoSrc: 'https://wander-ds.vercel.app/assets/wander-logomark.png',
logoDarkSrc: 'https://wander-ds.vercel.app/assets/wander-logomark-dark.png',
});The body prop accepts a single string or an array of strings (each rendered as a separate paragraph). The button only renders when both buttonText and buttonHref are provided.
The composeEmail function returns { html, text } — the rendered HTML and plain text versions. Pass these to any email provider:
import { composeEmail } from '@wandercom/design-system-emails';
const { html, text } = await composeEmail('os.transactional.guest.booking-confirmed', {
// ... template props
});
await emailProvider.send({
from: 'Wander <notifications@wander.com>',
to: guest.email,
subject: 'Booking confirmed',
html,
text,
});To preview emails during development, run from the emails package:
cd packages/emails
pnpm devThis starts the React Email dev server where you can browse and preview all templates with their default prop values.
The package exports these types for use in consuming applications:
import type {
EmailTemplateName,
EmailTemplateMap,
ComposeResult,
} from '@wandercom/design-system-emails';EmailTemplateName— union of all template key stringsEmailTemplateMap— maps each template key to its required propsComposeResult—{ html: string; text: string }
- Shared utilities — Shared package utilities
- Design tokens — Token-based styling used in email components