i'm using the following schema
const propertySchema = z.object({
rent_type: z.enum(['rent', 'sell']),
title: z.string().min(10),
typ: z.enum(['house', 'flat', 'garage', 'office', 'hotel']),
price: z.coerce.number().positive(),
area: z.coerce.number().positive(),
rooms: z.coerce.number().positive(),
address: z.string().min(10),
description: z.string().min(20),
beds: z.coerce.number().positive(),
bathrooms: z.coerce.number().positive(),
garage: z.coerce.number(),
constructionYear: z.coerce.number().int().positive().min(1900)
});
and parsing over: const propertyData = propertySchema.safeParse(formData);
in my
+page.server.ts
so far it works great but i wanted to add now translations for the error messages and there is a package called zod-i18n
i'm initiating the i18next as described in the docs in the +layout.server.ts
import i18next from "i18next";
import { z } from "zod";
import { zodI18nMap } from "zod-i18n-map";
// Import your language translation files
import translation from "zod-i18n-map/locales/es/zod.json";
// lng and resources key depend on your locale.
i18next.init({
lng: "es",
resources: {
es: { zod: translation },
},
});
z.setErrorMap(zodI18nMap);
but when i try to parse the error message keeps undefined which looks like its not loading the translation
const schema = z.string().email();
// Translated into Spanish (es)
schema.parse("foo"); // => error.message is undefined
it works when i do the initializing in the +layout.svelte in the onMount()
lifecycle - but how could i get this work server side ?
import i18next from "i18next";
import { z } from 'zod';
import { zodI18nMap } from "zod-i18n-map/dist/index.mjs"; // <-- use mjs version
import translation from "zod-i18n-map/locales/es/zod.json";
await i18next.init({
lng: "es",
ns: "zod",
resources: {
es: { zod: translation },
},
});
z.setErrorMap(zodI18nMap);
I had the same bug and just found a solution. I think the problem is that by default the import takes the zod-i18n-map/dist/index.js and not the index.mjs (at least in my case).
Because of this, the "global" i18n variable isn't the same in the two files. So when zod-i18n is mapping the error, i18next required in index.js try to translate a key, for wich he has no translation since it isn't the same as the i18next that is imported in +layout.server and initialized there.
My IDE (vscode) isn't happy then, saying that there is no module declared (ts error), you just need to add "declare module 'zod-i18n-map/dist/*'" inside the declare global of the app.d.ts file.
Bonus point, in the documentation it is said that i18n should not be initialised multiple times. So the init could be inserted into the hooks.server.js file, outside of the function to be executed once at the startup of the server (just did this so not fully tested).
Hope it helps someone
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With