🛠️ VitNode is still in development! You can try it out, but it is not recommended to use it now in production.
🖌️ Themes
Internationalization (i18n)

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
});

Or you can set **maxLength **:

const formSchema = z.object({
  content: zodInput.languageInput
    .min(1, {
      message: t("errors.required")
    })
    .refine(value => value.every(item => item.value.length <= 100), {
      message: t("errors.max_length", { length: 100 })
    })
});

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>