Open burggraf opened 3 years ago
any update on this?
Any update??? @supabase !!!
Hey all,
Thanks for your patience. Just to get a sense of what languages people are looking for, do you mind commenting with the corresponding language you'd like to see(or react to corresponding post) ? Some examples below.
This would probably fit better in discussions if we have more than five main languages
es
fr
de
pt
pl
Pt-br
Integrate with i18next !!!
nl
Nothing?
No news on this ?
Not yet but it's being looked into but there are potentially some dashboard updates which need to be made on the main platform to support changes so progress is not easily visible.
Thanks for your patience so far!
The update for now is that you can change your templates to support one single language (e.g. French, German, Spanish) but we're still adding support for multiple languages
Please don't forget to add PT-BR Portuguese.... ( or something like i18n ) My project is only waiting for this !!!!
@wizzymotion will keep pt-br in mind -- if it's okay with you do you mind sharing your use case (e.g. send emails entirely in pt-br or internationalisation with some users opting for en and others for pt-br and others for another language entirely)? We can see if we can suggest any workarounds in the time being
@J0 I already have an alternative up my sleeve.
https://github.com/burggraf/subase-mailer from @burggraf
While I don't finish all the rest of the project, I'm leaving this problem aside, trusting blindly that supabase will be able to serve my application in a GLOBAL way and not just in some languages.
But when this becomes my central problem, I will certainly share everything with you.
Thanks.
cs
Hey everyone,
Although not very well presented in the Supabase Dashboard, this is somewhat doable today. GoTrue uses Go's templating language which you can use to support internationalized templates.
For example, if you wish to support 2 languages, for example Spanish and English, this is an example template you can use:
{{if eq .Data.Language "es"}}
<h1>¡Has sido invitado!</h1>
<p>Ha sido invitado a crear un usuario en {{ .SiteURL }}. Sigue este enlace para aceptar la invitación...</p>
{{else}}
<h1>You have been invited!</h1>
<p>You have been invited to create a user on {{ .SiteURL }}. Follow this link to accept the invitation...</p>
{{end}}
The .Data.language
would be coming from the user's metadata, which you would need to set manually as the data
parameter in the sign up method for example.
We are thinking about adding better support for this in the future, but this will get you far if you really need this. Reach out to support@supabase.com if you need more help with this.
Hey,
thanks for the snippet @hf !
This didn't work for me:
{{if .Data.Language == "es"}}
I had to change the template syntax to:
{{if eq .Data.language "es"}}
That way, when using the signup-method with
//...
data: {
language: 'es'
}
//...
it sends the correct email content.
Maybe I just used your solution incorrectly, but this might help other people regardless ^^.
Curiously, with the orignal syntax it would send an entirely different Email containing the line
Alternatively, enter the code:
xxxxxx (6-digit number)
i tried the solution that @MJDeligan mentioned above but can't get it to work with supabase-js v2:
when i send a signInWithOtp like that:
supabase.auth.signInWithOtp({
email,
options: {
emailRedirectTo: `http://localhost:3000/${language}/app/auth`,
data: { language:"en" },
},
in the supabase magiclink template the gotrue template variable {{.Data.language}}
is empty.
are there any docs or references about this out there?
thanks for any feedback or help!
I can confirm that .Data does not seem to be accessible (or rather it is an empty map) in the template when using auth.signInWithOtp
. It works with the auth.signup
method (at least with email+password) in v2.0.0-rc.10.
The docs for auth.signInWithOtp
do not include the data property as part of options, but it is declared in the typescript type definition.
Thanks @MJDeligan for confirming that signInWithOTP in supabase-js v2 is lacking data options to be usable. Bit disappointed as that was the first thing I tried and making supabase my baas for a new commercial app. Can't see how I could make auth. via magiclink work including i18n email templates using supabase.auth for the time being.
I think sending data
with signInWithOtp
was maybe just fixed: https://github.com/supabase/gotrue/issues/699#issuecomment-1286449851
Here's how I solved it
confirm.html
<h1>{{ .Data.welcome }}</h1>
<p>{{ .Data.follow }}</p>
<p><a href='{{ .ConfirmationURL }}'>{{ .Data.link }}</a></p>
.env
GOTRUE_MAILER_TEMPLATES_CONFIRMATION=https://xxx.tld/mail-templates/confirm.html
signUp.js
...
const {error} = await supabase.auth.signUp(
{
email,
password,
options: {
data: t('mail.confirm', {returnObjects: true}),
},
},
);
...
With this solution I can use the same translation backend the frontend uses.
I still need to find a solution to translate the MAILER_SUBJECTS_XXX
.
I didn't have the opportunity to test the workaround described in this issue, but I'm curious if it is possible to use GoTrue syntax in the subject field for the email too? Has anybody tried that?
To be honest using dynamic values instead of several static templates (really coding antipattern) is the only way to go. I have to support all 24 EU languages for example.
how do you localise email subject with the template?
as an alternative... is it possible to disable emailing in cloud Supabase completely so I'd handle all email flows myself in my backend? the rough idea is to handle sign up flows, password resets etc in my own backend with the admin API. that logic would also feed PostMark or MailGun templates with data including URLs. for that to work, I'd need to disable emailing in Supabase (dashboard) completely. not ideal for paid BaaS .
Just to get a sense of what languages people are looking for
@J0 any language / locale really. as @kvetoslavnovak pointed out just in the EU there 20+ options.
Hi, I guess I have quite an easy working solution.
We can use data property when dealing with Supabase Auth metohods and send/store metadata for user. Which in this case means email respective language translations stored and in object (I call it authEmailsTranslations
in the example). [locals.lang]
refers to the user locale (language) you need to get somehow in the front end (usually using language dropdown in a web-page header or through browser API).
My endpoint code goes something like this when user signs up (it is possible to update authEmailsTranslations whenever we call Supabase auth method that accept data
) :
...
await supabase.auth.signUp({
email: body.email,
password: body.password,
options: {
data: authEmailsTranslations[locals.lang]
}
})
...
The possible structure of languages translations authEmailsTranslations object is hereunder at the bottom of this comment.
Respective email templates:
Confirm signup
Subject heading: {{ .Data.ConfirmSignup.Title }}
<h2>{{ .Data.ConfirmSignup.H2 }}</h2>
<p>{{ .Data.ConfirmSignup.P }}</p>
<p><a href="{{ .ConfirmationURL }}">{{ .Data.ConfirmSignup.Link }}</a></p>
Invite user
Subject heading: {{ .Data.InviteUser.Title }}
<h2>{{ .Data.InviteUser.H2 }}</h2>
<p>{{ .Data.InviteUser.PFirstPart }} {{ .SiteURL }} {{ .Data.InviteUser.PSecondPart }}</p>
<p><a href="{{ .ConfirmationURL }}">{{ .Data.InviteUser.Link }}</a></p>
Magic Link
Subject heading: {{ .Data.MagicLink.Title }}
<h2>{{ .Data.MagicLink.H2 }}</h2>
<p> {{ .Data.MagicLink.P }}</p>
<p><a href="{{ .ConfirmationURL }}">{{ .Data.MagicLink.Link }}</a></p></h2>
Change Email Address
Subject heading: {{ .Data.ChangeEmailAddress.Title }}
<h2>{{ .Data.ChangeEmailAddress.H2 }}</h2>
<p>{{ .Data.ChangeEmailAddress.P }} {{ .Email }} {{ .Data.ChangeEmailAddress.To }} {{ .NewEmail }} {{ .Data.ChangeEmailAddress.Last }} </p>
<p><a href="{{ .ConfirmationURL }}">{{ .Data.ChangeEmailAddress.Link }}</a></p>
Reset Password
Subject heading: {{ .Data.ResetPassword.Title }}
<h2>{{ .Data.ResetPassword.H2 }}</h2>
<p>{{ .Data.ResetPassword.P }}</p>
<p><a href="{{ .ConfirmationURL }}">{{ .Data.ResetPassword.Link }}</a></p>
So I guess Supabase may just update the documentation as internationalization for authentication email templates works quite ok, at least for me.
EDIT: I am storing all respective language email templates data when user sings up as user's metadata. You may add a code to update this whenever user sues Supabase auth methods that uses data
or data: options: { }
.
Would be nicer if Supabase let us to have juts one file for all users somewhere and store only language key per user. You might also have an endpoint and form to let user update his/her preferred email language later.
There are all translations for EU languages (authEmailsTranslations object) if someone is interested or for Supabase team to implement it:
// authEmailsTranslations object
export const authEmailsTranslations = {
bg: {
ConfirmSignup: {
Title: "Потвърдете регистрацията си",
H2: "Потвърдете регистрацията си",
P: "Следвайте този линк, за да потвърдите вашия потребител:",
Link: "Потвърдете имейла си"
},
InviteUser: {
Title: "Поканен сте",
H2: "Бяхте поканен",
PFirstPart: "Бяхте поканен да създадете потребител в",
PSecondPart: ". Следвайте този линк, за да приемете поканата:",
Link: "Приеми поканата"
},
MagicLink: {
Title: "Вашият магически линк",
H2: "Магически линк",
P: "Следвайте този линк, за да влезете в профила си:",
Link: "Влезте в профила си"
},
ChangeEmailAddress: {
Title: "Потвърдете промяната на електронната поща",
H2: "Потвърдете промяната на имейла",
P: "Следвайте този линк, за да потвърдите актуализацията на вашия имейл от",
To: "до",
Last: ":",
Link: "Променете имейла"
},
ResetPassword: {
Title: "Нулиране на паролата",
H2: "Нулиране на парола",
P: "Следвайте този линк, за да нулирате паролата за вашия потребител:",
Link: "Нулиране на паролата"
}
},
es: {
ConfirmSignup: {
Title: "Confirma tu registro",
H2: "Confirme su registro",
P: "Siga este enlace para confirmar su usuario:",
Link: "Confirme su correo electrónico"
},
InviteUser: {
Title: "Has sido invitado",
H2: "Ha sido invitado",
PFirstPart: "Ha sido invitado a crear un usuario en",
PSecondPart: ". Siga este enlace para aceptar la invitación:",
Link: "Acepte la invitación"
},
MagicLink: {
Title: "Tu enlace mágico",
H2: "Enlace mágico",
P: "Siga este enlace para iniciar sesión:",
Link: "Iniciar sesión"
},
ChangeEmailAddress: {
Title: "Confirma el cambio de correo electrónico",
H2: "Confirme el cambio de correo electrónico",
P: "Siga este enlace para confirmar la actualización de su correo electrónico de",
To: "a",
Last: ":",
Link: "Cambiar correo electrónico"
},
ResetPassword: {
Title: "Restablece tu contraseña",
H2: "Restablecer contraseña",
P: "Siga este enlace para restablecer la contraseña de su usuario:",
Link: "Restablecer contraseña"
}
},
cs: {
ConfirmSignup: {
Title: "Potvrďte registraci",
H2: "Potvrďte svou registraci",
P: "Následujte tento odkaz pro potvrzení uživatele:",
Link: "Potvrdit e-mail"
},
InviteUser: {
Title: "Byli jste pozváni",
H2: "Byli jste pozváni",
PFirstPart: "Byli jste pozváni k vytvoření uživatele na",
PSecondPart: ". Následujte tento odkaz pro přijetí pozvánky:",
Link: "Přijmout pozvání"
},
MagicLink: {
Title: "Váš kouzelný odkaz",
H2: "Kouzelný odkaz",
P: "Následujte tento odkaz pro přihlášení:",
Link: "Přihlásit se"
},
ChangeEmailAddress: {
Title: "Potvrďte změnu e-mailové adresy",
H2: "Potvrďte změnu e-mailové adresy",
P: "Následujte tento odkaz pro potvrzení aktualizace vaší e-mailové adresy z",
To: "na",
Last: ":",
Link: "Změnit e-mailovou adresu"
},
ResetPassword: {
Title: "Obnovte své heslo",
H2: "Obnovit heslo",
P: "Následujte tento odkaz pro obnovení hesla pro váš uživatelský účet:",
Link: "Obnovit heslo"
}
},
da: {
ConfirmSignup: {
Title: "Bekræft din tilmelding",
H2: "Bekræft din tilmelding",
P: "Følg dette link for at bekræfte din bruger:",
Link: "Bekræft din e-mail"
},
InviteUser: {
Title: "Du er blevet inviteret",
H2: "Du er blevet inviteret",
PFirstPart: "Du er blevet inviteret til at oprette en bruger på",
PSecondPart: ". Følg dette link for at acceptere invitationen:",
Link: "Accepter invitationen"
},
MagicLink: {
Title: "Dit magiske link",
H2: "Magisk link",
P: "Følg dette link for at logge ind:",
Link: "Log ind"
},
ChangeEmailAddress: {
Title: "Bekræft ændring af e-mailadresse",
H2: "Bekræft ændring af e-mailadresse",
P: "Følg dette link for at bekræfte opdateringen af din e-mailadresse fra",
To: "til",
Last: ":",
Link: "Ændre e-mailadresse"
},
ResetPassword: {
Title: "Nulstil din adgangskode",
H2: "Nulstil adgangskode<",
P: "Følg dette link for at nulstille adgangskoden for din bruger:",
Link: "Nulstil adgangskode"
}
},
de: {
ConfirmSignup: {
Title: "Bestätige deine Registrierung",
H2: "Bestätige deine Anmeldung",
P: "Folge diesem Link, um deinen Benutzer zu bestätigen:",
Link: "Bestätige deine E-Mail"
},
InviteUser: {
Title: "Du wurdest eingeladen",
H2: "Du wurdest eingeladen",
PFirstPart: "Du wurdest eingeladen, einen Benutzer auf",
PSecondPart: "zu erstellen. Folge diesem Link, um die Einladung anzunehmen:",
Link: "Einladung annehmen"
},
MagicLink: {
Title: "Dein magischer Link",
H2: "Magic Link",
P: "Folge diesem Link, um dich anzumelden:",
Link: "Anmelden"
},
ChangeEmailAddress: {
Title: "Bestätige Änderung deiner E-Mail-Adresse",
H2: "Bestätige Änderung der E-Mail-Adresse",
P: "Folge diesem Link, um die Aktualisierung deiner E-Mail-Adresse von",
To: "auf",
Last: "zu bestätigen:",
Link: "E-Mail-Adresse ändern"
},
ResetPassword: {
Title: "Setze dein Passwort zurück",
H2: "Passwort zurücksetzen",
P: "Folge diesem Link, um das Passwort für deinen Benutzer zurückzusetzen:",
Link: "Passwort zurücksetzen"
}
},
et: {
ConfirmSignup: {
Title: "Kinnita registreerumine",
H2: "Kinnita registreerimine",
P: "Järgi seda linki, et kinnitada oma kasutaja:",
Link: "Kinnita oma meil"
},
InviteUser: {
Title: "Olete kutsutud",
H2: "Sind on kutsutud",
PFirstPart: "Sind on kutsutud looma kasutajat saidil",
PSecondPart: ". Järgi seda linki, et kutsung vastu võtta:",
Link: "Kutsung vastu võtta"
},
MagicLink: {
Title: "Sinu maagiline link",
H2: "Võlulink",
P: "Järgi seda linki, et sisse logida:",
Link: "Logi sisse"
},
ChangeEmailAddress: {
Title: "Kinnita e-posti aadressi muutus",
H2: "Kinnita e-posti aadressi muutus",
P: "Järgi seda linki, et kinnitada oma e-posti aadressi muutust",
To: "lt",
Last: "le:",
Link: "Muuda e-posti aadressi"
},
ResetPassword: {
Title: "Lähtesta parool",
H2: "Lähtesta parool",
P: "Järgi seda linki, et lähtestada oma kasutaja parool:",
Link: "Lähtesta parool"
}
},
el: {
ConfirmSignup: {
Title: "Επιβεβαίωση εγγραφής",
H2: "Επιβεβαίωση εγγραφής",
P: "Ακολουθήστε αυτόν τον σύνδεσμο για να επιβεβαιώσετε τον χρήστη σας:",
Link: "Επιβεβαιώστε το email σας"
},
InviteUser: {
Title: "Έχετε προσκληθεί",
H2: "Έχετε προσκληθεί",
PFirstPart: "Έχετε προσκληθεί να δημιουργήσετε ένα χρήστη στο",
PSecondPart: ". Ακολουθήστε αυτόν τον σύνδεσμο για να αποδεχτείτε την πρόσκληση:",
Link: "Αποδέχομαι την πρόσκληση"
},
MagicLink: {
Title: "Ο μαγικός σας σύνδεσμος",
H2: "Μαγικός σύνδεσμος",
P: "Ακολουθήστε αυτόν τον σύνδεσμο για να συνδεθείτε:",
Link: "Σύνδεση"
},
ChangeEmailAddress: {
Title: "Επιβεβαίωση αλλαγής διεύθυνσης email",
H2: "Επιβεβαίωση αλλαγής email",
P: "Ακολουθήστε αυτόν τον σύνδεσμο για να επιβεβαιώσετε την ενημέρωση του email σας από το",
To: "σε",
Last: ":",
Link: "Αλλαγή email"
},
ResetPassword: {
Title: "Επαναφορά κωδικού πρόσβασης",
H2: "Επαναφορά κωδικού πρόσβασης",
P: "Ακολουθήστε αυτόν τον σύνδεσμο για να επαναφέρετε τον κωδικό πρόσβασης για τον χρήστη σας:",
Link: "Επαναφορά κωδικού πρόσβασης"
}
},
en: {
ConfirmSignup: {
Title: "Confirm Your Signup",
H2: "Confirm your signup",
P: "Follow this link to confirm your user:",
Link: "Confirm your mail"
},
InviteUser: {
Title: "You have been invited",
H2: "You have been invited",
PFirstPart: "You have been invited to create a user on",
PSecondPart: ". Follow this link to accept the invite:",
Link: "Accept the invite"
},
MagicLink: {
Title: "Your Magic Link",
H2: "Magic Link",
P: "Follow this link to login:",
Link: "Log In"
},
ChangeEmailAddress: {
Title: "Confirm Email Change",
H2: "Confirm Change of Email",
P: "Follow this link to confirm the update of your email from",
To: "to",
Last: ":",
Link: "Change Email"
},
ResetPassword: {
Title: "Reset Your Password",
H2: "Reset Password",
P: "Follow this link to reset the password for your user:",
Link: "Reset Password"
}
},
fr: {
ConfirmSignup: {
Title: "Confirmez votre inscription",
H2: "Confirmez votre inscription",
P: "Suivez ce lien pour confirmer votre compte :",
Link: "Confirmez votre adresse email"
},
InviteUser: {
Title: "Vous avez été invité",
H2: "Vous avez été invité",
PFirstPart: "Vous avez été invité à créer un compte sur",
PSecondPart: ". Suivez ce lien pour accepter l'invitation :",
Link: "Accepter l'invitation"
},
MagicLink: {
Title: "Votre lien magique",
H2: "Lien magique",
P: "Suivez ce lien pour vous connecter :",
Link: "Se connecter"
},
ChangeEmailAddress: {
Title: "Confirmez le changement d'adresse e-mail",
H2: "Confirmez le changement d'adresse email",
P: "Suivez ce lien pour confirmer la mise à jour de votre adresse email de",
To: "à",
Last: " :",
Link: "Changer l'adresse email"
},
ResetPassword: {
Title: "Réinitialisez votre mot de passe",
H2: "Réinitialiser le mot de passe",
P: "Suivez ce lien pour réinitialiser le mot de passe de votre compte :",
Link: "Réinitialiser le mot de passe"
}
},
ga: {
ConfirmSignup: {
Title: "Deimhnigh do chlárú",
H2: "Cinnteanaigh do chlárú",
P: "Lean an nasc seo chun do chuntas a dhearbhú:",
Link: "Deimhnigh do sheoladh ríomhphoist"
},
InviteUser: {
Title: "Tá cuireadh curtha chugat",
H2: "Dearadh cuireadh chugat",
PFirstPart: "Cuireadh cuireadh chugat chun cuntas a chruthú ar",
PSecondPart: ". Lean an nasc seo chun an cuireadh a dheimhniú:",
Link: "Glac leis an gcuireadh"
},
MagicLink: {
Title: "Do nasc draíochta",
H2: "Nasc Draíochta",
P: "Lean an nasc seo chun logáil isteach:",
Link: "Logáil isteach"
},
ChangeEmailAddress: {
Title: "Deimhnigh an t-athrú seolta ríomhphoist",
H2: "Cinnteanaigh Athrú ar Sheoladh Ríomhphoist",
P: "Lean an nasc seo chun an nuashonrú ar do sheoladh ríomhphoist ó",
To: "go",
Last: "a dhearbhú:",
Link: "Athraigh Seoladh Ríomhphoist"
},
ResetPassword: {
Title: "Athshocraigh do phasfhocal",
H2: "Athshocraigh Pasfhocal",
P: "Lean an nasc seo chun an pasfhocal ar do chuntas a athshocrú:",
Link: "Athshocraigh Pasfhocal"
}
},
hr: {
ConfirmSignup: {
Title: "Potvrdite svoju prijavu",
H2: "Potvrdite svoju prijavu",
P: "Slijedite ovu vezu da biste potvrdili svoj račun:",
Link: "Potvrdite svoju e-poštu"
},
InviteUser: {
Title: "Pozvani ste",
H2: "Pozvani ste",
PFirstPart: "Pozvani ste da stvorite račun na",
PSecondPart: ". Slijedite ovu vezu da biste prihvatili pozivnicu:",
Link: "Prihvati pozivnicu"
},
MagicLink: {
Title: "Vaš čarobni link",
H2: "Čarobna veza",
P: "Slijedite ovu vezu da biste se prijavili:",
Link: "Prijavi se"
},
ChangeEmailAddress: {
Title: "Potvrdite promjenu e-pošte",
H2: "Potvrdite promjenu adrese e-pošte",
P: "Slijedite ovu vezu da biste potvrdili ažuriranje vaše e-pošte sa",
To: "na",
Last: ":",
Link: "Promijenite e-poštu"
},
ResetPassword: {
Title: "Poništite svoju lozinku",
H2: "Poništite lozinku",
P: "Slijedite ovu vezu da biste poništili lozinku za svoj račun:",
Link: "Poništi lozinku"
}
},
it: {
ConfirmSignup: {
Title: "Conferma la tua iscrizione",
H2: "Conferma la tua registrazione",
P: "Segui questo link per confermare il tuo account:",
Link: "Conferma la tua email"
},
InviteUser: {
Title: "Sei stato invitato",
H2: "Sei stato invitato",
PFirstPart: "Sei stato invitato a creare un account su",
PSecondPart: ". Segui questo link per accettare l'invito:",
Link: "Accetta l'invito"
},
MagicLink: {
Title: "Il tuo link magico",
H2: "Link magico",
P: "Segui questo link per effettuare il login:",
Link: "Accedi"
},
ChangeEmailAddress: {
Title: "Conferma il cambio di indirizzo email",
H2: "Conferma modifica email",
P: "Segui questo link per confermare l'aggiornamento della tua email da",
To: "a",
Last: ":",
Link: "Cambia email"
},
ResetPassword: {
Title: "Reimposta la tua password",
H2: "Reimposta la password",
P: "Segui questo link per reimpostare la password del tuo account:",
Link: "Reimposta la password"
}
},
lv: {
ConfirmSignup: {
Title: "Apstipriniet reģistrāciju",
H2: "Apstipriniet reģistrāciju",
P: "Sekojiet šim saitam, lai apstiprinātu savu lietotāju:",
Link: "Apstipriniet e-pastu"
},
InviteUser: {
Title: "Jums ir ielūgums",
H2: "Jūs esat aicināts",
PFirstPart: "Jums ir pieprasīts izveidot lietotāju vietnē",
PSecondPart: ". Sekojiet šim saitam, lai pieņemtu uzaicinājumu:",
Link: "Pieņemt uzaicinājumu"
},
MagicLink: {
Title: "Jūsu burvju saite",
H2: "Mākslīgais saite",
P: "Sekojiet šim saitam, lai pierakstītos:",
Link: "Pierakstīties"
},
ChangeEmailAddress: {
Title: "Apstipriniet e-pasta izmaiņas",
H2: "Apstipriniet e-pasta adreses izmaiņas",
P: "Sekojiet šim saitam, lai apstiprinātu savas e-pasta adreses izmaiņas no",
To: "uz",
Last: ":",
Link: "Mainīt e-pastu"
},
ResetPassword: {
Title: "Atiestatiet paroli",
H2: "Atiestatiet paroli",
P: "Sekojiet šim saitam, lai atiestatītu savas lietotāja paroli:",
Link: "Atiestatīt paroli"
}
},
lt: {
ConfirmSignup: {
Title: "Patvirtinkite registraciją",
H2: "Patvirtinkite savo registraciją",
P: "Sekite šią nuorodą, kad patvirtintumėte savo vartotoją:",
Link: "Patvirtinti el. laišką"
},
InviteUser: {
Title: "Jums buvo pakviestas",
H2: "Jums buvo pakviestas kurti vartotoją",
PFirstPart: "Jums buvo pakviestas kurti vartotoją",
PSecondPart: ". Sekite šią nuorodą, kad priimtumėte pakvietimą:",
Link: "Priimti pakvietimą"
},
MagicLink: {
Title: "Jūsų magiškas nuorodas",
H2: "Magiškas prisijungimo nuoroda",
P: "Sekite šią nuorodą, kad prisijungtumėte:",
Link: "Prisijungti"
},
ChangeEmailAddress: {
Title: "Patvirtinkite el. pašto pakeitimą",
H2: "Patvirtinkite el. pašto adreso pakeitimą",
P: "Sekite šią nuorodą, kad patvirtintumėte savo el. pašto adreso pakeitimą iš",
To: "į",
Last: ":",
Link: "Pakeisti el. paštą"
},
ResetPassword: {
Title: "Atstatyti slaptažodį",
H2: "Slaptažodžio atkūrimas",
P: "Sekite šią nuorodą, kad atkurtumėte savo vartotojo slaptažodį:",
Link: "Atkurti slaptažodį"
}
},
hu: {
ConfirmSignup: {
Title: "Erősítse meg a regisztrációját",
H2: "Regisztráció megerősítése",
P: "A felhasználó megerősítéséhez kövesse ezt a hivatkozást:",
Link: "Erősítse meg az e-mail címét"
},
InviteUser: {
Title: "Meghívást kapott",
H2: "Elküldtek egy meghívót",
PFirstPart: "Meghívták Önt, hogy regisztráljon a(z)",
PSecondPart: "oldalra. Az alábbi hivatkozásra kattintva elfogadhatja a meghívást:",
Link: "Fogadja el a meghívást"
},
MagicLink: {
Title: "A varázs linkje",
H2: "Mágikus hivatkozás",
P: "A belépéshez kövesse ezt a hivatkozást:",
Link: "Bejelentkezés"
},
ChangeEmailAddress: {
Title: "Erősítse meg az e-mail cím módosítását",
H2: "E-mail cím változtatásának megerősítése",
P: "Az e-mail címe módosításához kövesse ezt a hivatkozást:",
To: "-tól",
Last: "-ra:",
Link: "Változtassa meg az e-mail címét"
},
ResetPassword: {
Title: "Állítsa vissza a jelszót",
H2: "Jelszó visszaállítása",
P: "A felhasználó jelszavának visszaállításához kövesse ezt a hivatkozást:",
Link: "Jelszó visszaállítása"
}
},
mt: {
ConfirmSignup: {
Title: "Ikkonferma l-Iskrizzjoni Tiegek",
H2: "Ikkonferma l-Iskrizzjoni tiegħek",
P: "Segwi dan il-link biex ikkonferma l-utent tiegħek:",
Link: "Ikkonferma l-email tiegħek"
},
InviteUser: {
Title: "Int il-ġejjin imsejħulik",
H2: "Inti imsejħa għall-ħatra",
PFirstPart: "Inti imsejħa biex tikkrea l-utent fuq",
PSecondPart: ". Segwi dan il-link biex taċċetta l-ħatra:",
Link: "Aċċetta l-ħatra"
},
MagicLink: {
Title: "Il-Link tal-Maġija Tiegek",
H2: "Link Magic",
P: "Segwi dan il-link biex tidħol fil-kont tiegħek:",
Link: "Dħol fil-Kont"
},
ChangeEmailAddress: {
Title: "Ikkonferma Tibdil fil-Indirizz Elettroniku",
H2: "Ikkonferma t-Tibdil fil-Email",
P: "Segwi dan il-link biex ikkonferma t-tibdil fil-email tiegħek minn",
To: "għal",
Last: ":",
Link: "Tibdil Email"
},
ResetPassword: {
Title: "Irrisettja l-Password Tiegek",
H2: "Irrikonoxxi l-Password",
P: "Segwi dan il-link biex irrikonoxxi l-password tal-utent tiegħek:",
Link: "Irrikonoxxi l-Password"
}
},
nl: {
ConfirmSignup: {
Title: "Bevestig uw aanmelding",
H2: "Bevestig je aanmelding",
P: "Volg deze link om je gebruiker te bevestigen:",
Link: "Bevestig je e-mail"
},
InviteUser: {
Title: "U bent uitgenodigd",
H2: "Je bent uitgenodigd",
PFirstPart: "Je bent uitgenodigd om een gebruiker aan te maken op",
PSecondPart: ". Volg deze link om de uitnodiging te accepteren:",
Link: "Accepteer de uitnodiging"
},
MagicLink: {
Title: "Uw magische link",
H2: "Magische link",
P: "Volg deze link om in te loggen:",
Link: "Inloggen"
},
ChangeEmailAddress: {
Title: "Bevestig de wijziging van e-mailadres",
H2: "Bevestig wijziging e-mailadres",
P: "Volg deze link om de update van je e-mailadres van",
To: "naar",
Last: "te bevestigen:",
Link: "E-mail wijzige"
},
ResetPassword: {
Title: "Reset uw wachtwoord",
H2: "Wachtwoord resetten",
P: "Volg deze link om het wachtwoord voor je gebruiker te resetten:",
Link: "Wachtwoord resetten"
}
},
pl: {
ConfirmSignup: {
Title: "Potwierdź swoje konto",
H2: "Potwierdź rejestrację",
P: "Kliknij w link, aby potwierdzić swoje konto:",
Link: "Potwierdź e-mail"
},
InviteUser: {
Title: "Zostałeś zaproszony",
H2: "Zostałeś zaproszony",
PFirstPart: "Zostałeś zaproszony do utworzenia konta na",
PSecondPart: ". Kliknij w link, aby przyjąć zaproszenie:",
Link: "Przyjmij zaproszenie"
},
MagicLink: {
Title: "Twój magiczny link",
H2: "Magiczny link<",
P: "Kliknij w link, aby się zalogować:",
Link: "Zaloguj się"
},
ChangeEmailAddress: {
Title: "Potwierdź zmianę adresu e-mail",
H2: "Potwierdź zmianę adresu e-mail",
P: "Kliknij w link, aby potwierdzić zmianę adresu e-mail z",
To: "na",
Last: ":",
Link: "Zmień adres e-mail"
},
ResetPassword: {
Title: "Zresetuj hasło",
H2: "Zresetuj hasło",
P: "Kliknij w link, aby zresetować hasło dla Twojego konta:",
Link: "Zresetuj hasło"
}
},
pt: {
ConfirmSignup: {
Title: "Confirme sua inscrição",
H2: "Confirme seu cadastro",
P: "Siga este link para confirmar o seu usuário:",
Link: "Confirme seu e-mail"
},
InviteUser: {
Title: "Você foi convidado",
H2: "Você foi convidado",
PFirstPart: "Você foi convidado para criar um usuário em",
PSecondPart: ". Siga este link para aceitar o convite:",
Link: "Aceite o convite"
},
MagicLink: {
Title: "Seu link mágico",
H2: "Link Mágico",
P: "Siga este link para fazer login:",
Link: "Entrar"
},
ChangeEmailAddress: {
Title: "Confirme a alteração do endereço de e-mail",
H2: "Confirme a alteração de e-mail",
P: "Siga este link para confirmar a atualização do seu e-mail de",
To: "para",
Last: ":",
Link: "Alterar e-mail"
},
ResetPassword: {
Title: "Redefinir sua senha",
H2: "Redefinir senha",
P: "Siga este link para redefinir a senha do seu usuário:",
Link: "Redefinir senha"
}
},
ro: {
ConfirmSignup: {
Title: "Confirmați-vă înregistrarea",
H2: "Confirmă-ți înregistrarea",
P: "Urmărește acest link pentru a-ți confirma utilizatorul:",
Link: "Confirmă-ți adresa de e-mail"
},
InviteUser: {
Title: "Ați fost invitat",
H2: "Ai fost invitat",
PFirstPart: "Ai fost invitat să-ți creezi un cont pe",
PSecondPart: ". Urmărește acest link pentru a accepta invitația:",
Link: "Acceptă invitația"
},
MagicLink: {
Title: "Link-ul dvs. magic",
H2: "Link magic",
P: "Urmărește acest link pentru a te autentifica:",
Link: "Conectează-te"
},
ChangeEmailAddress: {
Title: "Confirmați schimbarea adresei de e-mail",
H2: "Confirmă schimbarea adresei de e-mail",
P: "Urmărește acest link pentru a confirma schimbarea adresei tale de e-mail de la",
To: "la",
Last: ":",
Link: "Schimbă adresa de e-e-mail"
},
ResetPassword: {
Title: "Resetați parola",
H2: "Resetare parolă",
P: "Urmărește acest link pentru a-ți reseta parola:",
Link: "Resetează parola"
}
},
sk: {
ConfirmSignup: {
Title: "Potvrďte svoju registráciu",
H2: "Potvrdenie registrácie",
P: "Pre potvrdenie svojho používateľa postupujte podľa tohto odkazu:",
Link: "Potvrďte svoj email"
},
InviteUser: {
Title: "Boli ste pozvaní",
H2: "Boli ste pozvaní",
PFirstPart: "Boli ste pozvaní vytvoriť si používateľa na",
PSecondPart: ". Pre prijatie pozvánky postupujte podľa tohto odkazu:",
Link: "Prijmite pozvánku"
},
MagicLink: {
Title: "Váš kúzelný odkaz",
H2: "Kúzelný odkaz",
P: "Pre prihlásenie sa postupujte podľa tohto odkazu:",
Link: "Prihlásiť sa"
},
ChangeEmailAddress: {
Title: "Potvrďte zmenu e-mailovej adresy",
H2: "Potvrdenie zmeny e-mailu",
P: "re potvrdenie aktualizácie vašej e-mailovej adresy z",
To: "na",
Last: "postupujte podľa tohto odkazu:",
Link: "Zmeniť e-mail"
},
ResetPassword: {
Title: "Obnoviť svoje heslo",
H2: "Obnovenie hesla",
P: "Pre obnovenie hesla pre svojho používateľa postupujte podľa tohto odkazu:",
Link: "Obnoviť heslo"
}
},
sl: {
ConfirmSignup: {
Title: "Potrdite svojo registracijo",
H2: "Potrdite svojo prijavo",
P: "Sledite tej povezavi, da potrdite svojega uporabnika:",
Link: "Potrdi svoj e-poštni naslov"
},
InviteUser: {
Title: "Bili ste povabljeni",
H2: "Bili ste povabljeni",
PFirstPart: "Povabljeni ste, da ustvarite uporabnika na",
PSecondPart: ". Sledite tej povezavi, da sprejmete povabilo:",
Link: "Sprejmi povabilo"
},
MagicLink: {
Title: "Vaš čarobni povezava",
H2: "Čarovna povezava",
P: "Sledite tej povezavi, da se prijavite:",
Link: "Prijava"
},
ChangeEmailAddress: {
Title: "Potrdite spremembo e-poštnega naslova",
H2: "Potrdite spremembo e-poštnega naslova",
P: "Sledite tej povezavi, da potrdite posodobitev vašega e-poštnega naslova iz",
To: "v",
Last: ":",
Link: "Spremeni e-poštni naslov"
},
ResetPassword: {
Title: "Ponastavite svoje geslo",
H2: "Ponastavitev gesla",
P: "Sledite tej povezavi, da ponastavite geslo za vašega uporabnika:",
Link: "Ponastavi geslo"
}
},
fi: {
ConfirmSignup: {
Title: "Vahvista rekisteröitymisesi",
H2: "Vahvista rekisteröitymisesi",
P: "Seuraa tätä linkkiä vahvistaaksesi käyttäjäsi:",
Link: "Vahvista sähköposti"
},
InviteUser: {
Title: "Sinut on kutsuttu",
H2: "Olet kutsuttu käyttäjäksi",
PFirstPart: "Olet kutsuttu luomaan käyttäjä",
PSecondPart: "-sivustolle. Seuraa tätä linkkiä hyväksyäksesi kutsun:",
Link: "Hyväksy kutsu"
},
MagicLink: {
Title: "Taikalinkkisi",
H2: "Taikalinkki",
P: "Seuraa tätä linkkiä kirjautuaksesi sisään:",
Link: "Kirjaudu sisään"
},
ChangeEmailAddress: {
Title: "Vahvista sähköpostiosoitteen muutos",
H2: "Vahvista sähköpostiosoitteen muutos",
P: "Seuraa tätä linkkiä vahvistaaksesi sähköpostiosoitteesi päivitys kohteesta",
To: "kohteeseen",
Last: ":",
Link: "Vaihda sähköposti"
},
ResetPassword: {
Title: "Palauta salasanasi",
H2: "Nollaa salasana",
P: "Seuraa tätä linkkiä nollataksesi käyttäjäsi salasanan:",
Link: "Nollaa salasana"
}
},
sv: {
ConfirmSignup: {
Title: "Bekräfta din registrering",
H2: "Bekräfta din registrering",
P: "Följ länken för att bekräfta ditt konto:",
Link: "Bekräfta din e-postadress"
},
InviteUser: {
Title: "Du har blivit inbjuden",
H2: "Du har blivit inbjuden",
PFirstPart: "Du har blivit inbjuden att skapa ett konto på",
PSecondPart: ". Följ länken för att acceptera inbjudan:",
Link: "Acceptera inbjudan"
},
MagicLink: {
Title: "Din magiska länk",
H2: "Magisk länk",
P: "Följ länken för att logga in:",
Link: "Logga in"
},
ChangeEmailAddress: {
Title: "Bekräfta e-postadressändring",
H2: "Bekräfta ändring av e-postadress",
P: "Följ länken för att bekräfta uppdatering av din e-postadress från",
To: "till",
Last: ":",
Link: "Ändra e-postadress"
},
ResetPassword: {
Title: "Återställ ditt lösenord",
H2: "Återställ lösenordet",
P: "Följ länken för att återställa lösenordet för ditt konto:",
Link: "Återställ lösenord"
}
}
}
Hi,
The examples provided helped a lot to improve my multilingual registration email. I tested passing the translations from the client as @kvetoslavnovak described and using conditionals in the Supabase email templates. For now, I settled on a hybrid approach of passing the translated subject along with a ‘language' param via the options data from the client.
1) I struggled at the start as .Data was always empty. Others mentioned this as well. Another thread says data is only sent the first time.
'One caveat though: If the user has already signed up, you can't use the data param to update the user_metadata field.’
In my testing, this is also true even if the user just requested to sign up. I am not sure if this is a feature or a bug but if there is not a good reason for this I think the data should be updated every time. I kept having to delete the newly registered user to continue testing.
2) My solution uses a 'hard coded' plain English subject ‘Confirm Signup to app’ with the translation afterwards. If a TranslatedSubject is not received, only the English will be displayed. See below for an example. I also added a check for no language in the email message body to prevent empty emails… (Not sure if there is a !eq function…)
3) I am not sure why some examples for the client API use 'data’ and some, including the examples on the Supabase website, use options: {data}. Some better documentation about this would be welcome. As an aside it would also help to point out that the data ‘keys’ are case-sensitive.
I also tested including both data and redirect in options. After some trial and error, I got it working as shown below. (I think It helps the onboarding experience to forward new users to a dedicated page.)
4) In the 'Message variables' section on the email Templates page, there is no mention of the '.Data' option. It would be helpful to add an example and explanation there.
Client-side example: (Exclude English as assumed to be the default)
const authEmailsTranslations = {
en: {
},
es: {
ConfirmSignup: {
TranslatedSubject: 'Confirma tu registro'
},
InviteUser: {
TranslatedSubject: 'Has sido invitado'
},
MagicLink: {
TranslatedSubject: 'Tu enlace mágico'
},
ChangeEmailAddress: {
TranslatedSubject: 'Confirma el cambio de correo electrónico'
},
ResetPassword: {
TranslatedSubject: 'Confirma el cambio de correo electrónico'
}
},
fr: {
ConfirmSignup: {
TranslatedSubject: 'Confirmez votre inscription'
},
InviteUser: {
TranslatedSubject: 'Vous avez été invité'
},
MagicLink: {
TranslatedSubject: 'Votre lien magique'
},
ChangeEmailAddress: {
TranslatedSubject: 'Confirmez le changement d'adresse e-mail'
},
ResetPassword: {
TranslatedSubject: 'Réinitialisez votre mot de passe'
}
},
ja: {
ConfirmSignup: {
TranslatedSubject: 'サインアップを確認'
},
InviteUser: {
TranslatedSubject: '招待されました'
},
MagicLink: {
TranslatedSubject: 'マジックリンク'
},
ChangeEmailAddress: {
TranslatedSubject: '電子メール変更の確'
},
ResetPassword: {
TranslatedSubject: 'パスワードをリセット'
}
}
}
/* pass email address, pwd and lang as 2 char locale, i.e. 'es' */
const register = async (email, password, lang) => {
const langMetaData = authEmailsTranslations[lang]
langMetaData.language = lang // add this to use for conditionals on Supabase
// Make sure a matching url is added in the Supabase dashboard
// in Authentication/URL Configuration/Redirect URLs
// Note that window.location is only available for Client-side apps
const redirect = `${window.location.origin}/registered`
const { user, error } = await supabase.auth.signUp({
email,
password,
options: {
data: langMetaData,
emailRedirectTo: redirect
}
})
}
In Supabase dashboard:
Here's an approach that can work for this as well:
Thanks for all the ideas mentioned on how to solve (or rather work around) this, but I would be happy if supabase allowed you to set your own way to compose or send an email (and send it as well).
We have an api in our backend that can send fully localized emails, including subject lines. We have a dedicated git repository for this and we version the templates. Another advantage is that we are then able to see when what email was sent to a user and simply help them with customer care if necessary.
So I would like to basically be able to specify "api url for email delivery" and generate a "webook to confirm sending". Supabase would send the api request to my api, expecting a response about the send on my side (async).
Please consider this option for more advanced use. At the same time, this would open Supabase up to more 3rd-party providers, plugins that could offer their services.
Thanks for all the ideas mentioned on how to solve (or rather work around) this, but I would be happy if supabase allowed you to set your own way to compose or send an email (and send it as well).
We have an api in our backend that can send fully localized emails, including subject lines. We have a dedicated git repository for this and we version the templates. Another advantage is that we are then able to see when what email was sent to a user and simply help them with customer care if necessary.
So I would like to basically be able to specify "api url for email delivery" and generate a "webook to confirm sending". Supabase would send the api request to my api, expecting a response about the send on my side (async).
Please consider this option for more advanced use. At the same time, this would open Supabase up to more 3rd-party providers, plugins that could offer their services.
Yup, we're working on everything mentioned here. It will take a while though.
Here's an approach that can work for this as well:
We are also experiencing issues that .Data
is not available for reset password emails (not only those). I read your article (which I really like) but I still don't see how to translate the reset password email. We just can't seem to be able to pass the lang
param to the template.
Are we missing something?
Here's an approach that can work for this as well: https://blog.mansueli.com/creating-customized-i18n-ready-authentication-emails-using-supabase-edge-functions-postgresql-and-resend
We are also experiencing issues that
.Data
is not available for reset password emails (not only those). I read your article (which I really like) but I still don't see how to translate the reset password email. We just can't seem to be able to pass thelang
param to the template.Are we missing something?
I am also facing this blocker and I don't know how to solve it.
Thanks for all the ideas mentioned on how to solve (or rather work around) this, but I would be happy if supabase allowed you to set your own way to compose or send an email (and send it as well). We have an api in our backend that can send fully localized emails, including subject lines. We have a dedicated git repository for this and we version the templates. Another advantage is that we are then able to see when what email was sent to a user and simply help them with customer care if necessary. So I would like to basically be able to specify "api url for email delivery" and generate a "webook to confirm sending". Supabase would send the api request to my api, expecting a response about the send on my side (async). Please consider this option for more advanced use. At the same time, this would open Supabase up to more 3rd-party providers, plugins that could offer their services.
Yup, we're working on everything mentioned here. It will take a while though.
Awesome to hear, we also have our own templating & sending API internally (because we're also sending additional emails besides the registration emails) and it would make it supa easy, if we could just point GoTrue to an API which implements a few endpoints and then takes care of the emailing part ❤️
(This would also enable us to inline images, so that users can easily see our logo without unblocking image loading on their devices 👍 )
Here's an approach that can work for this as well:
Thanks for sharing @mansueli! Not clear how do you disabled the default supabase email delivery system and how you triggered the function. Can you clear on that?
Thanks!
Here's an approach that can work for this as well: https://blog.mansueli.com/creating-customized-i18n-ready-authentication-emails-using-supabase-edge-functions-postgresql-and-resend
Thanks for sharing @mansueli! Not clear how do you disabled the default supabase email delivery system and how you triggered the function. Can you clear on that?
Thanks!
Also wondering the same
Thanks for sharing @mansueli can you please tell us how to trigger the function and how to translate the reset password email
Here's an approach that can work for this as well:
So, in June 2024, what to do for the internationalization of email templates ? Is there any official/recommended/cleaner way to overcome this issue ?
Hello! I found the solution:
https://supabase.com/docs/guides/auth/auth-hooks/send-email-hook
I have not tried it yet, but I will try it in a few time.
Hey @kulakowka,
Thanks for posting - let us know how that goes or if there are any issues. As a heads up you might need to construct the confirmation URL which isn't stated in the example. We're putting in a fix to reflect that
@J0 I followed the instructions but when the auth webhook called my EdgeFunction, I've got a 401. How can I give the supabase token in headers ? (like I can do in "standard webhooks")
Hey @gregamann,
Thanks and apologies for the delay. Can you turn off the require JWT verification setting? Locally this would be the --no-verify-jwt
flag. It's fine to do so as there's additional verification done through the information passed in the headers
Feature request
Internationalization for Authentication Email Templates
The Authentication Email Templates should be made available for i18n internationalization so you can send an email in any language based on the current language or locale setting.
So instead of having one set of templates, you'd have one set for each language your application supports. I.e. "en", "es", "fr", "de".
To keep existing compatibility you could leave the existing templates alone as the "default templates" but override those with a language-specific version of a language or locale code is set.
Describe alternatives you've considered
The only alternative would be to write a completely separate system, using a third-party email system, to replicate the automated features for password reset, email confirmation, etc.
Additional context
While it's relatively easy to create an internationalized login screen with libraries such as Angular's @ngx-translate/core, it's pretty awkward for a Spanish speaking user to sign up on a Spanish page then get an English confirmation email.