@better-auth-ui/react 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (250) hide show
  1. package/dist/components/auth/auth-provider.d.ts +32 -0
  2. package/dist/components/auth/auth-provider.js +44 -0
  3. package/dist/components/email/email-changed.d.ts +97 -0
  4. package/dist/components/email/email-changed.js +70 -0
  5. package/dist/components/email/email-localization.d.ts +61 -0
  6. package/dist/components/email/email-localization.js +24 -0
  7. package/dist/components/email/email-styles.d.ts +89 -0
  8. package/dist/components/email/email-styles.js +129 -0
  9. package/dist/components/email/email-verification.d.ts +97 -0
  10. package/dist/components/email/email-verification.js +75 -0
  11. package/dist/components/email/index.d.ts +9 -0
  12. package/dist/components/email/index.js +9 -0
  13. package/dist/components/email/magic-link.d.ts +93 -0
  14. package/dist/components/email/magic-link.js +72 -0
  15. package/dist/components/email/new-device.d.ts +123 -0
  16. package/dist/components/email/new-device.js +90 -0
  17. package/dist/components/email/otp-email.d.ts +88 -0
  18. package/dist/components/email/otp-email.js +65 -0
  19. package/dist/components/email/password-changed.d.ts +96 -0
  20. package/dist/components/email/password-changed.js +76 -0
  21. package/dist/components/email/reset-password.d.ts +90 -0
  22. package/dist/components/email/reset-password.js +68 -0
  23. package/dist/components/icons/apple.d.ts +8 -0
  24. package/dist/components/icons/apple.js +10 -0
  25. package/dist/components/icons/atlassian.d.ts +10 -0
  26. package/dist/components/icons/atlassian.js +14 -0
  27. package/dist/components/icons/cognito.d.ts +8 -0
  28. package/dist/components/icons/cognito.js +10 -0
  29. package/dist/components/icons/discord.d.ts +8 -0
  30. package/dist/components/icons/discord.js +10 -0
  31. package/dist/components/icons/dropbox.d.ts +8 -0
  32. package/dist/components/icons/dropbox.js +10 -0
  33. package/dist/components/icons/facebook.d.ts +10 -0
  34. package/dist/components/icons/facebook.js +12 -0
  35. package/dist/components/icons/figma.d.ts +11 -0
  36. package/dist/components/icons/figma.js +13 -0
  37. package/dist/components/icons/github.d.ts +10 -0
  38. package/dist/components/icons/github.js +12 -0
  39. package/dist/components/icons/gitlab.d.ts +8 -0
  40. package/dist/components/icons/gitlab.js +10 -0
  41. package/dist/components/icons/google.d.ts +8 -0
  42. package/dist/components/icons/google.js +10 -0
  43. package/dist/components/icons/huggingface.d.ts +8 -0
  44. package/dist/components/icons/huggingface.js +10 -0
  45. package/dist/components/icons/index.d.ts +35 -0
  46. package/dist/components/icons/index.js +35 -0
  47. package/dist/components/icons/kakao.d.ts +10 -0
  48. package/dist/components/icons/kakao.js +12 -0
  49. package/dist/components/icons/kick.d.ts +10 -0
  50. package/dist/components/icons/kick.js +12 -0
  51. package/dist/components/icons/line.d.ts +8 -0
  52. package/dist/components/icons/line.js +10 -0
  53. package/dist/components/icons/linear.d.ts +8 -0
  54. package/dist/components/icons/linear.js +10 -0
  55. package/dist/components/icons/linkedin.d.ts +8 -0
  56. package/dist/components/icons/linkedin.js +10 -0
  57. package/dist/components/icons/microsoft.d.ts +8 -0
  58. package/dist/components/icons/microsoft.js +10 -0
  59. package/dist/components/icons/naver.d.ts +8 -0
  60. package/dist/components/icons/naver.js +10 -0
  61. package/dist/components/icons/notion.d.ts +8 -0
  62. package/dist/components/icons/notion.js +10 -0
  63. package/dist/components/icons/paybin.d.ts +7 -0
  64. package/dist/components/icons/paybin.js +9 -0
  65. package/dist/components/icons/paypal.d.ts +8 -0
  66. package/dist/components/icons/paypal.js +10 -0
  67. package/dist/components/icons/polar.d.ts +8 -0
  68. package/dist/components/icons/polar.js +10 -0
  69. package/dist/components/icons/railway.d.ts +8 -0
  70. package/dist/components/icons/railway.js +10 -0
  71. package/dist/components/icons/reddit.d.ts +8 -0
  72. package/dist/components/icons/reddit.js +10 -0
  73. package/dist/components/icons/roblox.d.ts +11 -0
  74. package/dist/components/icons/roblox.js +13 -0
  75. package/dist/components/icons/salesforce.d.ts +8 -0
  76. package/dist/components/icons/salesforce.js +10 -0
  77. package/dist/components/icons/slack.d.ts +8 -0
  78. package/dist/components/icons/slack.js +10 -0
  79. package/dist/components/icons/spotify.d.ts +8 -0
  80. package/dist/components/icons/spotify.js +10 -0
  81. package/dist/components/icons/tiktok.d.ts +9 -0
  82. package/dist/components/icons/tiktok.js +11 -0
  83. package/dist/components/icons/twitch.d.ts +8 -0
  84. package/dist/components/icons/twitch.js +13 -0
  85. package/dist/components/icons/vercel.d.ts +8 -0
  86. package/dist/components/icons/vercel.js +10 -0
  87. package/dist/components/icons/vk.d.ts +8 -0
  88. package/dist/components/icons/vk.js +10 -0
  89. package/dist/components/icons/wechat.d.ts +8 -0
  90. package/dist/components/icons/wechat.js +10 -0
  91. package/dist/components/icons/x.d.ts +8 -0
  92. package/dist/components/icons/x.js +10 -0
  93. package/dist/components/icons/zoom.d.ts +8 -0
  94. package/dist/components/icons/zoom.js +12 -0
  95. package/dist/components/settings/account/theme-preview.d.ts +3 -0
  96. package/dist/components/settings/account/theme-preview.js +10 -0
  97. package/dist/core.d.ts +1 -0
  98. package/dist/core.js +1 -0
  99. package/dist/hooks/auth/use-auth-mutation.d.ts +18 -0
  100. package/dist/hooks/auth/use-auth-mutation.js +10 -0
  101. package/dist/hooks/auth/use-auth-query.d.ts +24 -0
  102. package/dist/hooks/auth/use-auth-query.js +10 -0
  103. package/dist/hooks/auth/use-authenticate.d.ts +9 -0
  104. package/dist/hooks/auth/use-authenticate.js +28 -0
  105. package/dist/hooks/auth/use-forgot-password.d.ts +20 -0
  106. package/dist/hooks/auth/use-forgot-password.js +14 -0
  107. package/dist/hooks/auth/use-request-password-reset.d.ts +26 -0
  108. package/dist/hooks/auth/use-request-password-reset.js +14 -0
  109. package/dist/hooks/auth/use-reset-password.d.ts +40 -0
  110. package/dist/hooks/auth/use-reset-password.js +13 -0
  111. package/dist/hooks/auth/use-send-verification-email.d.ts +24 -0
  112. package/dist/hooks/auth/use-send-verification-email.js +13 -0
  113. package/dist/hooks/auth/use-session.d.ts +9 -0
  114. package/dist/hooks/auth/use-session.js +18 -0
  115. package/dist/hooks/auth/use-sign-in-email.d.ts +53 -0
  116. package/dist/hooks/auth/use-sign-in-email.js +24 -0
  117. package/dist/hooks/auth/use-sign-in-magic-link.d.ts +32 -0
  118. package/dist/hooks/auth/use-sign-in-magic-link.js +13 -0
  119. package/dist/hooks/auth/use-sign-in-social.d.ts +93 -0
  120. package/dist/hooks/auth/use-sign-in-social.js +13 -0
  121. package/dist/hooks/auth/use-sign-out.d.ts +19 -0
  122. package/dist/hooks/auth/use-sign-out.js +24 -0
  123. package/dist/hooks/auth/use-sign-up-email.d.ts +526 -0
  124. package/dist/hooks/auth/use-sign-up-email.js +24 -0
  125. package/dist/hooks/auth/use-user.d.ts +513 -0
  126. package/dist/hooks/auth/use-user.js +14 -0
  127. package/dist/hooks/settings/use-account-info.d.ts +17 -0
  128. package/dist/hooks/settings/use-account-info.js +25 -0
  129. package/dist/hooks/settings/use-change-email.d.ts +24 -0
  130. package/dist/hooks/settings/use-change-email.js +23 -0
  131. package/dist/hooks/settings/use-change-password.d.ts +54 -0
  132. package/dist/hooks/settings/use-change-password.js +11 -0
  133. package/dist/hooks/settings/use-delete-user.d.ts +42 -0
  134. package/dist/hooks/settings/use-delete-user.js +11 -0
  135. package/dist/hooks/settings/use-link-social.d.ts +46 -0
  136. package/dist/hooks/settings/use-link-social.js +10 -0
  137. package/dist/hooks/settings/use-list-accounts.d.ts +20 -0
  138. package/dist/hooks/settings/use-list-accounts.js +23 -0
  139. package/dist/hooks/settings/use-list-device-sessions.d.ts +11 -0
  140. package/dist/hooks/settings/use-list-device-sessions.js +22 -0
  141. package/dist/hooks/settings/use-list-sessions.d.ts +20 -0
  142. package/dist/hooks/settings/use-list-sessions.js +22 -0
  143. package/dist/hooks/settings/use-revoke-multi-session.d.ts +19 -0
  144. package/dist/hooks/settings/use-revoke-multi-session.js +20 -0
  145. package/dist/hooks/settings/use-revoke-session.d.ts +19 -0
  146. package/dist/hooks/settings/use-revoke-session.js +21 -0
  147. package/dist/hooks/settings/use-set-active-session.d.ts +37 -0
  148. package/dist/hooks/settings/use-set-active-session.js +28 -0
  149. package/dist/hooks/settings/use-unlink-account.d.ts +21 -0
  150. package/dist/hooks/settings/use-unlink-account.js +21 -0
  151. package/dist/hooks/settings/use-update-user.d.ts +11 -0
  152. package/dist/hooks/settings/use-update-user.js +29 -0
  153. package/dist/hooks/use-hydrated.d.ts +6 -0
  154. package/dist/hooks/use-hydrated.js +18 -0
  155. package/dist/index.d.ts +32 -0
  156. package/dist/index.js +33 -0
  157. package/dist/lib/auth-client.d.ts +1979 -0
  158. package/dist/lib/auth-client.js +5 -0
  159. package/dist/lib/auth-config.d.ts +43 -0
  160. package/dist/lib/auth-config.js +1 -0
  161. package/dist/lib/auth-context.d.ts +2 -0
  162. package/dist/lib/auth-context.js +3 -0
  163. package/dist/lib/auth-hook-options.d.ts +8 -0
  164. package/dist/lib/auth-hook-options.js +1 -0
  165. package/dist/lib/provider-icons.d.ts +13 -0
  166. package/dist/lib/provider-icons.js +48 -0
  167. package/dist/lib/utils.d.ts +2 -0
  168. package/dist/lib/utils.js +5 -0
  169. package/package.json +64 -0
  170. package/src/components/auth/auth-provider.tsx +82 -0
  171. package/src/components/email/email-changed.tsx +381 -0
  172. package/src/components/email/email-localization.tsx +33 -0
  173. package/src/components/email/email-styles.tsx +175 -0
  174. package/src/components/email/email-verification.tsx +350 -0
  175. package/src/components/email/index.ts +9 -0
  176. package/src/components/email/magic-link.tsx +349 -0
  177. package/src/components/email/new-device.tsx +452 -0
  178. package/src/components/email/otp-email.tsx +321 -0
  179. package/src/components/email/password-changed.tsx +380 -0
  180. package/src/components/email/reset-password.tsx +343 -0
  181. package/src/components/icons/apple.tsx +24 -0
  182. package/src/components/icons/atlassian.tsx +43 -0
  183. package/src/components/icons/cognito.tsx +25 -0
  184. package/src/components/icons/discord.tsx +24 -0
  185. package/src/components/icons/dropbox.tsx +24 -0
  186. package/src/components/icons/facebook.tsx +30 -0
  187. package/src/components/icons/figma.tsx +43 -0
  188. package/src/components/icons/github.tsx +26 -0
  189. package/src/components/icons/gitlab.tsx +36 -0
  190. package/src/components/icons/google.tsx +42 -0
  191. package/src/components/icons/huggingface.tsx +44 -0
  192. package/src/components/icons/index.ts +35 -0
  193. package/src/components/icons/kakao.tsx +26 -0
  194. package/src/components/icons/kick.tsx +30 -0
  195. package/src/components/icons/line.tsx +24 -0
  196. package/src/components/icons/linear.tsx +24 -0
  197. package/src/components/icons/linkedin.tsx +28 -0
  198. package/src/components/icons/microsoft.tsx +24 -0
  199. package/src/components/icons/naver.tsx +24 -0
  200. package/src/components/icons/notion.tsx +25 -0
  201. package/src/components/icons/paybin.tsx +37 -0
  202. package/src/components/icons/paypal.tsx +36 -0
  203. package/src/components/icons/polar.tsx +31 -0
  204. package/src/components/icons/railway.tsx +24 -0
  205. package/src/components/icons/reddit.tsx +25 -0
  206. package/src/components/icons/roblox.tsx +28 -0
  207. package/src/components/icons/salesforce.tsx +24 -0
  208. package/src/components/icons/slack.tsx +36 -0
  209. package/src/components/icons/spotify.tsx +24 -0
  210. package/src/components/icons/tiktok.tsx +32 -0
  211. package/src/components/icons/twitch.tsx +50 -0
  212. package/src/components/icons/vercel.tsx +21 -0
  213. package/src/components/icons/vk.tsx +24 -0
  214. package/src/components/icons/wechat.tsx +24 -0
  215. package/src/components/icons/x.tsx +24 -0
  216. package/src/components/icons/zoom.tsx +48 -0
  217. package/src/components/settings/account/theme-preview.tsx +271 -0
  218. package/src/core.ts +1 -0
  219. package/src/hooks/auth/use-auth-mutation.ts +56 -0
  220. package/src/hooks/auth/use-auth-query.ts +50 -0
  221. package/src/hooks/auth/use-authenticate.ts +35 -0
  222. package/src/hooks/auth/use-request-password-reset.ts +24 -0
  223. package/src/hooks/auth/use-reset-password.ts +23 -0
  224. package/src/hooks/auth/use-send-verification-email.ts +23 -0
  225. package/src/hooks/auth/use-session.ts +26 -0
  226. package/src/hooks/auth/use-sign-in-email.ts +35 -0
  227. package/src/hooks/auth/use-sign-in-magic-link.ts +23 -0
  228. package/src/hooks/auth/use-sign-in-social.ts +23 -0
  229. package/src/hooks/auth/use-sign-out.ts +34 -0
  230. package/src/hooks/auth/use-sign-up-email.ts +35 -0
  231. package/src/hooks/auth/use-user.ts +21 -0
  232. package/src/hooks/settings/use-account-info.ts +30 -0
  233. package/src/hooks/settings/use-change-email.ts +33 -0
  234. package/src/hooks/settings/use-change-password.ts +21 -0
  235. package/src/hooks/settings/use-delete-user.ts +21 -0
  236. package/src/hooks/settings/use-link-social.ts +19 -0
  237. package/src/hooks/settings/use-list-accounts.ts +27 -0
  238. package/src/hooks/settings/use-list-device-sessions.ts +32 -0
  239. package/src/hooks/settings/use-list-sessions.ts +26 -0
  240. package/src/hooks/settings/use-revoke-multi-session.ts +30 -0
  241. package/src/hooks/settings/use-revoke-session.ts +31 -0
  242. package/src/hooks/settings/use-set-active-session.ts +46 -0
  243. package/src/hooks/settings/use-unlink-account.ts +31 -0
  244. package/src/hooks/settings/use-update-user.ts +44 -0
  245. package/src/index.ts +34 -0
  246. package/src/lib/auth-client.ts +37 -0
  247. package/src/lib/auth-config.ts +48 -0
  248. package/src/lib/auth-context.ts +6 -0
  249. package/src/lib/provider-icons.ts +90 -0
  250. package/src/lib/utils.ts +6 -0
@@ -0,0 +1,33 @@
1
+ import EmailChangedEmail from "./email-changed"
2
+ import EmailVerificationEmail from "./email-verification"
3
+ import MagicLinkEmail from "./magic-link"
4
+ import NewDeviceEmail from "./new-device"
5
+ import OtpEmail from "./otp-email"
6
+ import PasswordChangedEmail from "./password-changed"
7
+ import ResetPasswordEmail from "./reset-password"
8
+
9
+ /**
10
+ * Aggregated localization strings for all email components.
11
+ *
12
+ * Combines localization strings from all email templates (EmailChangedEmail,
13
+ * EmailVerificationEmail, MagicLinkEmail, NewDeviceEmail, OtpEmail,
14
+ * PasswordChangedEmail, ResetPasswordEmail) into a single object for convenient
15
+ * bulk customization.
16
+ */
17
+ export const emailLocalization = {
18
+ ...EmailChangedEmail.localization,
19
+ ...EmailVerificationEmail.localization,
20
+ ...MagicLinkEmail.localization,
21
+ ...NewDeviceEmail.localization,
22
+ ...OtpEmail.localization,
23
+ ...PasswordChangedEmail.localization,
24
+ ...ResetPasswordEmail.localization
25
+ }
26
+
27
+ /**
28
+ * Type representing all available email localization strings.
29
+ *
30
+ * Derived from the emailLocalization constant, this type can be used for
31
+ * type-safe localization overrides across all email templates.
32
+ */
33
+ export type EmailLocalization = typeof emailLocalization
@@ -0,0 +1,175 @@
1
+ /**
2
+ * Default color scheme for email templates in light and dark modes.
3
+ *
4
+ * Provides a consistent color palette that can be customized via the EmailColors type.
5
+ */
6
+ export const defaultColors = {
7
+ light: {
8
+ background: "#F5F5F5",
9
+ border: "#E5E5E5",
10
+ card: "#FFFFFF",
11
+ cardForeground: "#0A0A0A",
12
+ foreground: "#262626",
13
+ muted: "#F5F5F5",
14
+ mutedForeground: "#737373",
15
+ primary: "#171717",
16
+ primaryForeground: "#FAFAFA"
17
+ },
18
+ dark: {
19
+ background: "#0A0A0A",
20
+ border: "#2E2E2E",
21
+ card: "#171717",
22
+ cardForeground: "#FAFAFA",
23
+ foreground: "#D4D4D4",
24
+ muted: "#212121",
25
+ mutedForeground: "#A1A1A1",
26
+ primary: "#E5E5E5",
27
+ primaryForeground: "#171717"
28
+ }
29
+ }
30
+
31
+ /**
32
+ * Custom CSS class names for styling different parts of email templates.
33
+ *
34
+ * Allows fine-grained control over the appearance of email components.
35
+ */
36
+ export type EmailClassNames = {
37
+ body?: string
38
+ container?: string
39
+ card?: string
40
+ logo?: string
41
+ title?: string
42
+ content?: string
43
+ button?: string
44
+ description?: string
45
+ separator?: string
46
+ link?: string
47
+ poweredBy?: string
48
+ codeBlock?: string
49
+ }
50
+
51
+ /**
52
+ * Custom color scheme configuration for email templates.
53
+ *
54
+ * Supports separate color definitions for light and dark modes.
55
+ * Any color not specified will fall back to the defaultColors values.
56
+ */
57
+ export type EmailColors = {
58
+ light?: Partial<typeof defaultColors.light>
59
+ dark?: Partial<typeof defaultColors.dark>
60
+ }
61
+
62
+ /**
63
+ * Props for the EmailStyles component.
64
+ */
65
+ interface EmailStylesProps {
66
+ /** Custom color scheme for light and dark modes */
67
+ colors?: EmailColors
68
+ /** Whether to enable dark mode support */
69
+ darkMode?: boolean
70
+ }
71
+
72
+ /**
73
+ * Component that injects CSS styles for email templates with support for light and dark modes.
74
+ *
75
+ * Generates inline styles that adapt to the user's color scheme preference and applies
76
+ * custom colors if provided. Handles logo visibility switching between light and dark modes.
77
+ *
78
+ * @param props - Style configuration options
79
+ * @returns A style element containing CSS for email template theming
80
+ *
81
+ * @example
82
+ * ```tsx
83
+ * <EmailStyles
84
+ * colors={{
85
+ * light: { primary: "#000000" },
86
+ * dark: { primary: "#FFFFFF" }
87
+ * }}
88
+ * darkMode={true}
89
+ * />
90
+ * ```
91
+ */
92
+ export const EmailStyles = ({ colors, darkMode = true }: EmailStylesProps) => {
93
+ return (
94
+ <style type="text/css">{`
95
+ .bg-background {
96
+ background-color: ${colors?.light?.background || defaultColors.light.background} !important;
97
+ }
98
+ .bg-card {
99
+ background-color: ${colors?.light?.card || defaultColors.light.card} !important;
100
+ }
101
+ .bg-primary {
102
+ background-color: ${colors?.light?.primary || defaultColors.light.primary} !important;
103
+ }
104
+ .bg-muted {
105
+ background-color: ${colors?.light?.muted || defaultColors.light.muted} !important;
106
+ }
107
+ .border-border {
108
+ border-color: ${colors?.light?.border || defaultColors.light.border} !important;
109
+ }
110
+ .text-card-foreground {
111
+ color: ${colors?.light?.cardForeground || defaultColors.light.cardForeground} !important;
112
+ }
113
+ .text-muted-foreground {
114
+ color: ${colors?.light?.mutedForeground || defaultColors.light.mutedForeground} !important;
115
+ }
116
+ .text-primary {
117
+ color: ${colors?.light?.primary || defaultColors.light.primary} !important;
118
+ }
119
+ .text-primary-foreground {
120
+ color: ${colors?.light?.primaryForeground || defaultColors.light.primaryForeground} !important;
121
+ }
122
+ .logo-dark {
123
+ display: none !important;
124
+ }
125
+ .logo-light {
126
+ display: block !important;
127
+ }
128
+
129
+ ${
130
+ darkMode
131
+ ? `@media (prefers-color-scheme: dark) {
132
+ .bg-background {
133
+ background-color: ${colors?.dark?.background || defaultColors.dark.background} !important;
134
+ }
135
+ .bg-card {
136
+ background-color: ${colors?.dark?.card || defaultColors.dark.card} !important;
137
+ }
138
+ .bg-primary {
139
+ background-color: ${colors?.dark?.primary || defaultColors.dark.primary} !important;
140
+ }
141
+ .bg-muted {
142
+ background-color: ${colors?.dark?.muted || defaultColors.dark.muted} !important;
143
+ }
144
+ .border-border {
145
+ border-color: ${colors?.dark?.border || defaultColors.dark.border} !important;
146
+ }
147
+ .text-card-foreground {
148
+ color: ${colors?.dark?.cardForeground || defaultColors.dark.cardForeground} !important;
149
+ }
150
+ .text-muted-foreground {
151
+ color: ${colors?.dark?.mutedForeground || defaultColors.dark.mutedForeground} !important;
152
+ }
153
+ .text-primary {
154
+ color: ${colors?.dark?.primary || defaultColors.dark.primary} !important;
155
+ }
156
+ .text-primary-foreground {
157
+ color: ${colors?.dark?.primaryForeground || defaultColors.dark.primaryForeground} !important;
158
+ }
159
+ .logo-dark {
160
+ display: block !important;
161
+ }
162
+ .logo-light {
163
+ display: none !important;
164
+ }
165
+ * {
166
+ box-shadow: none !important;
167
+ }
168
+ }`
169
+ : ""
170
+ }
171
+ `}</style>
172
+ )
173
+ }
174
+
175
+ export default EmailStyles
@@ -0,0 +1,350 @@
1
+ import {
2
+ Body,
3
+ Button,
4
+ Container,
5
+ Head,
6
+ Heading,
7
+ Hr,
8
+ Html,
9
+ Img,
10
+ Link,
11
+ Preview,
12
+ pixelBasedPreset,
13
+ Section,
14
+ Tailwind,
15
+ Text
16
+ } from "@react-email/components"
17
+ import type { ReactNode } from "react"
18
+
19
+ import { cn } from "../../lib/utils"
20
+ import {
21
+ type EmailClassNames,
22
+ type EmailColors,
23
+ EmailStyles
24
+ } from "./email-styles"
25
+
26
+ const emailVerificationEmailLocalization = {
27
+ VERIFY_YOUR_EMAIL_ADDRESS: "Verify your email address",
28
+ LOGO: "Logo",
29
+ CLICK_BUTTON_TO_VERIFY_EMAIL:
30
+ "Click the button below to verify your email address {emailAddress} for your {appName} account.",
31
+ VERIFY_EMAIL_ADDRESS: "Verify email address",
32
+ OR_COPY_AND_PASTE_URL: "Or copy and paste this URL into your browser:",
33
+ THIS_LINK_EXPIRES_IN_MINUTES:
34
+ "This link expires in {expirationMinutes} minutes.",
35
+ EMAIL_SENT_BY: "Email sent by {appName}.",
36
+ IF_YOU_DIDNT_REQUEST_THIS_EMAIL:
37
+ "If you didn't request this email, you can safely ignore it. Someone else might have typed your email address by mistake.",
38
+ POWERED_BY_BETTER_AUTH: "Powered by {betterAuth}"
39
+ }
40
+
41
+ /**
42
+ * Localization strings for the EmailVerificationEmail component.
43
+ *
44
+ * Contains all text content used in the email verification email template.
45
+ */
46
+ export type EmailVerificationEmailLocalization =
47
+ typeof emailVerificationEmailLocalization
48
+
49
+ /**
50
+ * Props for the EmailVerificationEmail component.
51
+ */
52
+ export interface EmailVerificationEmailProps {
53
+ /** Verification URL that users must click to verify their email */
54
+ url: string
55
+ /** Email address being verified */
56
+ email?: string
57
+ /** Name of the application sending the email */
58
+ appName?: string
59
+ /** Number of minutes until the verification link expires */
60
+ expirationMinutes?: number
61
+ /** Logo URL(s) - a single string or light/dark variants. If omitted, no logo is shown. */
62
+ logoURL?: string | { light: string; dark: string }
63
+ /** Custom CSS class names for styling specific parts of the email */
64
+ classNames?: EmailClassNames
65
+ /** Custom color scheme for light and dark modes */
66
+ colors?: EmailColors
67
+ /** Whether to show the "Powered by better-auth" footer */
68
+ poweredBy?: boolean
69
+ /** Whether to enable dark mode support */
70
+ darkMode?: boolean
71
+ /** Additional React nodes to inject into the email head */
72
+ head?: ReactNode
73
+ /**
74
+ * Localization overrides for customizing email text
75
+ * @remarks `EmailVerificationEmailLocalization`
76
+ */
77
+ localization?: Partial<EmailVerificationEmailLocalization>
78
+ }
79
+
80
+ /**
81
+ * Email template component that sends email verification links to users.
82
+ *
83
+ * This email includes:
84
+ * - Verification button and fallback URL
85
+ * - Expiration time information
86
+ * - Security notice for unauthorized requests
87
+ * - Customizable branding and styling
88
+ * - Support for light/dark mode themes
89
+ *
90
+ * @example
91
+ * ```tsx
92
+ * <EmailVerificationEmail
93
+ * url="https://example.com/verify?token=abc123"
94
+ * email="user@example.com"
95
+ * appName="My App"
96
+ * expirationMinutes={60}
97
+ * logoURL="https://example.com/logo.png"
98
+ * darkMode={true}
99
+ * />
100
+ * ```
101
+ */
102
+ export const EmailVerificationEmail = ({
103
+ url,
104
+ email,
105
+ appName,
106
+ expirationMinutes = 60,
107
+ logoURL,
108
+ colors,
109
+ classNames,
110
+ darkMode = true,
111
+ poweredBy,
112
+ head,
113
+ ...props
114
+ }: EmailVerificationEmailProps) => {
115
+ const localization = {
116
+ ...EmailVerificationEmail.localization,
117
+ ...props.localization
118
+ }
119
+
120
+ const previewText = localization.VERIFY_YOUR_EMAIL_ADDRESS
121
+
122
+ return (
123
+ <Html>
124
+ <Head>
125
+ <meta content="light dark" name="color-scheme" />
126
+ <meta content="light dark" name="supported-color-schemes" />
127
+
128
+ <EmailStyles colors={colors} darkMode={darkMode} />
129
+
130
+ {head}
131
+ </Head>
132
+
133
+ <Preview>{previewText}</Preview>
134
+
135
+ <Tailwind config={{ presets: [pixelBasedPreset] }}>
136
+ <Body className={cn("bg-background font-sans", classNames?.body)}>
137
+ <Container
138
+ className={cn(
139
+ "mx-auto my-auto max-w-xl px-2 py-10",
140
+ classNames?.container
141
+ )}
142
+ >
143
+ <Section
144
+ className={cn(
145
+ "bg-card text-card-foreground rounded-none border border-border p-8",
146
+ classNames?.card
147
+ )}
148
+ >
149
+ {logoURL &&
150
+ (typeof logoURL === "string" ? (
151
+ <Img
152
+ src={logoURL}
153
+ width={48}
154
+ height={48}
155
+ alt={appName || localization.LOGO}
156
+ className={cn("mx-auto mb-8", classNames?.logo)}
157
+ />
158
+ ) : (
159
+ <>
160
+ <Img
161
+ src={logoURL.light}
162
+ width={48}
163
+ height={48}
164
+ alt={appName || localization.LOGO}
165
+ className={cn(
166
+ "mx-auto mb-8 logo-light",
167
+ classNames?.logo
168
+ )}
169
+ />
170
+ <Img
171
+ src={logoURL.dark}
172
+ width={48}
173
+ height={48}
174
+ alt={appName || localization.LOGO}
175
+ className={cn(
176
+ "hidden mx-auto mb-8 logo-dark",
177
+ classNames?.logo
178
+ )}
179
+ />
180
+ </>
181
+ ))}
182
+
183
+ <Heading
184
+ className={cn(
185
+ "m-0 mb-5 text-2xl font-semibold",
186
+ classNames?.title
187
+ )}
188
+ >
189
+ {localization.VERIFY_EMAIL_ADDRESS}
190
+ </Heading>
191
+
192
+ <Text className={cn("text-sm font-normal", classNames?.content)}>
193
+ {(() => {
194
+ const textWithAppName =
195
+ localization.CLICK_BUTTON_TO_VERIFY_EMAIL.replace(
196
+ "{appName}",
197
+ appName || ""
198
+ )
199
+ .replace(/\s{2,}/g, " ")
200
+ .replace(" .", ".")
201
+
202
+ const [beforeEmailAddress, afterEmailAddress] =
203
+ textWithAppName.split("{emailAddress}")
204
+
205
+ return email ? (
206
+ <>
207
+ {beforeEmailAddress}
208
+
209
+ <Link
210
+ href={`mailto:${email}`}
211
+ className="text-primary font-medium"
212
+ >
213
+ {email}
214
+ </Link>
215
+
216
+ {afterEmailAddress}
217
+ </>
218
+ ) : (
219
+ textWithAppName
220
+ .replace("{emailAddress}", "")
221
+ .replace(/\s{2,}/g, " ")
222
+ .replace(" .", ".")
223
+ )
224
+ })()}
225
+ </Text>
226
+
227
+ <Section className="my-6">
228
+ <Button
229
+ href={url}
230
+ className={cn(
231
+ "inline-block whitespace-nowrap rounded-none text-sm font-medium py-2.5 px-6 bg-primary text-primary-foreground no-underline",
232
+ classNames?.button
233
+ )}
234
+ >
235
+ {localization.VERIFY_EMAIL_ADDRESS}
236
+ </Button>
237
+ </Section>
238
+
239
+ <Text
240
+ className={cn(
241
+ "mb-3 text-xs text-muted-foreground",
242
+ classNames?.description
243
+ )}
244
+ >
245
+ {localization.OR_COPY_AND_PASTE_URL}
246
+ </Text>
247
+
248
+ <Link
249
+ className={cn(
250
+ "break-all text-xs text-primary",
251
+ classNames?.link
252
+ )}
253
+ href={url}
254
+ >
255
+ {url}
256
+ </Link>
257
+
258
+ <Hr
259
+ className={cn(
260
+ "my-6 w-full border border-solid border-border",
261
+ classNames?.separator
262
+ )}
263
+ />
264
+
265
+ {expirationMinutes || appName ? (
266
+ <Text
267
+ className={cn(
268
+ "mb-3 text-xs text-muted-foreground",
269
+ classNames?.description
270
+ )}
271
+ >
272
+ {expirationMinutes
273
+ ? localization.THIS_LINK_EXPIRES_IN_MINUTES.replace(
274
+ "{expirationMinutes}",
275
+ expirationMinutes.toString()
276
+ )
277
+ : null}
278
+
279
+ {appName && (
280
+ <>
281
+ {expirationMinutes ? " " : ""}
282
+ {localization.EMAIL_SENT_BY.replace("{appName}", appName)}
283
+ </>
284
+ )}
285
+ </Text>
286
+ ) : null}
287
+
288
+ <Text
289
+ className={cn(
290
+ "mt-3 text-xs text-muted-foreground",
291
+ classNames?.description
292
+ )}
293
+ >
294
+ {localization.IF_YOU_DIDNT_REQUEST_THIS_EMAIL}
295
+ </Text>
296
+
297
+ {poweredBy && (
298
+ <Text
299
+ className={cn(
300
+ "mt-4 mb-0 text-center text-[11px] text-muted-foreground",
301
+ classNames?.poweredBy
302
+ )}
303
+ >
304
+ {(() => {
305
+ const [beforeBetterAuth, afterBetterAuth] =
306
+ localization.POWERED_BY_BETTER_AUTH.split("{betterAuth}")
307
+
308
+ return (
309
+ <>
310
+ {beforeBetterAuth}
311
+ <Link
312
+ href="https://better-auth.com"
313
+ className={cn(
314
+ "text-primary underline",
315
+ classNames?.link
316
+ )}
317
+ >
318
+ better-auth
319
+ </Link>
320
+ {afterBetterAuth}
321
+ </>
322
+ )
323
+ })()}
324
+ </Text>
325
+ )}
326
+ </Section>
327
+ </Container>
328
+ </Body>
329
+ </Tailwind>
330
+ </Html>
331
+ )
332
+ }
333
+
334
+ /**
335
+ * Default localization strings for the email verification template.
336
+ * Can be overridden via the `localization` prop.
337
+ */
338
+ EmailVerificationEmail.localization = emailVerificationEmailLocalization
339
+
340
+ /**
341
+ * Example props for previewing the email template in development.
342
+ */
343
+ EmailVerificationEmail.PreviewProps = {
344
+ url: "https://better-auth-ui.com/auth/verify-email?token=example-token",
345
+ appName: "Better Auth",
346
+ email: "m@example.com",
347
+ darkMode: true
348
+ } as EmailVerificationEmailProps
349
+
350
+ export default EmailVerificationEmail
@@ -0,0 +1,9 @@
1
+ export * from "./email-changed"
2
+ export * from "./email-localization"
3
+ export * from "./email-styles"
4
+ export * from "./email-verification"
5
+ export * from "./magic-link"
6
+ export * from "./new-device"
7
+ export * from "./otp-email"
8
+ export * from "./password-changed"
9
+ export * from "./reset-password"