Next-translate error when trying to send mail via Resend
Unanswered
West African Lion posted this in #help-forum
West African LionOP
Hey there.
I've been trying to send mails with Resend in my Next.js app. So far so good, it works with "raw data".
But then I've tried to enhance my templates with translations, reusing my already in place next-translate.
At first, I've added at the beginning of my template a
I've tried to replace it by
I wanted to try the getT method as well, but I haven't even been able to load a translation in local with this method.
Am I missing something, is there a common way to achieve this?
I've been trying to send mails with Resend in my Next.js app. So far so good, it works with "raw data".
But then I've tried to enhance my templates with translations, reusing my already in place next-translate.
At first, I've added at the beginning of my template a
useTranslationwhich I believed was working server-side despite its hook name, but it crashed the whole process.I've tried to replace it by
createTranslation, and while working in local, it does not work in prod. By looking at vercel logs once deployed, I haveTypeError: Cannot read properties of undefined (reading 'localesToIgnore')I wanted to try the getT method as well, but I haven't even been able to load a translation in local with this method.
Am I missing something, is there a common way to achieve this?
32 Replies
@West African Lion Hey there.
I've been trying to send mails with Resend in my Next.js app. So far so good, it works with "raw data".
But then I've tried to enhance my templates with translations, reusing my already in place next-translate.
At first, I've added at the beginning of my template a `useTranslation `which I believed was working server-side despite its hook name, but it crashed the whole process.
I've tried to replace it by `createTranslation`, and while working in local, it does not work in prod. By looking at vercel logs once deployed, I have
TypeError: Cannot read properties of undefined (reading 'localesToIgnore')
I wanted to try the getT method as well, but I haven't even been able to load a translation in local with this method.
Am I missing something, is there a common way to achieve this?
useTranslation should work fine on the serverside as you can [see here](https://github.com/aralroca/next-translate/blob/master/examples/with-app-directory/src/app/layout.tsx#L10).Keep in mind to check if there is a language as well. As we haven't seen any code nor structure from you, I can only guess where the error comes from
Original message was deleted
thanks for sharing all the files. We might need them later. Can you share the specific errors & issues that you got, that you described like
but it crashed the whole process.
@B33fb0n3 thanks for sharing all the files. We might need them later. Can you share the specific errors & issues that you got, that you described like
> but it crashed the whole process.
West African LionOP
Once deployed, the
And from what I've seen no further useful log.
Like I said, replacing by
send-otp route returns a 500 error with, within Vercel logs, this displayed:⨯ TypeError: Cannot read properties of null (reading 'useContext')And from what I've seen no further useful log.
Like I said, replacing by
createTranslation just gives another error about an undefined property, trying to read localesToIgnore (from what I've seen on https://github.com/aralroca/next-translate/blob/master/src/createTranslation.tsx it means that config is not defined, but anyways if useTranslation is supposed to be working I'd be fine with any solution)@West African Lion Once deployed, the `send-otp` route returns a 500 error with, within Vercel logs, this displayed:
⨯ TypeError: Cannot read properties of null (reading 'useContext')
And from what I've seen no further useful log.
Like I said, replacing by `createTranslation` just gives another error about an `undefined` property, trying to read `localesToIgnore` (from what I've seen on https://github.com/aralroca/next-translate/blob/master/src/createTranslation.tsx it means that `config` is not defined, but anyways if `useTranslation` is supposed to be working I'd be fine with any solution)
can you comment out the red line and add this to the green line:
Are you able to access the translations?
const { t } = useTranslation('emails');Are you able to access the translations?
@B33fb0n3 can you comment out the red line and add this to the green line:
tsx
const { t } = useTranslation('emails');
Are you able to access the translations?
West African LionOP
Is the goal to check if it crashes prod as well? Locally, it works of course
@West African Lion Is the goal to check if it crashes prod as well? Locally, it works of course
I think it only crashes in prod, right?
@B33fb0n3 I think it only crashes in prod, right?
West African LionOP
yep, just verified it was working locally, but it's being deployed atm
@B33fb0n3 I think it only crashes in prod, right?
West African LionOP
Same error logged in Vercel:
⨯ TypeError: Cannot read properties of null (reading 'useContext')
at t.useContext (/var/task/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:183619)
at /var/task/.next/server/app/api/auth/send-otp/route.js:1:6618
at u (/var/task/.next/server/app/api/auth/send-otp/route.js:1:6699)
at d (/var/task/.next/server/app/api/auth/send-otp/route.js:1:1455)
at /var/task/node_modules/@sentry/nextjs/build/cjs/common/wrapRouteHandlerWithSentry.js:59:44
at Object.handleCallbackErrors (/var/task/node_modules/@sentry/core/build/cjs/utils/handleCallbackErrors.js:26:26)
at /var/task/node_modules/@sentry/nextjs/build/cjs/common/wrapRouteHandlerWithSentry.js:58:47
at /var/task/node_modules/@sentry/opentelemetry/build/cjs/index.js:870:15
at Object.handleCallbackErrors (/var/task/node_modules/@sentry/core/build/cjs/utils/handleCallbackErrors.js:26:26)
at /var/task/node_modules/@sentry/opentelemetry/build/cjs/index.js:869:19As expected, just wrapped the code in the POST method:
And the first one is displayed, then it crashes
console.log('will init t from useTranslation "hook"');
const { t } = useTranslation('emails');
console.log('send-otp translate ', t('otp.isYourLoginCode'));And the first one is displayed, then it crashes
@B33fb0n3 hm pretty weird. Looks like it's a vercel limitation 🤔
West African LionOP
Maybe. I was thinking another ugly-ish solution which would just be to translate manually?
Since it's working for the whole application except mails, maybe creating a
Since it's working for the whole application except mails, maybe creating a
public/locales/XX/emails.json and then importing the json file in templates for direct use (considering I have the locale to do the right dynamic import?) would work... idk@West African Lion Maybe. I was thinking another ugly-ish solution which would just be to translate manually?
Since it's working for the whole application except mails, maybe creating a `public/locales/XX/emails.json` and then importing the json file in templates for direct use (considering I have the locale to do the right dynamic import?) would work... idk
yea.. what do you think about sending the (already translated) texts directly to the route handler? And then read it from the body of the route handler? Woudln't that work?
@B33fb0n3 yea.. what do you think about sending the (already translated) texts directly to the route handler? And then read it from the body of the route handler? Woudln't that work?
West African LionOP
You mean since translations are available on client, I could send them to the route handler from there?
If that's what you meant, then I'd have 2 concerns:
- Increased payload / traffic weight w/ translated texts
- Other use cases that would still be problematic, e.g. when stripe webhooks are triggered, there's no client side hence I'll still have to deal with translations in the backend
If that's what you meant, then I'd have 2 concerns:
- Increased payload / traffic weight w/ translated texts
- Other use cases that would still be problematic, e.g. when stripe webhooks are triggered, there's no client side hence I'll still have to deal with translations in the backend
Increased payload / traffic weight w/ translated textsof couse it would be a bit more. However not really that much more (you don't send the whole file. Only the parts that are needed)
Other use cases that would still be problematic, e.g. when stripe webhooks are triggered, there's no client side hence I'll still have to deal with translations in the backendhow do you expect rn the backend knows which language the output should be?
@B33fb0n3 > Increased payload / traffic weight w/ translated texts
of couse it would be a bit more. However not really that much more (you *don't* send the whole file. Only the parts that are needed)
> Other use cases that would still be problematic, e.g. when stripe webhooks are triggered, there's no client side hence I'll still have to deal with translations in the backend
how do you expect rn the backend knows which language the output should be?
West African LionOP
Yeah that's right, template are not that heavy but I guess it always counts.
From what I've browsed in the payload sent by stripe, there are several leads I can exploit
- The country within customer address that could be normalized and used somehow (e.g. transform FR into fr and such); could be problematic if lots of countries are not tied to a language
- Another lead which seems better, the return url. Since routing includes the lang within the app, the return url sent back by stripe contains the locale that was used during checkout.
From what I've browsed in the payload sent by stripe, there are several leads I can exploit
- The country within customer address that could be normalized and used somehow (e.g. transform FR into fr and such); could be problematic if lots of countries are not tied to a language
- Another lead which seems better, the return url. Since routing includes the lang within the app, the return url sent back by stripe contains the locale that was used during checkout.
More generally of course, if I ever needed more mails to be sent from the BE, I'd have to store the user's locale in db or something similar... But that's not in the plans for now, not sure if I should anticipate that.
@West African Lion More generally of course, if I ever needed more mails to be sent from the BE, I'd have to store the user's locale in db or something similar... But that's not in the plans for now, not sure if I should anticipate that.
yea and that may be the issue, that next-translate is facing right now. He doesn't have a context and also can't create a context
@B33fb0n3 yea and that may be the issue, that next-translate is facing right now. He doesn't have a context and also can't create a context
West African LionOP
Probably. I need to see if my leads can solve that, or... send mails in english for now 🫠
@West African Lion Probably. I need to see if my leads can solve that, or... send mails in english for now 🫠
yea, try to initialize your dict with a language code and then use the translations from that. That's why I like to use the nextjs integrated internationalization system as it's soooo easy:
@B33fb0n3 yea, try to initialize your dict with a language code and then use the translations from that. That's why I like to use the nextjs integrated internationalization system as it's soooo easy:
West African LionOP
I don't know much about next i18n system tbh (if there's something besides routing), I'll take a look at that, ty 👌
@B33fb0n3 Sure thing. For reference: https://nextjs.org/docs/app/building-your-application/routing/internationalization
West African LionOP
Oh that's a similar idea in the end, it's cool. Maybe simpler or more explicit than mine. I've implemented it like this in my email.ts file:
A bit more verbose since it's a switch rather than an object, but there's a fallback language 🤔
Haven't dived much deeper to see important differences w/ what's suggested on the page
export const loadEmailTranslations = async (lang: string) => {
// Cannot be dynamic or files will not be included in the bundle
switch (lang) {
case 'en':
return (await import('@/locales/en/emails.json')).default;
case 'fr':
return (await import('@/locales/fr/emails.json')).default;
default:
return (await import('@/locales/en/emails.json')).default;
}
};A bit more verbose since it's a switch rather than an object, but there's a fallback language 🤔
Haven't dived much deeper to see important differences w/ what's suggested on the page
@West African Lion Oh that's a similar idea in the end, it's cool. Maybe simpler or more explicit than mine. I've implemented it like this in my email.ts file:
js
export const loadEmailTranslations = async (lang: string) => {
// Cannot be dynamic or files will not be included in the bundle
switch (lang) {
case 'en':
return (await import('@/locales/en/emails.json')).default;
case 'fr':
return (await import('@/locales/fr/emails.json')).default;
default:
return (await import('@/locales/en/emails.json')).default;
}
};
A bit more verbose since it's a switch rather than an object, but there's a fallback language 🤔
Haven't dived much deeper to see important differences w/ what's suggested on the page
yea, it's similar to the
getDirectories function from i18n of nextjs itself. Rename it, so it can be served as this@B33fb0n3 yea, it's similar to the getDirectories function from i18n of nextjs itself. Rename it, so it can be served as this
West African LionOP
Is it possible that it broke something somehow?
A page that is not using the [lang] slug now crashes
A page that is not using the [lang] slug now crashes
@West African Lion Is it possible that it broke something somehow?
A page that is not using the [lang] slug now crashes
don't you have a fallback value?
West African LionOP
Nvm I don't see what it could be linked to, since error also happens in local and it seems to be located on
Which is weird since I haven't touched it for 2 months. Somehow latest changes broke this, or at least it explodes there...
const redisClientSingleton = () => {
return new Redis({
url: process.env.UPSTASH_REDIS_REST_URL,
token: process.env.UPSTASH_REDIS_REST_TOKEN,
});
};Which is weird since I haven't touched it for 2 months. Somehow latest changes broke this, or at least it explodes there...
@B33fb0n3 don't you have a fallback value?
West African LionOP
I don't even need next-translate on this page, so there's nothing requested and everything was working fine until... now
https://console.upstash.com/redis
Idk why it seems broken for me.
Idk why it seems broken for me.
If there was an issue on their side it would be an explanation but eh
If I would be in your situation I would migrate to next's default i18n system. I hate to have these kind of "unfixable" errors
West African LionOP
I hate them too yeah...