mirror of
https://github.com/lukevella/rallly.git
synced 2025-04-29 18:26:34 +02:00
♻️ Move i18n config (#1418)
This commit is contained in:
parent
a2414ff8ca
commit
641eb13cb6
29 changed files with 80 additions and 92 deletions
|
@ -6,7 +6,7 @@ import {
|
|||
PageHeader,
|
||||
PageTitle,
|
||||
} from "@/app/components/page-layout";
|
||||
import { getTranslation } from "@/app/i18n";
|
||||
import { getTranslation } from "@/i18n/server";
|
||||
|
||||
export default async function Page({ params }: { params: Params }) {
|
||||
const { t } = await getTranslation(params.locale);
|
||||
|
|
|
@ -8,7 +8,7 @@ import {
|
|||
PageHeader,
|
||||
PageTitle,
|
||||
} from "@/app/components/page-layout";
|
||||
import { getTranslation } from "@/app/i18n";
|
||||
import { getTranslation } from "@/i18n/server";
|
||||
|
||||
export default async function Page({ params }: { params: Params }) {
|
||||
const { t } = await getTranslation(params.locale);
|
||||
|
|
|
@ -10,7 +10,7 @@ import {
|
|||
PageIcon,
|
||||
PageTitle,
|
||||
} from "@/app/components/page-layout";
|
||||
import { getTranslation } from "@/app/i18n";
|
||||
import { getTranslation } from "@/i18n/server";
|
||||
|
||||
export default async function Page({ params }: { params: Params }) {
|
||||
const { t } = await getTranslation(params.locale);
|
||||
|
|
|
@ -9,7 +9,7 @@ import {
|
|||
PageIcon,
|
||||
PageTitle,
|
||||
} from "@/app/components/page-layout";
|
||||
import { getTranslation } from "@/app/i18n";
|
||||
import { getTranslation } from "@/i18n/server";
|
||||
|
||||
export default async function Page({
|
||||
params,
|
||||
|
|
|
@ -3,8 +3,8 @@ import { notFound } from "next/navigation";
|
|||
|
||||
import { BillingPage } from "@/app/[locale]/(admin)/settings/billing/billing-page";
|
||||
import { Params } from "@/app/[locale]/types";
|
||||
import { getTranslation } from "@/app/i18n";
|
||||
import { env } from "@/env";
|
||||
import { getTranslation } from "@/i18n/server";
|
||||
|
||||
export default async function Page() {
|
||||
if (env.NEXT_PUBLIC_SELF_HOSTED === "true") {
|
||||
|
|
|
@ -6,7 +6,7 @@ import {
|
|||
PageHeader,
|
||||
PageTitle,
|
||||
} from "@/app/components/page-layout";
|
||||
import { getTranslation } from "@/app/i18n";
|
||||
import { getTranslation } from "@/i18n/server";
|
||||
|
||||
import { SettingsMenu } from "./settings-menu";
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Params } from "@/app/[locale]/types";
|
||||
import { getTranslation } from "@/app/i18n";
|
||||
import { getTranslation } from "@/i18n/server";
|
||||
|
||||
import { PreferencesPage } from "./preferences-page";
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
"use client";
|
||||
import Head from "next/head";
|
||||
|
||||
import { useTranslation } from "@/app/i18n/client";
|
||||
import { DateTimePreferences } from "@/components/settings/date-time-preferences";
|
||||
import { LanguagePreference } from "@/components/settings/language-preference";
|
||||
import {
|
||||
|
@ -10,6 +9,7 @@ import {
|
|||
SettingsSection,
|
||||
} from "@/components/settings/settings";
|
||||
import { Trans } from "@/components/trans";
|
||||
import { useTranslation } from "@/i18n/client";
|
||||
|
||||
export function PreferencesPage() {
|
||||
const { t } = useTranslation();
|
||||
|
|
|
@ -15,8 +15,8 @@ import { Input } from "@rallly/ui/input";
|
|||
import { signOut } from "next-auth/react";
|
||||
import { useForm } from "react-hook-form";
|
||||
|
||||
import { useTranslation } from "@/app/i18n/client";
|
||||
import { Trans } from "@/components/trans";
|
||||
import { useTranslation } from "@/i18n/client";
|
||||
import { usePostHog } from "@/utils/posthog";
|
||||
import { trpc } from "@/utils/trpc/client";
|
||||
|
||||
|
@ -32,7 +32,7 @@ export function DeleteAccountDialog({
|
|||
email: "",
|
||||
},
|
||||
});
|
||||
const { t } = useTranslation("app");
|
||||
const { t } = useTranslation();
|
||||
const trpcUtils = trpc.useUtils();
|
||||
const posthog = usePostHog();
|
||||
const deleteAccount = trpc.user.delete.useMutation({
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Params } from "@/app/[locale]/types";
|
||||
import { getTranslation } from "@/app/i18n";
|
||||
import { getTranslation } from "@/i18n/server";
|
||||
|
||||
import { ProfilePage } from "./profile-page";
|
||||
|
||||
|
|
|
@ -4,11 +4,11 @@ import * as Sentry from "@sentry/nextjs";
|
|||
import React, { useState } from "react";
|
||||
import { z } from "zod";
|
||||
|
||||
import { useTranslation } from "@/app/i18n/client";
|
||||
import { OptimizedAvatarImage } from "@/components/optimized-avatar-image";
|
||||
import { Trans } from "@/components/trans";
|
||||
import { useUser } from "@/components/user-provider";
|
||||
import { IfCloudHosted } from "@/contexts/environment";
|
||||
import { useTranslation } from "@/i18n/client";
|
||||
import { usePostHog } from "@/utils/posthog";
|
||||
import { trpc } from "@/utils/trpc/client";
|
||||
|
||||
|
|
|
@ -3,8 +3,8 @@ import { Trans } from "react-i18next/TransWithoutContext";
|
|||
|
||||
import { LoginForm } from "@/app/[locale]/(auth)/login/login-form";
|
||||
import { Params } from "@/app/[locale]/types";
|
||||
import { getTranslation } from "@/app/i18n";
|
||||
import { AuthCard } from "@/components/auth/auth-layout";
|
||||
import { getTranslation } from "@/i18n/server";
|
||||
|
||||
export default async function LoginPage({ params }: { params: Params }) {
|
||||
const { t } = await getTranslation(params.locale);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { RegisterForm } from "@/app/[locale]/(auth)/register/register-page";
|
||||
import { Params } from "@/app/[locale]/types";
|
||||
import { getTranslation } from "@/app/i18n";
|
||||
import { getTranslation } from "@/i18n/server";
|
||||
|
||||
export default async function Page() {
|
||||
return <RegisterForm />;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { notFound } from "next/navigation";
|
||||
import { z } from "zod";
|
||||
|
||||
import { getTranslation } from "@/app/i18n";
|
||||
import { getTranslation } from "@/i18n/server";
|
||||
|
||||
import { LoginPage } from "./login-page";
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ import { Metadata } from "next";
|
|||
import { notFound } from "next/navigation";
|
||||
|
||||
import { InvitePage } from "@/app/[locale]/invite/[urlId]/invite-page";
|
||||
import { getTranslation } from "@/app/i18n";
|
||||
import { getTranslation } from "@/i18n/server";
|
||||
import { absoluteUrl } from "@/utils/absolute-url";
|
||||
|
||||
export default async function Page() {
|
||||
|
|
|
@ -3,9 +3,9 @@ import { Trans } from "react-i18next/TransWithoutContext";
|
|||
import { GroupPollIcon } from "@/app/[locale]/(admin)/app-card";
|
||||
import { BackButton } from "@/app/[locale]/(admin)/menu/menu-button";
|
||||
import { Params } from "@/app/[locale]/types";
|
||||
import { getTranslation } from "@/app/i18n";
|
||||
import { CreatePoll } from "@/components/create-poll";
|
||||
import { UserDropdown } from "@/components/user-dropdown";
|
||||
import { getTranslation } from "@/i18n/server";
|
||||
|
||||
export default async function Page({ params }: { params: Params }) {
|
||||
const { t } = await getTranslation(params.locale);
|
||||
|
|
|
@ -2,7 +2,7 @@ import { Button } from "@rallly/ui/button";
|
|||
import { FileSearchIcon } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
|
||||
import { getTranslation } from "@/app/i18n";
|
||||
import { getTranslation } from "@/i18n/server";
|
||||
|
||||
export default async function Page() {
|
||||
// TODO (Luke Vella) [2023-11-03]: not-found doesn't have access to params right now
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
"use client";
|
||||
import i18next, { Namespace } from "i18next";
|
||||
import ICU from "i18next-icu";
|
||||
import resourcesToBackend from "i18next-resources-to-backend";
|
||||
import { useParams } from "next/navigation";
|
||||
import React from "react";
|
||||
import {
|
||||
I18nextProvider,
|
||||
initReactI18next,
|
||||
useTranslation as useTranslationOrg,
|
||||
} from "react-i18next";
|
||||
import { useAsync } from "react-use";
|
||||
|
||||
import { defaultNS, getOptions } from "./settings";
|
||||
|
||||
async function initTranslations(lng: string) {
|
||||
const i18n = i18next
|
||||
.use(initReactI18next)
|
||||
.use(ICU)
|
||||
.use(
|
||||
resourcesToBackend(
|
||||
(language: string, namespace: string) =>
|
||||
import(`../../../public/locales/${language}/${namespace}.json`),
|
||||
),
|
||||
);
|
||||
await i18n.init(getOptions(lng));
|
||||
|
||||
return i18n;
|
||||
}
|
||||
|
||||
export function useTranslation(ns?: Namespace) {
|
||||
return useTranslationOrg(ns);
|
||||
}
|
||||
|
||||
export function I18nProvider({ children }: { children: React.ReactNode }) {
|
||||
const params = useParams<{ locale: string }>();
|
||||
const locale = params?.locale ?? defaultNS;
|
||||
|
||||
const res = useAsync(async () => {
|
||||
return await initTranslations(locale);
|
||||
});
|
||||
|
||||
if (!res.value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<I18nextProvider i18n={res.value} defaultNS={defaultNS}>
|
||||
{children}
|
||||
</I18nextProvider>
|
||||
);
|
||||
}
|
|
@ -6,8 +6,8 @@ import { domMax, LazyMotion } from "framer-motion";
|
|||
import { SessionProvider } from "next-auth/react";
|
||||
import { useState } from "react";
|
||||
|
||||
import { I18nProvider } from "@/app/i18n/client";
|
||||
import { UserProvider } from "@/components/user-provider";
|
||||
import { I18nProvider } from "@/i18n/client";
|
||||
import { AppRouter } from "@/trpc/routers";
|
||||
import { ConnectedDayjsProvider } from "@/utils/dayjs";
|
||||
import { trpcConfig } from "@/utils/trpc/config";
|
||||
|
|
|
@ -5,13 +5,13 @@ import { Icon } from "@rallly/ui/icon";
|
|||
import dayjs from "dayjs";
|
||||
import { DotIcon, MapPinIcon, PauseIcon } from "lucide-react";
|
||||
|
||||
import { useTranslation } from "@/app/i18n/client";
|
||||
import TruncatedLinkify from "@/components/poll/truncated-linkify";
|
||||
import VoteIcon from "@/components/poll/vote-icon";
|
||||
import { PollStatusBadge } from "@/components/poll-status";
|
||||
import { RandomGradientBar } from "@/components/random-gradient-bar";
|
||||
import { Trans } from "@/components/trans";
|
||||
import { usePoll } from "@/contexts/poll";
|
||||
import { useTranslation } from "@/i18n/client";
|
||||
|
||||
function IconGuide() {
|
||||
return (
|
||||
|
|
|
@ -23,11 +23,11 @@ import {
|
|||
EmptyStateIcon,
|
||||
EmptyStateTitle,
|
||||
} from "@/app/components/empty-state";
|
||||
import { useTranslation } from "@/app/i18n/client";
|
||||
import { TimesShownIn } from "@/components/clock";
|
||||
import { useVotingForm } from "@/components/poll/voting-form";
|
||||
import { usePermissions } from "@/contexts/permissions";
|
||||
import { usePoll } from "@/contexts/poll";
|
||||
import { useTranslation } from "@/i18n/client";
|
||||
|
||||
import {
|
||||
useParticipants,
|
||||
|
|
|
@ -7,11 +7,11 @@ import { ChevronDownIcon, ChevronUpIcon } from "lucide-react";
|
|||
import * as React from "react";
|
||||
import { useToggle } from "react-use";
|
||||
|
||||
import { useTranslation } from "@/app/i18n/client";
|
||||
import { OptimizedAvatarImage } from "@/components/optimized-avatar-image";
|
||||
import { useParticipants } from "@/components/participants-provider";
|
||||
import { usePoll } from "@/contexts/poll";
|
||||
import { useRole } from "@/contexts/role";
|
||||
import { useTranslation } from "@/i18n/client";
|
||||
|
||||
import { ConnectedScoreSummary } from "../score-summary";
|
||||
import VoteIcon from "../vote-icon";
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Trans as BaseTrans } from "react-i18next";
|
||||
|
||||
import { useTranslation } from "@/app/i18n/client";
|
||||
import { useTranslation } from "@/i18n/client";
|
||||
|
||||
import { I18nNamespaces } from "../../declarations/i18next";
|
||||
|
||||
|
@ -11,6 +11,6 @@ export const Trans = (props: {
|
|||
children?: React.ReactNode;
|
||||
components?: Record<string, React.ReactElement> | React.ReactElement[];
|
||||
}) => {
|
||||
const { t } = useTranslation("app");
|
||||
const { t } = useTranslation();
|
||||
return <BaseTrans ns="app" t={t} {...props} />;
|
||||
};
|
||||
|
|
|
@ -3,11 +3,11 @@ import { Session } from "next-auth";
|
|||
import { useSession } from "next-auth/react";
|
||||
import React from "react";
|
||||
|
||||
import { useTranslation } from "@/app/i18n/client";
|
||||
import { Spinner } from "@/components/spinner";
|
||||
import { useSubscription } from "@/contexts/plan";
|
||||
import { PostHogProvider } from "@/contexts/posthog";
|
||||
import { PreferencesProvider } from "@/contexts/preferences";
|
||||
import { useTranslation } from "@/i18n/client";
|
||||
import { trpc } from "@/utils/trpc/client";
|
||||
|
||||
import { useRequiredContext } from "./use-required-context";
|
||||
|
|
34
apps/web/src/i18n/client.tsx
Normal file
34
apps/web/src/i18n/client.tsx
Normal file
|
@ -0,0 +1,34 @@
|
|||
"use client";
|
||||
import { useParams } from "next/navigation";
|
||||
import React from "react";
|
||||
import {
|
||||
I18nextProvider,
|
||||
useTranslation as useTranslationOrg,
|
||||
} from "react-i18next";
|
||||
import useAsync from "react-use/lib/useAsync";
|
||||
|
||||
import { initI18next } from "./i18n";
|
||||
import { defaultNS } from "./settings";
|
||||
|
||||
export function useTranslation() {
|
||||
return useTranslationOrg("app");
|
||||
}
|
||||
|
||||
export function I18nProvider({ children }: { children: React.ReactNode }) {
|
||||
const params = useParams<{ locale: string }>();
|
||||
const locale = params?.locale ?? defaultNS;
|
||||
|
||||
const res = useAsync(async () => {
|
||||
return await initI18next(locale, "app");
|
||||
});
|
||||
|
||||
if (!res.value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<I18nextProvider i18n={res.value} defaultNS={defaultNS}>
|
||||
{children}
|
||||
</I18nextProvider>
|
||||
);
|
||||
}
|
|
@ -1,13 +1,15 @@
|
|||
import { createInstance, Namespace } from "i18next";
|
||||
import ICU from "i18next-icu";
|
||||
import resourcesToBackend from "i18next-resources-to-backend";
|
||||
import { initReactI18next } from "react-i18next/initReactI18next";
|
||||
|
||||
import { defaultNS, getOptions } from "./i18n/settings";
|
||||
import { getOptions } from "./settings";
|
||||
|
||||
const initI18next = async (lng: string, ns: Namespace) => {
|
||||
export const initI18next = async (lng: string, ns: Namespace) => {
|
||||
const i18nInstance = createInstance();
|
||||
await i18nInstance
|
||||
.use(initReactI18next)
|
||||
.use(ICU)
|
||||
.use(
|
||||
resourcesToBackend(
|
||||
(language: string, namespace: string) =>
|
||||
|
@ -17,14 +19,3 @@ const initI18next = async (lng: string, ns: Namespace) => {
|
|||
.init(getOptions(lng, ns));
|
||||
return i18nInstance;
|
||||
};
|
||||
|
||||
export async function getTranslation(
|
||||
locale: string,
|
||||
ns: Namespace = defaultNS,
|
||||
) {
|
||||
const i18nextInstance = await initI18next(locale, ns);
|
||||
return {
|
||||
t: i18nextInstance.getFixedT(locale, Array.isArray(ns) ? ns[0] : ns),
|
||||
i18n: i18nextInstance,
|
||||
};
|
||||
}
|
16
apps/web/src/i18n/server.ts
Normal file
16
apps/web/src/i18n/server.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
import type { Namespace } from "i18next";
|
||||
|
||||
import { defaultNS } from "@/i18n/settings";
|
||||
|
||||
import { initI18next } from "./i18n";
|
||||
|
||||
export async function getTranslation(
|
||||
locale: string,
|
||||
ns: Namespace = defaultNS,
|
||||
) {
|
||||
const i18nextInstance = await initI18next(locale, ns);
|
||||
return {
|
||||
t: i18nextInstance.getFixedT(locale, Array.isArray(ns) ? ns[0] : ns),
|
||||
i18n: i18nextInstance,
|
||||
};
|
||||
}
|
|
@ -10,7 +10,6 @@ export function getOptions(
|
|||
ns: string | string[] = defaultNS,
|
||||
): InitOptions {
|
||||
return {
|
||||
// debug: true,
|
||||
supportedLngs: languages,
|
||||
fallbackLng,
|
||||
lng,
|
|
@ -11,9 +11,9 @@ import Head from "next/head";
|
|||
import { SessionProvider, signIn, useSession } from "next-auth/react";
|
||||
import React from "react";
|
||||
|
||||
import { I18nProvider } from "@/app/i18n/client";
|
||||
import Maintenance from "@/components/maintenance";
|
||||
import { UserProvider } from "@/components/user-provider";
|
||||
import { I18nProvider } from "@/i18n/client";
|
||||
import { ConnectedDayjsProvider } from "@/utils/dayjs";
|
||||
import { trpc } from "@/utils/trpc/client";
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue