我已经本地化了世界上最好的短链接平台

2025-05-28

我已经本地化了世界上最好的短链接平台

在Tolgee的开发过程中,我尝试将一家知名开源公司 dub.co 的网站翻译成其他语言!我花了 1 个小时,结果令人惊喜!

结果


在本教程中,我将引导您使用Tolgee(一个专为快速自主翻译管理而设计的平台)在 Next.js 应用程序中进行简单有效的本地化方法。

您还将学习如何将 Tolgee 与Dub.co集成,Dub.co 是一个流行的链接管理平台,允许用户以他们喜欢的语言访问和与应用程序交互。

先决条件

要完全理解本教程,您需要对 React 或 Next.js 有基本的了解。

您还需要设置以下内容:

  • Tolgee 项目——一个至少有两种语言翻译的现有项目。
  • Tolgee CLI - 允许您使用命令行从计算机与 Tolgee 平台进行交互。
  • Docker - 运行 Dub.co 所必需的。它是一个开源平台,利用容器化技术,简化应用程序的创建、部署和运行。
  • Docker Compose——用于定义和运行多容器 Docker 应用程序的软件应用程序。
  • Python(3.8 或更高版本):配置 Dub.co 的一些包所必需的。

Tolgee 是什么?

Tolgee 是一个开发者友好的本地化平台,它允许您在不修改代码的情况下将应用程序翻译成任何语言。它专为 Web 应用程序设计,但也支持移动和桌面应用程序。

使用 Tolgee,您无需在源代码中查找关键字、编辑本地化文件或手动导出译员数据。Tolgee 提供上下文翻译、用于跟踪已翻译字符串的翻译记忆库、机器翻译和自动翻译等众多功能。

托尔吉特色

请帮我们加一颗星。🥹

这将有助于我们创作更多这样的文章💖

为 Tolgee 仓库加星标 ⭐


如何在本地计算机上设置 Dub.co

Dub.co 是一个开源链接管理平台,允许营销团队为其链接添加强大的分析功能、创建短链接、为链接生成二维码等等。它由 Steven Tey(前 Vercel 员工)创建。

请按照以下步骤在您的计算机上设置 Dub.co:

通过运行下面的代码片段克隆Dub.co GitHub 存储库。

git clone https://github.com/dubinc/dub.git
Enter fullscreen mode Exit fullscreen mode

导航到dub文件夹并安装项目依赖项:

pnpm install
Enter fullscreen mode Exit fullscreen mode

在文件夹中 apps/web ,将 .env.example 文件重命名为 .env

创建一个新的 Tinybird 帐户,并将您的复制 Admin Auth Token 到 .env 文件中。

TINYBIRD_API_KEY=<your_admin_auth_token>
Enter fullscreen mode Exit fullscreen mode

导航到 packages/tinybird 目录并使用以下命令安装 Tinybird CLI:

pip3 install tinybird-cli
Enter fullscreen mode Exit fullscreen mode

在终端中执行以下命令,并在提示使用 Tinybird CLI 进行身份验证时输入您的管理员身份验证令牌:

tb auth
Enter fullscreen mode Exit fullscreen mode

通过运行以下代码片段发布 Tinybird 数据源和端点:

tb push
Enter fullscreen mode Exit fullscreen mode

创建一个 Upstash 数据库 并将以下凭据从 REST API 部分复制到 .env 文件中:

UPSTASH_REDIS_REST_URL=<your_rest_url>
UPSTASH_REDIS_REST_TOKEN=<your_rest_token>
Enter fullscreen mode Exit fullscreen mode

导航到 QStash 选项卡 并将以下凭据复制到 .env 文件中。

QSTASH_TOKEN=
QSTASH_CURRENT_SIGNING_KEY=
QSTASH_NEXT_SIGNING_KEY=
Enter fullscreen mode Exit fullscreen mode

接下来,在 apps/web 目录中运行以下命令来启动 Docker Compose 堆栈:

docker-compose up
Enter fullscreen mode Exit fullscreen mode

使用以下命令生成 Prisma 客户端并创建其数据库表:

npx prisma generate
npx prisma db push
Enter fullscreen mode Exit fullscreen mode

Dub.co 支持多种身份验证方法。 创建一个 GitHub 应用 ,并复制以下 URL 作为其回调 URL。

http://localhost:8888/api/auth/callback/github
Enter fullscreen mode Exit fullscreen mode

最后,启动开发服务器:

pnpm dev
Enter fullscreen mode Exit fullscreen mode

您可以通过浏览器访问 Web 应用程序 http://localhost:8888 ,创建工作区并开始使用。如果您遇到任何问题,请参阅 完整的安装指南 以获取更详细的帮助。

Dub.co 概述


如何在 Next.js 应用程序中配置 Tolgee

在本节中,您将学习如何将 Tolgee 添加到 Next.js 应用程序并将其配置为支持多种语言,从而允许用户使用他们喜欢的语言访问该应用程序。

要在 Next.js 应用程序中实现本地化,您需要安装Tolgee React SDK

npm install @tolgee/react
Enter fullscreen mode Exit fullscreen mode

接下来,创建一个Tolgee 平台帐户并登录您的仪表板。

Tolgee 仪表板

点击“项目”按钮,选择项目所需的语言,即可添加新项目。在本应用中,我们将使用五种语言:英语(作为基础语言)、中文、印地语、西班牙语和阿拉伯语。

可用的语言翻译

单击仪表板右上角的个人资料图标,然后选择项目 API 密钥为您的 Tolgee 项目创建 API 密钥。

Tolgee 项目 API 密钥

创建.env.development.local并将您的 API 密钥复制到文件中:

NEXT_PUBLIC_TOLGEE_API_KEY=<paste_your_API_key_here>
NEXT_PUBLIC_TOLGEE_API_URL=https://app.tolgee.io
Enter fullscreen mode Exit fullscreen mode

从侧边栏菜单中选择“翻译”,然后将新翻译添加到项目中。

添加新翻译

您可以创建一个翻译键,添加您需要翻译的内容或字符串,提供描述,然后保存。

创建新的翻译键

Tolgee 默认提供各种机器翻译选项,让您可以轻松地将内容翻译成项目中可用的语言。

使用 Tolgee 翻译内容

恭喜!您已成功在应用程序中设置 Tolgee 平台进行翻译。接下来,让我们在 Dub.co 项目中配置 Tolgee,以便直接在应用程序中轻松生成翻译。

如何在 Dub.co 中设置本地化

在本节中,我将指导您配置 Tolgee 以支持 Dub.co 项目内的客户端-服务器交互。

首先,安装Tolgee CLI包。

npm install --global @tolgee/cli
Enter fullscreen mode Exit fullscreen mode

运行以下代码片段,使用您的项目 API 密钥登录您的 Tolgee 平台。

tolgee login <your_tolgee_api_key>
Enter fullscreen mode Exit fullscreen mode

Tolgee CLI 登录

i18n接下来,在目录中创建一个文件夹apps/web。该文件夹将存储包含 Tolgee 平台项目中各种语言翻译的 JSON 文件。

apps
├── web #👈🏼 this folder
    ├── app 
    ├── i18n  #👈🏼 newly created 
packages
├── tailwind-config
├── tinybird
├── tsconfig
├── ui
├── utils
Enter fullscreen mode Exit fullscreen mode

在目录中apps/web,通过运行以下代码片段来获取在 Tolgee 项目中创建的语言翻译:

tolgee --project-id <tolgee_platform_project_id> pull --path ./i18n
Enter fullscreen mode Exit fullscreen mode

Tolgee 项目 ID

上面的代码片段会自动将i18nTolgee 平台内创建的各种语言翻译填充到文件夹中。

apps
├── web 
    ├── app 
    ├── i18n #👇🏻 translation files
        ├── ar.json
        ├── en.json
        ├── es.json 
        ├── zh.json  
packages
├── tailwind-config
├── tinybird
├── tsconfig
├── ui
├── utils
Enter fullscreen mode Exit fullscreen mode

创建一个tolgee文件夹,其中包含apps/web目录中的 Tolgee 配置:

apps
├── web # 👈🏼 this folder
    ├── app 
    ├── i18n  
    ├── tolgee # 👈🏼 Tolgee folder
packages
├── tailwind-config
├── tinybird
├── tsconfig
├── ui
├── utils
Enter fullscreen mode Exit fullscreen mode

在目录中添加一个shared.ts文件tolgee,然后将以下代码片段复制到文件中:

import { FormatIcu } from "@tolgee/format-icu";
import { DevTools, Tolgee } from "@tolgee/react";

const apiKey = process.env.NEXT_PUBLIC_TOLGEE_API_KEY;
const apiUrl = process.env.NEXT_PUBLIC_TOLGEE_API_URL;

//👇🏻 available translations
export const ALL_LOCALES = ["en", "ar", "es", "zh"];

//👇🏻 default translation
export const DEFAULT_LOCALE = "en";

//👇🏻 returns an object containing the translation files
export async function getStaticData(languages: string[]) {
  const result: Record<string, any> = {};

  for (const lang of languages) {
    result[lang] = (await import(`../i18n/${lang}.json`)).default;
  }

  return result;
}

export function TolgeeBase() {
  return Tolgee().use(FormatIcu()).use(DevTools()).updateDefaults({
    apiKey,
    apiUrl,
    fallbackLanguage: "en",
    defaultLanguage: DEFAULT_LOCALE,
  });
}
Enter fullscreen mode Exit fullscreen mode

上面的代码片段使用默认和后备语言配置 Tolgee,以在应用程序内实现本地化。

接下来,在目录中创建一个client.tsx文件tolgee,然后将下面的代码片段复制到文件中:

'use client';

import { TolgeeBase } from './shared';
import { TolgeeProvider, useTolgeeSSR } from '@tolgee/react';
import { useRouter } from 'next/navigation';
import { useEffect } from 'react';

type Props = {
  locales: any;
  locale: string;
  children: React.ReactNode;
};

const tolgee = TolgeeBase().init();

export const TolgeeNextProvider = ({ locale, locales, children }: Props) => {
  const tolgeeSSR = useTolgeeSSR(tolgee, locale, locales);
  const router = useRouter();

  useEffect(() => {
    const { unsubscribe } = tolgeeSSR.on('permanentChange', () => {
      router.refresh();
    });

    return () => unsubscribe();
  }, [tolgeeSSR, router]);

  return (
    <TolgeeProvider
      tolgee={tolgeeSSR}
      options={{ useSuspense: false }}
      fallback="Loading"
    >
      {children}
    </TolgeeProvider>
  );
};
Enter fullscreen mode Exit fullscreen mode

client.tsx文件用于翻译客户端组件,并启用服务器渲染组件的上下文功能。上面的代码片段定义了一个TolgeeNextProvider组件,它包装了整个 Dub.co 应用程序,提供了管理语言更改和翻译所需的配置。

在文件夹中创建一个自定义locale.ts文件tolgee并将以下代码片段复制到其中:

"use server";

import { cookies, headers } from "next/headers";
import { ALL_LOCALES, DEFAULT_LOCALE } from "./shared.ts";

const COOKIE_NAME = "NEXT_LOCALE";

//👇🏻 Retrieves the current language setting for the user.
// If not set, it attempts to detect the user's language from browser preferences.
// Defaults to the application's default locale if no match is found.
export async function getUserLocale() {
  return (
    cookies().get(COOKIE_NAME)?.value || detectLanguage() || DEFAULT_LOCALE
  );
}

//👇🏻 Sets the user’s preferred language in a cookie to persist their selection.
export async function setUserLocale(locale: string) {
  cookies().set(COOKIE_NAME, locale);
}

//👇🏻 Attempts to detect the user's preferred language based on browser settings.
const detectLanguage = () => {
  const allPreferred = getAcceptedLanguages();

  for (const language of allPreferred) {
    // Checks for an exact match in the list of supported locales
    const exactMatch = ALL_LOCALES.find((l) => l === language);
    if (exactMatch) {
      return exactMatch;
    }

    // Falls back to matching only the two-letter language code
    const getTwoLetters = (fullTag: string) =>
      fullTag.replace(/^(.+?)(-.*)?$/, "$1");

    const preferredTwoLetter = getTwoLetters(language);
    const twoLetterMatch = ALL_LOCALES.find(
      (l) => getTwoLetters(l) === preferredTwoLetter,
    );
    if (twoLetterMatch) {
      return twoLetterMatch;
    }
  }
};

//👇🏻 Retrieves accepted languages from the "Accept-Language" HTTP header.
// Returns an array of languages in order of preference.
function getAcceptedLanguages() {
  const acceptLanguageHeader = getAcceptLanguageHeader();
  if (!acceptLanguageHeader) {
    return [];
  }

  // Splits the header value by commas to separate each language code
  return acceptLanguageHeader.split(",").map((lang) => {
    const [language] = lang.split(";");
    return language.trim();
  });
}

//👇🏻 Fetches the "Accept-Language" HTTP header from the user's browser.
// This header lists languages preferred by the user, ranked by preference.
function getAcceptLanguageHeader() {
  return headers().get("Accept-Language");
}
Enter fullscreen mode Exit fullscreen mode

最后,在文件夹server.tsx中创建一个文件tolgee,然后将以下代码片段复制到文件中:

import { getUserLocale } from "./locale.ts";
import { TolgeeBase, ALL_LOCALES, getStaticData } from './shared';
import { createServerInstance } from '@tolgee/react/server';

export const { getTolgee, getTranslate, T } = createServerInstance({
   getLocale: async () => getUserLocale(),
  createTolgee: async (locale) =>
    TolgeeBase().init({
      // including all locales
      // on server we are not concerned about bundle size
      staticData: await getStaticData(ALL_LOCALES),
      observerOptions: {
        fullKeyEncode: true,
      },
      language: locale,
      fetch: async (input, init) => {
        const data = await fetch(input, { ...init, next: { revalidate: 0 } });
        return data;
      },
    }),
});
Enter fullscreen mode Exit fullscreen mode

该应用程序利用 React 服务器缓存在单次渲染中跨组件共享 Tolgee 实例。这使得应用程序可以在服务器组件中的任何位置使用 Tolgee 实例。

恭喜!您已成功配置 Tolgee,现在可以开始为应用程序内的各种内容添加翻译了。


如何使用 Tolgee 翻译您的应用程序内容

在这里,您将了解如何在 Web 应用程序中翻译内容,并了解 Tolgee 如何实现轻松的应用内翻译。

首先,您需要使用TolgeeNextProvider中定义的组件包装整个 Dub.co 应用程序tolgee/client.tsx。导航到apps/web/app文件夹,然后转到app.dub.co/(dashboard)目录,并更新layout.tsx文件,如下所示:

import { MainNav } from "@/ui/layout/main-nav";
import { HelpButtonRSC } from "@/ui/layout/sidebar/help-button-rsc";
import Toolbar from "@/ui/layout/toolbar/toolbar";
import { constructMetadata } from "@dub/utils";
import { ReactNode } from "react";
import Providers from "../../providers";
//👇🏻 Tolgee imports
import { TolgeeNextProvider } from "../../../tolgee/client.tsx";
import { getUserLocale } from "../../../tolgee/locale.ts";
import { getStaticData } from "../../../tolgee/shared.ts";


export const metadata = constructMetadata();

export default async function Layout({ children }: { children: ReactNode }) {
  const locale = await getUserLocale();
  const locales = await getStaticData([locale, "en"]);

  return (
    <TolgeeNextProvider locale={locale} locales={locales}>
      <Providers>
        <div className="min-h-screen w-full bg-white">
          <MainNav toolContent={<HelpButtonRSC />}>{children}</MainNav>
        </div>
        {/* <ChangelogPopup /> */}
        <Toolbar show={["onboarding"]} />
      </Providers>
    </TolgeeNextProvider>
  );
}
Enter fullscreen mode Exit fullscreen mode

上面的代码片段将仪表板路由与 Tolgee 提供程序包装在一起,从而实现整个应用程序的语言切换和本地化。

Tolgee 提供了两个钩子来帮助您在应用程序中选择和翻译文本:useTolgeeuseTranslate

  • useTolgee钩子返回 Tolgee 实例,允许您订阅在翻译文本时触发重新渲染的各种事件。
  • useTranslate钩子包含一个翻译函数(t函数),该函数直接在应用程序内呈现实际的翻译。

通过添加以下代码片段来更新目录page.tsx中的文件:app.dub.co/(dashboard)/[slug]

"use client";
import { PageContent } from "@/ui/layout/page-content";
import WorkspaceLinksClient from "./page-client";
//👇🏻 Tolgee installations
import { useTolgee, useTranslate } from "@tolgee/react";
import { setUserLocale } from "tolgee/locale";


export default function WorkspaceLinks() {
  const { t } = useTranslate();
  const tolgee = useTolgee(["pendingLanguage"]);
  const language = tolgee.getPendingLanguage();

  return (
    <PageContent title="Links">
    {/** -- HTML input for selecting the preferred language -- */}
      <div className="flex w-full flex-col px-10">
        <p>Select Language</p>
        <select
          defaultValue={language}
          className="rounded-sm"
          name="locale"
          id="locale"
          onChange={(e) => setUserLocale(e.currentTarget.value)}
        >
          <option value="en">English</option>
          <option value="es">Spanish</option>
          <option value="ar">Arabic</option>
          <option value="zh">Chinese</option>
        </select>

        <p>{t("hello")}</p>
      </div>
    {/** -- end of Tolgee -- */}
      <WorkspaceLinksClient />
    </PageContent>
  );
}
Enter fullscreen mode Exit fullscreen mode

上面的代码片段显示了一个 HTML<select>标签,允许用户选择和切换不同的语言。该{t("hello")}元素使用 Tolgee 的翻译功能,根据所选语言渲染“hello”键的值。

托尔吉翻译公司在行动

最后,您可以更新整个应用程序中的剩余内容以支持语言变化,从而允许用户以他们选择的语言查看所有组件。

使用 Tolgee 进行本地化

Tolgee 还提供了上下文翻译功能,允许您直接在应用程序内翻译字符串,无论是在开发还是生产过程中,只需单击文本并按住 Alt 或 Option 键即可。

使用 Tolgee 进行应用内翻译

恭喜!您已成功完成本教程的项目。

本教程的源代码可以在这里找到:

https://github.com/JanCizmar/dub-with-tolgee


结论

到目前为止,您已经学习了如何使用 Tolgee 为您的软件应用程序添加本地化,​​实现对多种语言的支持,以及如何在实际项目中实现无缝语言切换。

Tolgee 是一个快速、以开发者为中心的本地化平台,可让您为内容提供上下文并在几秒钟内生成翻译。它还支持多个 JavaScript 框架,包括 Vue、Angular 和 Svelte,并与 Figma 等工具和 REST API 集成,以提高灵活性。

如果您想为用户打造个性化体验,Tolgee 是您的理想之选。欢迎您为我们的GitHub 代码库贡献代码并点赞,并加入我们的Slack 社区,与他人联系并与团队互动。

感谢您的阅读!

文章来源:https://dev.to/tolgee_i18n/i-have-localized-the-best-short-linking-platform-in-the-world-344l
PREV
我说过,React 不需要状态管理工具
NEXT
更快!彻底优化 React 应用