I have the same problem with this solution, where the i18n message didn’t load before the Zod schema definitions. So I tried a quick and simple way, and it works.
We can define the schemas as functions, so whenever the form loads the schema, we can ensure that i18n is loaded. For example, for the login page, we can have this:
const emailSchema = () =>
z
.string({
required_error: requiredDefaultMessage(i18n?.t("settings:email")),
})
.min(1, requiredDefaultMessage(i18n?.t("settings:email")))
.email(i18n?.t("common:validation.email_invalid"));
const MIN_PASSWORD_LENGTH = 8;
const passwordSchema = () =>
z.string().min(
MIN_PASSWORD_LENGTH,
i18n?.t("validation.min_limit", {
name: i18n?.t("settings:password"),
min: MIN_PASSWORD_LENGTH,
})
);
/**
* login form schema
*/
export const loginFormSchema = () =>
z.object({
email: emailSchema(),
password: passwordSchema(),
});
and in login page we can use this schema by:
export type LoginFormValuesType = z.infer<ReturnType<typeof loginFormSchema>>;
export const useLogin = () => {
const methods = useForm<LoginFormValuesType>({
resolver: zodResolver(loginFormSchema()),
mode: "onSubmit",
});
...
}