@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,349 @@
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 magicLinkEmailLocalization = {
27
+ SIGN_IN_TO_APP_NAME: "Sign in to {appName}",
28
+ SIGN_IN_TO_YOUR_ACCOUNT: "Sign in to your account",
29
+ YOUR_ACCOUNT: "your account",
30
+ LOGO: "Logo",
31
+ CLICK_BUTTON_TO_SIGN_IN:
32
+ "Click the button below to sign in to your account {emailAddress}.",
33
+ OR_COPY_AND_PASTE_URL: "Or copy and paste this URL into your browser:",
34
+ THIS_LINK_EXPIRES_IN_MINUTES:
35
+ "This link expires in {expirationMinutes} minutes.",
36
+ EMAIL_SENT_BY: "Email sent by {appName}.",
37
+ IF_YOU_DIDNT_REQUEST_THIS_EMAIL:
38
+ "If you didn't request this email, you can safely ignore it. Someone else might have typed your email address by mistake.",
39
+ POWERED_BY_BETTER_AUTH: "Powered by {betterAuth}"
40
+ }
41
+
42
+ /**
43
+ * Localization strings for the MagicLinkEmail component.
44
+ *
45
+ * Contains all text content used in the magic link authentication email template.
46
+ */
47
+ export type MagicLinkEmailLocalization = typeof magicLinkEmailLocalization
48
+
49
+ /**
50
+ * Props for the MagicLinkEmail component.
51
+ */
52
+ export interface MagicLinkEmailProps {
53
+ /** Magic link URL for passwordless authentication */
54
+ url: string
55
+ /** Email address of the user signing in */
56
+ email?: string
57
+ /** Name of the application sending the email */
58
+ appName?: string
59
+ /** Number of minutes until the magic 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 `MagicLinkEmailLocalization`
76
+ */
77
+ localization?: Partial<MagicLinkEmailLocalization>
78
+ }
79
+
80
+ /**
81
+ * Email template component that sends magic link authentication emails for passwordless sign-in.
82
+ *
83
+ * This email includes:
84
+ * - Sign-in button with magic link
85
+ * - Fallback URL for manual copy/paste
86
+ * - Expiration time information
87
+ * - Security notice for unauthorized requests
88
+ * - Customizable branding and styling
89
+ * - Support for light/dark mode themes
90
+ *
91
+ * @example
92
+ * ```tsx
93
+ * <MagicLinkEmail
94
+ * url="https://example.com/auth/verify?token=abc123"
95
+ * email="user@example.com"
96
+ * appName="My App"
97
+ * expirationMinutes={5}
98
+ * logoURL="https://example.com/logo.png"
99
+ * darkMode={true}
100
+ * />
101
+ * ```
102
+ */
103
+ export const MagicLinkEmail = ({
104
+ url,
105
+ email,
106
+ appName,
107
+ expirationMinutes = 5,
108
+ logoURL,
109
+ colors,
110
+ classNames,
111
+ darkMode = true,
112
+ poweredBy,
113
+ head,
114
+ ...props
115
+ }: MagicLinkEmailProps) => {
116
+ const localization = {
117
+ ...MagicLinkEmail.localization,
118
+ ...props.localization
119
+ }
120
+
121
+ const previewText = appName
122
+ ? localization.SIGN_IN_TO_APP_NAME.replace("{appName}", appName)
123
+ : localization.SIGN_IN_TO_YOUR_ACCOUNT
124
+
125
+ return (
126
+ <Html>
127
+ <Head>
128
+ <meta content="light dark" name="color-scheme" />
129
+ <meta content="light dark" name="supported-color-schemes" />
130
+
131
+ <EmailStyles colors={colors} darkMode={darkMode} />
132
+
133
+ {head}
134
+ </Head>
135
+
136
+ <Preview>{previewText}</Preview>
137
+
138
+ <Tailwind config={{ presets: [pixelBasedPreset] }}>
139
+ <Body className={cn("bg-background font-sans", classNames?.body)}>
140
+ <Container
141
+ className={cn(
142
+ "mx-auto my-auto max-w-xl px-2 py-10",
143
+ classNames?.container
144
+ )}
145
+ >
146
+ <Section
147
+ className={cn(
148
+ "bg-card text-card-foreground rounded-none border border-border p-8",
149
+ classNames?.card
150
+ )}
151
+ >
152
+ {logoURL &&
153
+ (typeof logoURL === "string" ? (
154
+ <Img
155
+ src={logoURL}
156
+ width={48}
157
+ height={48}
158
+ alt={appName || localization.LOGO}
159
+ className={cn("mx-auto mb-8", classNames?.logo)}
160
+ />
161
+ ) : (
162
+ <>
163
+ <Img
164
+ src={logoURL.light}
165
+ width={48}
166
+ height={48}
167
+ alt={appName || localization.LOGO}
168
+ className={cn(
169
+ "mx-auto mb-8 logo-light",
170
+ classNames?.logo
171
+ )}
172
+ />
173
+ <Img
174
+ src={logoURL.dark}
175
+ width={48}
176
+ height={48}
177
+ alt={appName || localization.LOGO}
178
+ className={cn(
179
+ "hidden mx-auto mb-8 logo-dark",
180
+ classNames?.logo
181
+ )}
182
+ />
183
+ </>
184
+ ))}
185
+
186
+ <Heading
187
+ className={cn(
188
+ "m-0 mb-5 text-2xl font-semibold",
189
+ classNames?.title
190
+ )}
191
+ >
192
+ {appName
193
+ ? localization.SIGN_IN_TO_APP_NAME.replace(
194
+ "{appName}",
195
+ appName
196
+ )
197
+ : localization.SIGN_IN_TO_YOUR_ACCOUNT}
198
+ </Heading>
199
+
200
+ <Text
201
+ className={cn("m-0 text-sm font-normal", classNames?.content)}
202
+ >
203
+ {(() => {
204
+ const [beforeEmailAddress, afterEmailAddress] =
205
+ localization.CLICK_BUTTON_TO_SIGN_IN.split("{emailAddress}")
206
+
207
+ return email ? (
208
+ <>
209
+ {beforeEmailAddress}
210
+ <Link
211
+ href={`mailto:${email}`}
212
+ className="text-primary font-medium"
213
+ >
214
+ {email}
215
+ </Link>
216
+ {afterEmailAddress}
217
+ </>
218
+ ) : (
219
+ localization.CLICK_BUTTON_TO_SIGN_IN.replace(
220
+ "{emailAddress}",
221
+ ""
222
+ )
223
+ .replace(/\s{2,}/g, " ")
224
+ .replace(" .", ".")
225
+ )
226
+ })()}
227
+ </Text>
228
+
229
+ <Section className="my-6">
230
+ <Button
231
+ href={url}
232
+ className={cn(
233
+ "inline-block whitespace-nowrap rounded-none text-sm font-medium py-2.5 px-6 bg-primary text-primary-foreground no-underline",
234
+ classNames?.button
235
+ )}
236
+ >
237
+ {appName
238
+ ? localization.SIGN_IN_TO_APP_NAME.replace(
239
+ "{appName}",
240
+ appName
241
+ )
242
+ : localization.SIGN_IN_TO_YOUR_ACCOUNT}
243
+ </Button>
244
+ </Section>
245
+
246
+ <Text
247
+ className={cn(
248
+ "m-0 mb-3 text-xs text-muted-foreground",
249
+ classNames?.description
250
+ )}
251
+ >
252
+ {localization.OR_COPY_AND_PASTE_URL}
253
+ </Text>
254
+
255
+ <Link
256
+ className={cn(
257
+ "break-all text-xs text-primary",
258
+ classNames?.link
259
+ )}
260
+ href={url}
261
+ >
262
+ {url}
263
+ </Link>
264
+
265
+ <Hr
266
+ className={cn(
267
+ "my-6 w-full border border-solid border-border",
268
+ classNames?.separator
269
+ )}
270
+ />
271
+
272
+ {expirationMinutes || appName ? (
273
+ <Text
274
+ className={cn(
275
+ "m-0 mb-3 text-xs text-muted-foreground",
276
+ classNames?.description
277
+ )}
278
+ >
279
+ {expirationMinutes
280
+ ? localization.THIS_LINK_EXPIRES_IN_MINUTES.replace(
281
+ "{expirationMinutes}",
282
+ expirationMinutes.toString()
283
+ )
284
+ : null}
285
+ {appName && (
286
+ <>
287
+ {expirationMinutes ? " " : ""}
288
+ {localization.EMAIL_SENT_BY.replace("{appName}", appName)}
289
+ </>
290
+ )}
291
+ </Text>
292
+ ) : null}
293
+
294
+ <Text
295
+ className={cn(
296
+ "m-0 text-xs text-muted-foreground",
297
+ classNames?.description
298
+ )}
299
+ >
300
+ {localization.IF_YOU_DIDNT_REQUEST_THIS_EMAIL}
301
+ </Text>
302
+
303
+ {poweredBy && (
304
+ <Text
305
+ className={cn(
306
+ "m-0 mt-4 text-center text-[11px] text-muted-foreground",
307
+ classNames?.poweredBy
308
+ )}
309
+ >
310
+ {(() => {
311
+ const [beforeBetterAuth, afterBetterAuth] =
312
+ localization.POWERED_BY_BETTER_AUTH.split("{betterAuth}")
313
+
314
+ return (
315
+ <>
316
+ {beforeBetterAuth}
317
+ <Link
318
+ href="https://better-auth.com"
319
+ className={cn(
320
+ "text-primary underline",
321
+ classNames?.link
322
+ )}
323
+ >
324
+ better-auth
325
+ </Link>
326
+ {afterBetterAuth}
327
+ </>
328
+ )
329
+ })()}
330
+ </Text>
331
+ )}
332
+ </Section>
333
+ </Container>
334
+ </Body>
335
+ </Tailwind>
336
+ </Html>
337
+ )
338
+ }
339
+
340
+ MagicLinkEmail.localization = magicLinkEmailLocalization
341
+
342
+ MagicLinkEmail.PreviewProps = {
343
+ url: "https://better-auth-ui.com/auth/verify?token=example-token",
344
+ email: "m@example.com",
345
+ appName: "Better Auth",
346
+ darkMode: true
347
+ } as MagicLinkEmailProps
348
+
349
+ export default MagicLinkEmail