Internationalization (i18n)
VitNode uses not only native i18n form next-intl (opens in a new tab), but also translations from database. It gives your full control for your translations without restart your server.
Each translations are stored in database as array
.
[
{
language_code: "en",
value: "Hello world"
},
{
language_code: "pl",
value: "Witaj świecie"
}
];
Display text
To display text you can use useTextLang
hook.
import { useTextLang } from "@/hooks/core/use-text-lang";
const { convertText } = useTextLang();
const text = convertText(value);
value
is TextLanguage[]
interface form GraphQL backend
.
Form
Create form with translations is very similar to normal Forms.
Define schema
import * as z from "zod";
import { zodInput } from "@/functions/zod";
const formSchema = z.object({
name: zodInput.languageInput
});
You can add more functions to validate translations.
import * as z from "zod";
import { zodInput } from "@/functions/zod";
const formSchema = z.object({
name: z
.array(
z.object({
language_code: zodInput.string,
value: zodInput.string.min(3).max(50)
})
)
.min(1)
});
We're using zodInput.string
instead of z.string
to add more functions to validate translations.
Set initial values
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
name: []
}
});
Choose input
import { TextLanguageInput } from "@/components/text-language-input";
<TextLanguageInput {...field} />;
Create form field
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem>
<FormLabel>{t("name.label")}</FormLabel>
<FormControl>
<TextLanguageInput {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<Button
disabled={!form.formState.isValid}
loading={form.formState.isSubmitting}
type="submit"
>
{tCore("create")}
</Button>
</form>
</Form>