Replies: 2 comments 5 replies
|
Hey @romankoho 👋 I'm facing a similar issue : I am using i18next with typescript (https://www.i18next.com/overview/typescript) to get intellisense for translations and rely on type safety. Therefore, my translation keys are string literals instead of simple strings : t($ => $['my.key'])To keep static zod schema definitions, I am giving only the keys to my zod errors, for instance : // schema.ts
export const SOME_SCHEMA = z.object({
description: z.string("field.invalid").min(1, "field.required"),
});I then rely on rendering inside components to make sure my translations are recomputed whenever language changes : // component.tsx
return (
{errors.description?.message && (
{t($ => $[errors.description.message]}
})
)This is my best option so far, to keep schemas and i18n decorrelated. I'd need a way to infer the possible types of an error message based on its schema definition : t($ => $[errors.description.message]
// ideal type for message : 'field.invalid' | 'field.required'I expect this to be a bit expensive for ts and computations, but I'd need feedback from the community, or other ideas that also circumvent the issues @romankoho mentions :
Thanks in advance, all 🙏 |
|
Hi I was facing the similar kind of issue, and also wanted translations to be changed as soon as the language change So here is the workaround and it is working perfect for me, however it needs some manual configuration to be done export const USER_SCHEMA_VALIDATION = {
username: z.string().trim().min(1, '_common::username').max(50, '_common::username'),
password: z.string().trim().min(1, '_common::password')
}
/*
Here **_common** is a namespace and **username** is a key in my translation files
en-US > _common.json
{
"username": "Username",
"password": "Password",
"validation_messages": {
"enter_valid": "Enter valid {{text, lowercase}}",
"fix_errors_to_proceed": "Fix errors to proceed",
"is_required": "{{text}} is required",
"max_length": "The maximum length for a {{text, lowercase}} is {{length}}",
"min_length": "{{text}} is too short. Minimum {{length}} characters required",
"must_be_less_than": "{{text}} must be less than {{limit}}",
"must_be_more_than": "{{text}} must be more than {{limit}}",
"must_be_number": "{{text}} must be number"
},
}
*/Below is my code to display error messages ( Can be different at your side, I am using shadcn FieldError component to display error and using Tanstack Form const TranslatedErrors = ({ field }) => {
const { t } = useTranslation(["en-US", "en-GB", "hi-IN"])
const errors = field.state.meta.errors
const modifiedErrors = useMemo(
() =>
errors?.map((issue) => {
let message = issue.message
// If the error is not from translation, return as it is
if (message.indexOf('::') === -1) return { message }
// [0] will be namespace, [1] will be the actual key
const messageBlocks = message.split('::')
const messageFromTranslation = t(($) => $[messageBlocks[1]], {
ns: messageBlocks[0]
})
if (issue.origin === 'number') {
if (issue.code === 'too_small') {
message = t(($) => $.validation_messages.must_be_more_than, {
text: messageFromTranslation,
limit: issue.minimum
})
} else if (issue.code === 'too_big') {
message = t(($) => $.validation_messages.must_be_less_than, {
text: messageFromTranslation,
limit: issue.maximum
})
}
} else if (issue.origin === 'string') {
if (issue.code === 'too_small') {
message = t(($) => $.validation_messages.is_required, {
text: messageFromTranslation
})
} else if (issue.code === 'too_big') {
message = t(($) => $.validation_messages.max_length, {
text: messageFromTranslation,
length: issue.maximum
})
} else if (issue.code === 'invalid_format') {
message = t(($) => $.validation_messages.enter_valid, {
text: messageFromTranslation
})
}
}
return { message }
}),
[t]
)
return <FieldError errors={modifiedErrors} />
}I hope this helps
Let's connect on |
Uh oh!
There was an error while loading. Please reload this page.
The error message type is limited to being a string.
This makes things complicated when it comes to localization of error messages in combination with resolvers and form libraries like react-hook-form.
There was basically the same discussion in the yup repository:
https://github.com/orgs/react-hook-form/discussions/3808#discussioncomment-2150621
@balzdur summarized it pretty well.
there are these two issues:
The goal would be to do the translation at the very last moment when it comes to rendering / declaring the JSX
All reactions