diff --git a/blog/2025-01-06-sdk-v6.mdx b/blog/2025-01-06-sdk-v6.mdx new file mode 100644 index 00000000..26ff4f48 --- /dev/null +++ b/blog/2025-01-06-sdk-v6.mdx @@ -0,0 +1,75 @@ +--- +slug: sdk-v6 +title: 'Tolgee SDK Version 6 released!' +description: "Supercharge your localization with Tolgee SDK V6! Simplified Next.js integration, smarter translation fetching, and minimal breaking changes for a seamless transition!" +image: /img/blog/sdk-v6/SDK6-light.webp +authors: [sgranat] +tags: ['tolgee', 'sdk', 'release'] +--- + +import ThemedImage from '@theme/ThemedImage'; +import useBaseUrl from '@docusaurus/useBaseUrl'; + +<ThemedImage + alt="SDK v6" + sources={{ + light: useBaseUrl( + '/img/blog/sdk-v6/SDK6-light.webp' + ), + dark: useBaseUrl( + '/img/blog/sdk-v6/SDK6-dark.webp' + ), + }} +/> + +With Tolgee SDK Version 6, fetching translations for your Next.js applications is easier than ever. You can prefetch translation data on the server and seamlessly pass it to the client, ensuring smooth and efficient localization. + +<!-- truncate--> + +### Fetching Required Translations with `loadRequired` + +The `loadRequired` method fetches translations based on the current language and namespace settings. Use it on the server to prefetch data and on the client to avoid extra fetches: + +```ts +// Server-side +const translations = JSON.stringify(await tolgee.loadRequired()); + +// Client-side +tolgee.addStaticData(JSON.parse(translations)); +``` + +This approach ensures the client has the translations ready without additional requests. +Check the [next.js integration guide](/js-sdk/integrations/react/next/app-router) to see how it's used. + +### Advanced Prefetching with `loadMatrix` + +For greater control, use `loadMatrix` to prefetch specific languages and namespaces. + +```ts +// Fetch translations for multiple languages and namespaces +const translations = await tolgee.loadMatrix({ + languages: ['en', 'cs'], + namespaces: ['common', 'info'] +}); +``` + +To prefetch all namespaces for a language: + +```ts +await tolgee.loadMatrix({ + languages: ['en'], + namespaces: 'all' +}); +t('app_title', { ns: 'info' }); +``` + +These tools make it simple to fetch and render translations, streamlining the localization process for server-rendered and server components. + +## Breaking changes + +Version 6 is just a mild update, so breaking changes are minimal. + +Read the [migration guide](/js-sdk/migration_to_v6) to see what has changed. + +[](https://app.tolgee.io/sign_up) + diff --git a/docs.js b/docs.js index 1a01bf32..97c17bd9 100644 --- a/docs.js +++ b/docs.js @@ -30,7 +30,7 @@ const docs = [ versions: { current: { banner: 'none', - label: '5.x.x', + label: '6.x.x', }, }, }, diff --git a/js-sdk/api/core_package/events.mdx b/js-sdk/api/core_package/events.mdx index 2d5c5516..85052135 100644 --- a/js-sdk/api/core_package/events.mdx +++ b/js-sdk/api/core_package/events.mdx @@ -11,7 +11,7 @@ Tolgee events which can be listened through `tolgee.on` method. Emitted on language change. ```ts -tolgee.on('language', handler: ListenerHandler<string>) +tolgee.on('language', handler: Handler<LanguageEvent>) ``` ### pendingLanguage @@ -19,7 +19,7 @@ tolgee.on('language', handler: ListenerHandler<string>) Emitted on language change. Before languages are loaded (when tolgee is running). ```ts -tolgee.on('pendingLanguage', handler: ListenerHandler<string>) +tolgee.on('pendingLanguage', handler: Handler<PendingLanguageEvent>) ``` ### loading @@ -27,7 +27,7 @@ tolgee.on('pendingLanguage', handler: ListenerHandler<string>) Emitted on loading change. Changes when tolgee is loading some data for the first time. ```ts -tolgee.on('loading', handler: ListenerHandler<boolean>) +tolgee.on('loading', handler: Handler<LoadingEvent>) ``` ### fetching @@ -35,7 +35,7 @@ tolgee.on('loading', handler: ListenerHandler<boolean>) Emitted on fetching change. Changes when tolgee is fetching any data. ```ts -tolgee.on('fetching', handler: ListenerHandler<boolean>) +tolgee.on('fetching', handler: Handler<FetchingEvent>) ``` ### initialLoad @@ -43,7 +43,7 @@ tolgee.on('fetching', handler: ListenerHandler<boolean>) Emitted when `run` method finishes. ```ts -tolgee.on('initialLoad', handler: ListenerHandler<void>) +tolgee.on('initialLoad', handler: Handler<InitialLoadEvent>) ``` ### running @@ -51,7 +51,7 @@ tolgee.on('initialLoad', handler: ListenerHandler<void>) Emitted when internal `running` state changes. ```ts -tolgee.on('initialLoad', handler: ListenerHandler<boolean>) +tolgee.on('running', handler: Handler<RunningEvent>) ``` ### cache @@ -59,16 +59,23 @@ tolgee.on('initialLoad', handler: ListenerHandler<boolean>) Emitted when cache changes. ```ts -tolgee.on('cache', handler: ListenerHandler<CacheDescriptorWithKey>) +tolgee.on('cache', handler: Handler<CacheEvent>) ``` ### update -Emitted when any key needs (or might need) to be re-rendered. Similar to `tolgee.onNsUpdate`, -except we intercept all events, not just selection. +Emitted when any key needs (or might need) to be re-rendered. It's derrived from other events +(`initialLoad`, `language`, `cache`), the events are grouped when multiple happen at the same time, +so it only results to one `update` event being emitted. ```ts -tolgee.on('update', handler: ListenerHandler<void>) +tolgee.on('update', handler: CombinedHandler<UpdateEvent>) +``` + +You can check what events triggered this change event from the first argument of the handler. + +```ts +tolgee.on('update', (events) => events.forEach(e => ...)) ``` ### error @@ -79,6 +86,6 @@ Emitted when there is an error. You can intercept different types of errors, con - `LanguageStorageError` - error when loading/saving language through language storage plugin ```ts -tolgee.on('error', handler: ListenerHandler<TolgeeError>) +tolgee.on('error', handler: Handler<ErrorEvent>) ``` diff --git a/js-sdk/api/core_package/options.mdx b/js-sdk/api/core_package/options.mdx index cfb4c997..5556e154 100644 --- a/js-sdk/api/core_package/options.mdx +++ b/js-sdk/api/core_package/options.mdx @@ -68,8 +68,8 @@ projectId: number | string; ### availableLanguages -Languages which can be used for language detection -and also limits which values can be stored. Is derrived from `staticData` keys if not provided. +Specify all available languages. Required for language detection or loading all languages at once ([loadMatrix](./tolgee.mdx#loadmatrix)). +It also limits which values can be stored. Is derrived from `staticData` keys if not provided. ```ts availableLanguages: string[]; @@ -99,6 +99,14 @@ Default namespace when no namespace defined (default: empty string) defaultNs: string; ``` +### availableNs + +Specify all available namespaces. Required for loading all namespaces at once ([loadMatrix](./tolgee.mdx#loadmatrix)). + +```ts +availableNs: string[]; +``` + ### staticData These data go directly to cache or you can specify async diff --git a/js-sdk/api/core_package/tolgee.mdx b/js-sdk/api/core_package/tolgee.mdx index eb8e52b9..cb78513e 100644 --- a/js-sdk/api/core_package/tolgee.mdx +++ b/js-sdk/api/core_package/tolgee.mdx @@ -102,27 +102,6 @@ listener.unsubscribe() Check [Events](./events) for details. -### onNsUpdate - -Allows you to listen to key changes of namespaces that you pick. - -```ts -tolgee.onNsUpdate(handler: ListenerHandler): ListenerSelective -``` - -Returns object, which allows you to subscribe to namespaces. - -```ts -const listener = tolgee.onNsUpdate(...) -// subscribes namespace -listener.subscribeNs(ns) -// unsubscribe completely -listener.unsubscribe() -``` - -Use this when you want to make sure, you always update translation when it's necessary. -It internally stores list of namespaces that you are interested in and calls the handler, when necessary. - ### t Returns formatted translation based on current language. If `Observer` is present and tolgee is running, `wraps` the result to be identifiable in the DOM. @@ -274,15 +253,16 @@ when you need to find out if tolgee has all the necessary data before `run` func tolgee.isLoaded(ns?: FallbackNsTranslation): boolean ``` -### getRequiredRecords +### getRequiredDescriptors -Returns records needed for instance to be `loaded` +Returns descriptors of records needed for instance to be `loaded` ```ts -tolgee.getRequiredRecords(): CacheDescriptor[] +tolgee.getRequiredDescriptors(lang?: string, ns?: NsFallback): CacheDescriptorInternal[] ``` -- `ns`: `string` | `string[]` - optional list of namespaces that you are interested in +- `lang`: `string` - optional language (if not present, takes current language) +- `ns`: `string` | `string[]` - optional list of namespaces that you are interested in (if not present takes current active namespaces) ### isDev @@ -335,24 +315,81 @@ Returns wrapped translation info. tolgee.unwrap(text: string): Unwrapped ``` -### loadRecord -Manually load record from `Backend` (or `DevBackend` when in dev mode). +### loadRequired + +Load records required by current settings (influenced by current language and active namespaces). ```ts -tolgee.loadRecord(descriptors: CacheDescriptor): Promise<TranslationsFlat> +loadRequired(options?: LoadRequiredOptions): Promise<CacheInternalRecord[]> ``` +In most cases can be called without any options and will return records which would be loaded +by `run` method initially. + +Options: + - `language`: `string` - optionally override instance language (can be used when you don't know the language at the initialization time) + - `noDev`: `boolean` - load production translations only - skips DevBackend (false by default) + - `useCache`: `boolean` - skip fetching already loaded records (false by default) + +### loadMatrix + +Loads all combinations of specified languages and namespaces. + +```ts +loadRequired(options?: LoadRequiredOptions): Promise<CacheInternalRecord[]> +``` + +Example usage: +```ts +const result = await tolgee.loadMatrix({ + languages: ['en', 'cs'], + namespaces: [''] +}) +// loads `en` and `cs` languages for empty namespace + +const result = await tolgee.loadMatrix({ + languages: ['en', 'cs'], + namespaces: ['common', 'info'] +}) +// loads `en:common`, `en:info`, `cs:common` and `cs:info` records +``` + +Options: + - `languages`: `string[] | 'all'` - languages that should be loaded + - use `all` value to load all [`availableLanguages`](./options.mdx#availablelanguages) + - `namespaces`: `string[] | 'all'` - namespaces that should be loaded + - use `all` value to load all [`availableNs`](./options.mdx#availablens) + - `noDev`: `boolean` - load production translations only - skips DevBackend (false by default) + - `useCache`: `boolean` - skip fetching already loaded records (false by default) + + ### loadRecords -Manually load multiple records from `Backend` (or `DevBackend` when in dev mode). +Load records by specifying it's descriptors (language and namespace). ```ts -tolgee.loadRecords(descriptors: CacheDescriptor[]): Promise<TranslationsFlat[]> +tolgee.loadRecords(descriptors: CacheDescriptor[], options?: LoadOptions): Promise<TranslationsFlat[]> ``` It loads data together and adds them to cache in one operation, to prevent partly loaded state. +Options: + - `noDev`: `boolean` - load production translations only - skips DevBackend (false by default) + - `useCache`: `boolean` - skip fetching already loaded records (false by default) + +### loadRecord + +Load record by specifying it's descriptor (language and namespace). + +```ts +tolgee.loadRecord(descriptor: CacheDescriptor, options?: LoadOptions): Promise<TranslationsFlat> +``` + +Options: + - `noDev`: `boolean` - load production translations only - skips DevBackend (false by default) + - `useCache`: `boolean` - skip fetching already loaded records (false by default) + ### getRecord Get record from cache. diff --git a/js-sdk/api/web_package/tools.mdx b/js-sdk/api/web_package/tools.mdx index 820ca928..e99d09e0 100644 --- a/js-sdk/api/web_package/tools.mdx +++ b/js-sdk/api/web_package/tools.mdx @@ -8,10 +8,6 @@ slug: tools As `DevTools` are automatically omitted on production, `@tolgee/web/tools` can be used to include it unconditionally. -:::info -Tools were moved from `@tolgee/web` in version 5.2.0. -::: - ## `InContextTools` diff --git a/js-sdk/fetching_translations.mdx b/js-sdk/fetching_translations.mdx new file mode 100644 index 00000000..33754b93 --- /dev/null +++ b/js-sdk/fetching_translations.mdx @@ -0,0 +1,68 @@ +--- +id: fetching_translations +title: Fetching translations +description: Learn how to use the Tolgee SDK to fetch translation files, prefetch data for server-side rendering, and manage caching strategies effectively. +--- + +:::info +New in SDK version 6 +::: + +Tolgee SDK can be used to load correct translation files simply from the Tolgee platform or static data. +This is primarily useful on the server when you need to prefetch data and pass them to frontend as a JSON. + +These methods also load the data to the cache, so you can then call `t` function to render the translations. + +## loadRequired + +This method fetches the same data as `tolgee.run()` method - based on current options of `language`, `ns` (and their fallbacks). + +```ts +// on the server +const translations = JSON.stringify(await tolgee.loadRequired()) + +// ... pass translations to the client + +// on the client +tolgee.addStaticData(translations) +// now the client doesn't have to fetch anything, when `run` is called +``` + +> Check the [method API](./api/core_package/tolgee.mdx#loadrequired) + +## loadMatrix + +Use this method for easy prefetching of user-defined records. + +```ts +const translations = await tolgee.loadMatrix({ + languages: ['en', 'cs'] + namespaces: ['common', 'info'] +}) +// loads `en:common`, `en:info`, `cs:common` and `cs:info` records +``` + +Let's say we want to load all namespaces on the server so we can render them without loading them later. + +```ts +await tolgee.loadMatrix({ + languages: ['en'] + namespaces: 'all' +}) + +// now all namespaces are now prefetched for English + +t('app_title', { ns: 'info' }) +``` + +For this to work, you need to specify [`availableNs`](./api/core_package/options.mdx#availablens) or [`availableLanguages`](./api/core_package/options.mdx#availablelanguages). + +> Check the [method API](./api/core_package/tolgee.mdx#loadmatrix) + +# Data caching on the server + +By default these methods always re-fetch the data when called (requests are only de-duped). + +If you want to re-use already fetched data from the cache, you can pass option `{ useCache: true }`. +However, on the server, this is not recommended, because until the tolgee instance is live, the data wouldn't be renewed. +Instead, we recommend an external caching solution (for example next.js caching). \ No newline at end of file diff --git a/js-sdk/filter_by_tags.mdx b/js-sdk/filter_by_tags.mdx index 4b473a6e..cfc21c69 100644 --- a/js-sdk/filter_by_tags.mdx +++ b/js-sdk/filter_by_tags.mdx @@ -1,7 +1,7 @@ --- id: filter_by_tags title: Filter keys by tags -description: '' +description: Learn how to configure the Tolgee SDK to filter translation keys by tags, enabling targeted translation loading for different platforms like web and mobile. --- You can configure Tolgee to only use keys with certain tags. This can be useful if you are sharing translations e.g. between multiple platforms (e.g. web and mobile). diff --git a/js-sdk/integrations/react/next/app_router.mdx b/js-sdk/integrations/react/next/app_router.mdx index f1cf6fa0..9caf2154 100644 --- a/js-sdk/integrations/react/next/app_router.mdx +++ b/js-sdk/integrations/react/next/app_router.mdx @@ -8,6 +8,7 @@ description: "Get started with Tolgee's integration for Next.js. Learn how to ad import AppRouterTranslating from './shared/_AppRouterTranslating.mdx' import ExampleBanner from '../../../shared/ExampleBanner'; import LimitationsOfServerComponents from './shared/_LimitationsOfServerComponents.mdx' +import CdnFetchPlugin from './shared/_CdnFetchPlugin.mdx'; <ExampleBanner framework="Next app router" appName="next-app" /> @@ -31,10 +32,6 @@ To implement localization to your app, you need to install the `@tolgee/react` p npm install @tolgee/react ``` -:::info -Use `@tolgee/react` version `5.30.0` and higher -::: - ## Folder structure The folder structure of your project should resemble the following: @@ -90,25 +87,6 @@ export const ALL_LANGUAGES = ['en', 'cs']; export const DEFAULT_LANGUAGE = 'en'; -export async function getStaticData( - languages: string[], - namespaces: string[] = [''] -) { - const result: Record<string, any> = {}; - for (const lang of languages) { - for (const namespace of namespaces) { - if (namespace) { - result[`${lang}:${namespace}`] = ( - await import(`../../messages/${namespace}/${lang}.json`) - ).default; - } else { - result[lang] = (await import(`../../messages/${lang}.json`)).default; - } - } - } - return result; -} - export function TolgeeBase() { return Tolgee() .use(FormatSimple()) @@ -117,13 +95,17 @@ export function TolgeeBase() { .updateDefaults({ apiKey, apiUrl, + staticData: { + en: () => import('../../messages/en.json'), + cs: () => import('../../messages/cs.json'), + } }); } ``` ### Client configutation -The client configuration is very similar to the [Pages Router set up](./pages-router). It serves the purpose of translating client components and also enables the in-context functionality for server-rendered components. +The client configuration is very similar to the [Pages Router setup](./pages-router). It serves the purpose of translating client components and also enables the in-context functionality for server-rendered components. ```tsx title="src/tolgee/client.tsx" 'use client'; @@ -149,6 +131,7 @@ export const TolgeeNextProvider = ({ const router = useRouter(); useEffect(() => { + // this ensures server components refresh, after translation change const { unsubscribe } = tolgee.on('permanentChange', () => { router.refresh(); }); @@ -158,7 +141,6 @@ export const TolgeeNextProvider = ({ return ( <TolgeeProvider tolgee={tolgee} - options={{ useSuspense: false }} fallback="Loading" ssr={{ language, staticData }} > @@ -209,25 +191,22 @@ Your app will utilize the React server cache for sharing Tolgee instance across One important difference from the client setup is the utilization of [`fullKeyEncode`](../../../api/core_package/observer-options#fullkeyencode). `fullKeyEncode` ensures that translations rendered on the server are correctly picked up and interactive for in-context mode. ```tsx title="src/tolgee/server.tsx" -import { TolgeeBase, ALL_LANGUAGES, getStaticData } from './shared'; -import { createServerInstance } from '@tolgee/react/server'; import { getLanguage } from './language'; +import { TolgeeBase } from './shared'; +import { createServerInstance } from '@tolgee/react/server'; -export const { getTolgee, getTranslate, T } = createServerInstance({ - getLocale: getLanguage, - createTolgee: async (locale) => - TolgeeBase().init({ - // including all locales - // on server we are not concerned about bundle size - staticData: await getStaticData(ALL_LANGUAGES), - observerOptions: { - fullKeyEncode: true, - }, - language: locale, - fetch: async (input, init) => - fetch(input, { ...init, next: { revalidate: 0 } }), - }), -}); +export const { getTolgee, getTranslate, T, getTolgeeStaticInstance } = + createServerInstance({ + getLocale: getLanguage, + createTolgee: async (language) => { + return TolgeeBase().init({ + observerOptions: { + fullKeyEncode: true, + }, + language, + }); + }, + }); ``` ## Use the `TolgeeNextProvider` @@ -237,20 +216,18 @@ The next step is to wrap the children with the `TolgeeNextProvider`. Update the ```tsx title="src/app/layout.tsx" import { ReactNode } from 'react'; import { TolgeeNextProvider } from '@/tolgee/client'; -import { getStaticData } from '@/tolgee/shared'; +import { getTolgee } from '@/tolgee/server'; import { getLanguage } from '@/tolgee/language'; -import './style.css'; type Props = { children: ReactNode; - params: { locale: string }; }; export default async function LocaleLayout({ children }: Props) { const locale = await getLanguage(); - // it's important you provide all data which are needed for initial render - // so current language and also fallback languages + necessary namespaces - const staticData = await getStaticData([locale]); + const tolgee = await getTolgee(); + // serializable data that are passed to client components + const staticData = await tolgee.loadRequired(); return ( <html lang={locale}> @@ -302,4 +279,6 @@ export const LangSelector: React.FC = () => { <LimitationsOfServerComponents /> +<CdnFetchPlugin /> + <ExampleBanner framework="Next app router" appName="next-app" /> diff --git a/js-sdk/integrations/react/next/app_router_next_intl.mdx b/js-sdk/integrations/react/next/app_router_next_intl.mdx index dcd59d86..e3213b52 100644 --- a/js-sdk/integrations/react/next/app_router_next_intl.mdx +++ b/js-sdk/integrations/react/next/app_router_next_intl.mdx @@ -8,6 +8,7 @@ description: "Get started with Tolgee's integration for Next.js. Learn how to ad import AppRouterTranslating from './shared/_AppRouterTranslating.mdx' import ExampleBanner from '../../../shared/ExampleBanner'; import LimitationsOfServerComponents from './shared/_LimitationsOfServerComponents.mdx' +import CdnFetchPlugin from './shared/_CdnFetchPlugin.mdx'; This guide shows how to include language information into the page URL, so your application is SEO friendly. @@ -36,10 +37,6 @@ To implement localization to your app, you need to install the `next-intl` and ` npm install next-intl @tolgee/react ``` -:::info -Use `@tolgee/react` version `5.30.0` and higher -::: - ## Folder structure The folder structure of your project should resemble the following: @@ -99,25 +96,6 @@ export const ALL_LANGUAGES = ['en', 'cs', 'de', 'fr']; export const DEFAULT_LANGUAGE = 'en'; -export async function getStaticData( - languages: string[], - namespaces: string[] = [''] -) { - const result: Record<string, any> = {}; - for (const lang of languages) { - for (const namespace of namespaces) { - if (namespace) { - result[`${lang}:${namespace}`] = ( - await import(`../../messages/${namespace}/${lang}.json`) - ).default; - } else { - result[lang] = (await import(`../../messages/${lang}.json`)).default; - } - } - } - return result; -} - export function TolgeeBase() { return Tolgee() .use(FormatSimple()) @@ -168,7 +146,6 @@ export const TolgeeNextProvider = ({ return ( <TolgeeProvider tolgee={tolgee} - options={{ useSuspense: false }} fallback="Loading" ssr={{ language, staticData }} > @@ -187,25 +164,19 @@ One important difference from the client setup is the utilization of [`fullKeyEn ```tsx title="src/tolgee/server.tsx" import { getLocale } from 'next-intl/server'; - -import { TolgeeBase, ALL_LANGUAGES, getStaticData } from './shared'; import { createServerInstance } from '@tolgee/react/server'; +import { TolgeeBase } from './shared'; export const { getTolgee, getTranslate, T } = createServerInstance({ getLocale: getLocale, - createTolgee: async (language) => - TolgeeBase().init({ - // including all languages - // on server we are not concerned about bundle size - staticData: await getStaticData(ALL_LANGUAGES), + createTolgee: async (language) => { + return TolgeeBase().init({ observerOptions: { fullKeyEncode: true, }, language, - // using custom fetch to avoid aggressive caching - fetch: async (input, init) => - fetch(input, { ...init, next: { revalidate: 0 } }), - }), + }); + }, }); ``` @@ -214,32 +185,29 @@ export const { getTolgee, getTranslate, T } = createServerInstance({ The next step is to wrap the children with the `TolgeeNextProvider`. Update the `layout.tsx` file with the following code: ```tsx title="src/app/[locale]/layout.tsx" +import React, { ReactNode } from 'react'; import { notFound } from 'next/navigation'; -import { ReactNode } from 'react'; import { TolgeeNextProvider } from '@/tolgee/client'; -import { ALL_LANGUAGES, getStaticData } from '@/tolgee/shared'; +import { ALL_LANGUAGES } from '@/tolgee/shared'; +import { getTolgee } from '@/tolgee/server'; type Props = { children: ReactNode; - params: { locale: string }; + params: Promise<{ locale: string }>; }; -export default async function LocaleLayout({ - children, - params: { locale }, -}: Props) { +export default async function LocaleLayout({ children, params }: Props) { + const { locale } = await params; if (!ALL_LANGUAGES.includes(locale)) { notFound(); } - - // it's important you provide all data which are needed for initial render - // so current language and also fallback languages + necessary namespaces - const staticData = await getStaticData([locale, 'en']); + const tolgee = await getTolgee(); + const records = await tolgee.loadRequired(); return ( <html lang={locale}> <body> - <TolgeeNextProvider language={locale} staticData={staticData}> + <TolgeeNextProvider language={locale} staticData={records}> {children} </TolgeeNextProvider> </body> @@ -277,14 +245,14 @@ export const config = { Next, create a `src/navigation.ts` file. This provides easy access to the navigation APIs in your components. ```ts title="src/navigation.ts" -import { createSharedPathnamesNavigation } from 'next-intl/navigation'; +import { createNavigation } from 'next-intl/navigation'; import { ALL_LANGUAGES } from './tolgee/shared'; // read more about next-intl library // https://next-intl-docs.vercel.app -export const { Link, redirect, usePathname, useRouter } = - createSharedPathnamesNavigation({ locales: ALL_LANGUAGES }); -``` +export const { Link, redirect, usePathname, useRouter } = createNavigation({ + locales: ALL_LANGUAGES, +});``` > To gain a comprehensive understanding of how `next-intl` operates, read [their documentation](https://next-intl-docs.vercel.app/docs/getting-started/app-router-server-components). This example utilizes the necessary setup for proper routing. Not all the listed configurations are required. @@ -309,12 +277,12 @@ The `i18n/request.ts` is required by `next-intl` package, we don't actually need ```ts title="src/i18n.ts" import { getRequestConfig } from 'next-intl/server'; -import { getStaticData } from '../tolgee/shared'; -export default getRequestConfig(async ({ locale }) => { +export default getRequestConfig(async ({ requestLocale }) => { + const locale = await requestLocale; return { - // do this to make next-intl not emitting any warnings - messages: { locale }, + // do this to make next-intl not emmit any warnings + messages: { locale: locale! }, }; }); ``` @@ -337,7 +305,7 @@ export const LangSelector: React.FC = () => { const locale = tolgee.getLanguage(); const router = useRouter(); const pathname = usePathname(); - const [isPending, startTransition] = useTransition(); + const [_, startTransition] = useTransition(); function onSelectChange(event: ChangeEvent<HTMLSelectElement>) { const newLocale = event.target.value; @@ -360,4 +328,6 @@ Make sure you use navigation-related components from `@/navigation` instead nati <LimitationsOfServerComponents /> +<CdnFetchPlugin /> + <ExampleBanner framework="Next app router with next-intl" appName="next-app-intl" /> diff --git a/js-sdk/integrations/react/next/pages_router.mdx b/js-sdk/integrations/react/next/pages_router.mdx index 329692cd..d93c3243 100644 --- a/js-sdk/integrations/react/next/pages_router.mdx +++ b/js-sdk/integrations/react/next/pages_router.mdx @@ -6,6 +6,8 @@ description: "Get started with Tolgee's integration for Next.js. Learn how to ad --- import ExampleBanner from '../../../shared/ExampleBanner'; +import CdnFetchPlugin from './shared/_CdnFetchPlugin.mdx'; + <ExampleBanner framework="Next pages router" appName="next" /> @@ -25,10 +27,6 @@ To implement localization to your app, you need to install the `@tolgee/react` p npm install @tolgee/react ``` -:::info -Use `@tolgee/react` version `5.30.0` and higher -::: - ## Folder structure The folder structure of your project should resemble the following: @@ -82,25 +80,6 @@ This file contains tolgee setup and helper function for loading static files. import { FormatIcu } from '@tolgee/format-icu'; import { Tolgee, DevTools } from '@tolgee/react'; -export async function getStaticData( - languages: string[], - namespaces: string[] = [''] -) { - const result: Record<string, any> = {}; - for (const lang of languages) { - for (const namespace of namespaces) { - if (namespace) { - result[`${lang}:${namespace}`] = ( - await import(`../messages/${namespace}/${lang}.json`) - ).default; - } else { - result[lang] = (await import(`../messages/${lang}.json`)).default; - } - } - } - return result; -} - export const tolgee = Tolgee() .use(FormatIcu()) .use(DevTools()) @@ -109,6 +88,10 @@ export const tolgee = Tolgee() defaultLanguage: 'en', apiKey: process.env.NEXT_PUBLIC_TOLGEE_API_KEY, apiUrl: process.env.NEXT_PUBLIC_TOLGEE_API_URL, + staticData: { + en: () => import('../messages/en.json'), + cs: () => import('../messages/cs.json'), + } }); ``` @@ -150,7 +133,12 @@ MyApp.getInitialProps = async ( context: AppContext ): Promise<AppOwnProps & AppInitialProps> => { const ctx = await App.getInitialProps(context); - return { ...ctx, staticData: await getStaticData([context.ctx.locale!]) }; + return { + ...ctx, + staticData: await tolgee.loadRequired({ + language: context.ctx.locale!, + }), + }; }; ``` @@ -188,6 +176,8 @@ The next step is to render the translated text for the selected locale. Use the </h1> ``` +<CdnFetchPlugin /> + That's it! You have successfully implemented translation to your Next.js applicaiton. You can also use translation methods described in the [React Translating documentation](../translating.mdx). <ExampleBanner framework="Next pages router" appName="next" /> diff --git a/js-sdk/integrations/react/next/shared/_CdnFetchPlugin.mdx b/js-sdk/integrations/react/next/shared/_CdnFetchPlugin.mdx new file mode 100644 index 00000000..68d938fc --- /dev/null +++ b/js-sdk/integrations/react/next/shared/_CdnFetchPlugin.mdx @@ -0,0 +1,17 @@ +## Usage of Tolgee Content Delivery + +If you want to use Tolgee Content Delivery instead of local static data, +we recommend usage of next.js cache functionality by configuring the BackendFetch plugin in following way: + +```ts +tolgee.use( + BackendFetch({ + prefix: '<your content storage link>', + next: { + revalidate: 60, // cache CDN data for one minute + }, + }) +) +``` + +You can remove `staticData` or use them as fallback ([read more](/js-sdk/providing-static-data#load-translations-directly-from-tolgee)). \ No newline at end of file diff --git a/js-sdk/integrations/react/react_native.mdx b/js-sdk/integrations/react/react_native.mdx index d0bef4f8..70e39788 100644 --- a/js-sdk/integrations/react/react_native.mdx +++ b/js-sdk/integrations/react/react_native.mdx @@ -27,7 +27,7 @@ const tolgee = Tolgee() // DevTools will work only for web view .use(DevTools()) .use(FormatSimple()) - // replace with .use(FormatIcu()) for rendering plurals, foramatted numbers, etc. + // replace with .use(FormatIcu()) for rendering plurals, formatted numbers, etc. .init({ language: 'en', diff --git a/js-sdk/integrations/vanilla/translating.mdx b/js-sdk/integrations/vanilla/translating.mdx index 262b56ec..8a6d13ee 100644 --- a/js-sdk/integrations/vanilla/translating.mdx +++ b/js-sdk/integrations/vanilla/translating.mdx @@ -24,14 +24,4 @@ You can [listen](../../api/core_package/tolgee.mdx#on) for translation change wi tolgee.on('update', () => { domElement.textContent = tolgee.t('key', 'Default value'); }); -``` - -This event gets triggered when any translation need to be updated, so it might be inefficient if you use many namespaces. Therefore there is also [`onNsUpdate`](../../api/core_package/tolgee.mdx#onnsupdate) method, which allows you to subscribe only to selected namespaces. - -```ts -tolgee - .onNsUpdate(() => { - domElement.textContent = tolgee.t('key', 'Default value'); - }) - .subscribeNs('my_namespace'); -``` +``` \ No newline at end of file diff --git a/js-sdk/integrations/vue/api.mdx b/js-sdk/integrations/vue/api.mdx index 3171dc30..07efa400 100644 --- a/js-sdk/integrations/vue/api.mdx +++ b/js-sdk/integrations/vue/api.mdx @@ -114,10 +114,6 @@ import { T } from '@tolgee/vue'; ### Children -:::info -Feature available from version 5.24.0 -::: - Pass children to the `T` component that gets mapped to the translation parameters respective to their slot names. Allows implementation of custom components as a part of the translation. ```html diff --git a/js-sdk/integrations/vue/component_interpolation.mdx b/js-sdk/integrations/vue/component_interpolation.mdx index 14572d6a..07b07117 100644 --- a/js-sdk/integrations/vue/component_interpolation.mdx +++ b/js-sdk/integrations/vue/component_interpolation.mdx @@ -6,10 +6,6 @@ slug: component-interpolation description: "Learn to use component interpolation in Vue with Tolgee. Guide covers implementing custom components within translations, using FormatIcu and the T component. Includes code examples and usage tips." --- -:::info -Feature available from version 5.24.0 -::: - You might want to use a Component for certain part of the translated string. For example, let's take the translated string `Click this link`. You want to add the anchor tag to the word `link`. Using the integration library, you can implement this easily. The integration library, uses [`FormatIcu`](/formatting.mdx#icu-formatter) which supports component interpolation. You can map variables in translations to custom Vue components. diff --git a/js-sdk/integrations/vue/ssr.mdx b/js-sdk/integrations/vue/ssr.mdx index 7d5c811c..1950e365 100644 --- a/js-sdk/integrations/vue/ssr.mdx +++ b/js-sdk/integrations/vue/ssr.mdx @@ -43,7 +43,7 @@ const language = ?; ... <template> - <TolgeeProvider :language="language" :static-data="staticData" ...> + <TolgeeProvider :ssr="{ staticData, language: 'en' }" ...> ... </TolgeeProvider> </template> @@ -65,7 +65,7 @@ const staticData = ?; ... <template> - <TolgeeProvider :language="language" :static-data="staticData" ...> + <TolgeeProvider :ssr="{ staticData, language: 'en' }" ...> ... </TolgeeProvider> </template> diff --git a/js-sdk/migration_to_v6.mdx b/js-sdk/migration_to_v6.mdx new file mode 100644 index 00000000..59bf8f1d --- /dev/null +++ b/js-sdk/migration_to_v6.mdx @@ -0,0 +1,103 @@ +--- +id: migration_to_v6 +title: Migration to v6 +description: 'In v6 we introduced a few minor breaking changes, which were mostly necessary for better support of +next.js' +--- + +In v6 we introduced a few minor breaking changes, which were mostly necessary for better support of +next.js (and server-side rendering in general). + +## Updates to cache + +The cache no longer returns records as maps. +All methods interacting with the cache are now returning plain objects instead of `Map`. + +```ts +tolgee.loadRecords(): Promise<CacheInternalRecord[]> +tolgee.loadRecord(): Promise<CacheInternalRecord> +tolgee.getRecord(): CacheInternalRecord +tolgee.getAllRecords(): CacheInternalRecord[] +``` + +Returned cache record(s) are now unified like this: +```ts +type CacheInternalRecord = { + data: Record<string, string | undefined | null>; // replaces Map() + language: string; + namespace: string; + cacheKey: string; +}; +``` + +## Updated `getRequiredRecords` + +This function was renamed to `getRequiredDescriptors`, because it's not returning data from the cache, +but description (descriptors) of what needs to be in cache. The previous name was confusing. + +```ts +tolgee.getRequiredDescriptors(lang?: string, ns?: NsFallback): CacheDescriptorInternal[] +``` + +Previously the method returned the descriptors that were missing in the cache, but now we are returning +all the missing records regardless of what is currently in the cache. + +Previous behavior can be achieved by comparing the cache content with the results of this function. + +## Removed obscure `onNsUpdate` subscribing + +Previously it was possible to subscribe to specific namespace changes like this: + +```ts +const listener = tolgee.onNsUpdate(...) +// subscribes namespace +listener.subscribeNs(ns) +// unsubscribe completely +listener.unsubscribe() +``` + +You can replace that with `update` event. + +```ts +tolgee.on('update', ...) +``` + +If you only want to react to certain namespaces, the event handler receives an array of events which +led to the invocation of `update` event (`update` is derived from other events). + +```ts +tolgee.on('update', (events) => { + if (events.every(e => (e.type !== 'cache' || e.value.namespace === 'namespace'))) { + handler() + } +}) +``` + +## React + +`TolgeeProvider` component `useSuspense` is now false by default. It didn't work well with next.js, +so it's off by default. + +Old: +```tsx +<TolgeeProvider options={{ useSuspense: false }}> +``` + +New: +```tsx +<TolgeeProvider> +``` + +## Vue + +`TolgeeProvider` ssr interface is now the same as the react one. + +Old: +```html +<TolgeeProvider :staticData="staticData" language="en"> +``` + +New: +```html +<TolgeeProvider :ssr="{ staticData, language: 'en' }"> +``` diff --git a/js-sdk_versioned_docs/version-5.x.x/about.mdx b/js-sdk_versioned_docs/version-5.x.x/about.mdx new file mode 100644 index 00000000..e37a916a --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/about.mdx @@ -0,0 +1,53 @@ +--- +id: about +title: Overview +slug: / +description: 'Tolgee SDK provides the functionality of an i18n library and helps you with formatting, interpolation, or language detection. ' +--- + +import { ScreenRecording } from '../../platform/shared/_ScreenRecording'; + +Tolgee SDK provides the functionality of an i18n library and helps you with [formatting](./formatting), interpolation, and [language detection](./language#language-detection). +The SDK also allows you to connect to the [Tolgee Platform](../../platform/). It enables you to implement [in-context translation](./in-context) which also helps you generate one-click screenshots and edit translations directly in your app. + +## In-context Translation + +In-context translation helps you speed up development by saving you from tedious localization tasks. Using the Tolgee SDK, you can implement in-context translation. Learn more about in-context translation and how to implement it in your local development environment in [this documentation](./in-context). + +<ScreenRecording> + <source src="/in-context.mov"></source> +</ScreenRecording> + +You can also enable in-context translation in the production version of your web application. Set up the [Tolgee Tools](https://chrome.google.com/webstore/detail/tolgee-tools/hacnbapajkkfohnonhbmegojnddagfnj) to use in-context translation in production. + +<ScreenRecording> + <source src="/in-context-production.mov"></source> +</ScreenRecording> + +## Automated Screenshots Generation + +To help translators understand the exact context of the translation, you can now add screenshots. Generate one-click screenshots with in-context translation or the [Tolgee Tools](https://chrome.google.com/webstore/detail/tolgee-tools/hacnbapajkkfohnonhbmegojnddagfnj) extension. + +<ScreenRecording> + <source src="/in-context-screenshot.mov"></source> +</ScreenRecording> + +## Automatic Context Collection + +The SDK automatically collects additional context about the layout of the keys on the page. This context allows the Tolgee Translator to provide you with better results, utilizing ChatGPT under the hood. + +### What data are collected and when? + +Every time you save a translation through the in-context translation dialog box, the SDK sends a list of keys currently present on the page to the Tolgee platform. The platform then tracks the relationships between the keys based on thier order of appreance across different pages. + +### Is this safe, and what about data leaks? + +We only collect information about the order of the translations, which are already present on the platform. This order information helps the model better understand their relationships. We do not collect any additional information from your page. + +## Review translations + +Your team can review the translations directly in your app, make any necessary changes, and mark these translations as reviewed. This helps you set up a workflow for translation, speeding up the process and resulting in faster development. + +<ScreenRecording> + <source src="/in-context-review.mov"></source> +</ScreenRecording> diff --git a/js-sdk_versioned_docs/version-5.x.x/api/core_package/about.mdx b/js-sdk_versioned_docs/version-5.x.x/api/core_package/about.mdx new file mode 100644 index 00000000..b1b0f90e --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/api/core_package/about.mdx @@ -0,0 +1,15 @@ +--- +id: about +title: About +description: "Tolgee core package is platform agnosting and aims to provide universal basis for all other packages from Tolgee SDK." +--- + +## Tolgee core + +Tolgee core package is platform agnosting and aims to provide universal basis for all other packages from Tolgee SDK. + +It exports these basic parts: + +- [`TolgeeCore`](./tolgee#tolgeecore) instance creator +- [`FormatSimple`](./format-simple) plugin +- [Other tools](./other-tools) diff --git a/js-sdk_versioned_docs/version-5.x.x/api/core_package/events.mdx b/js-sdk_versioned_docs/version-5.x.x/api/core_package/events.mdx new file mode 100644 index 00000000..2d5c5516 --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/api/core_package/events.mdx @@ -0,0 +1,84 @@ +--- +id: events +title: Core Events +sidebar_label: Events +--- + +Tolgee events which can be listened through `tolgee.on` method. + +### language + +Emitted on language change. + +```ts +tolgee.on('language', handler: ListenerHandler<string>) +``` + +### pendingLanguage + +Emitted on language change. Before languages are loaded (when tolgee is running). + +```ts +tolgee.on('pendingLanguage', handler: ListenerHandler<string>) +``` + +### loading + +Emitted on loading change. Changes when tolgee is loading some data for the first time. + +```ts +tolgee.on('loading', handler: ListenerHandler<boolean>) +``` + +### fetching + +Emitted on fetching change. Changes when tolgee is fetching any data. + +```ts +tolgee.on('fetching', handler: ListenerHandler<boolean>) +``` + +### initialLoad + +Emitted when `run` method finishes. + +```ts +tolgee.on('initialLoad', handler: ListenerHandler<void>) +``` + +### running + +Emitted when internal `running` state changes. + +```ts +tolgee.on('initialLoad', handler: ListenerHandler<boolean>) +``` + +### cache + +Emitted when cache changes. + +```ts +tolgee.on('cache', handler: ListenerHandler<CacheDescriptorWithKey>) +``` + +### update + +Emitted when any key needs (or might need) to be re-rendered. Similar to `tolgee.onNsUpdate`, +except we intercept all events, not just selection. + +```ts +tolgee.on('update', handler: ListenerHandler<void>) +``` + +### error + +Emitted when there is an error. You can intercept different types of errors, connected to fetching language data, detecting language or loading/storing language, you can filter them by `name` property on the error, which can be: + - `RecordFetchError` - error when fetching translations record, you can also read `language` and `namespace` properties, to see which record has failed + - `LanguageDetectorError` - error when detecting language through language detector plugin + - `LanguageStorageError` - error when loading/saving language through language storage plugin + +```ts +tolgee.on('error', handler: ListenerHandler<TolgeeError>) +``` + diff --git a/js-sdk_versioned_docs/version-5.x.x/api/core_package/format_simple.mdx b/js-sdk_versioned_docs/version-5.x.x/api/core_package/format_simple.mdx new file mode 100644 index 00000000..69eda873 --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/api/core_package/format_simple.mdx @@ -0,0 +1,47 @@ +--- +id: format_simple +title: FormatSimple +sidebar_label: FormatSimple +slug: format-simple +description: Super light formatter, which will enable you to pass variables into translations. It is a subset of ICU format. +--- + +Super light formatter, which will enable you to pass variables into translations. +It's a subset of Icu format. + +## Usage + +```ts +import { FormatSimple } from '@tolgee/core'; + +const tolgee = Tolgee() + .use(FormatSimple()) + .init(...) +``` + +## Syntax + +Passing variable: + +```ts +f('Martin is {age} years old.', { age: 10 }); +// Martin is 10 years old +``` + +You can also escape special characters by wrapping them into `'`, it works the same as in Icu standard and it only +acts like escaping character when it's followed by escapable character ("{`). It doesn't have to be closed (then all +rest of the translation is escaped). + +```ts +f("This is escaped text: '{age}'"); +// This is escaped text: {age} + +f("This is also '{fine}"); +// This is also {fine} + +f("This will work 'as expected'"); +// This will work 'as expected' +``` + +That's it! We've tried to do this format as simple as possible so the parser doesn't bloat your bundle. +If you need advanced features use [`@tolgee/format-icu`](/platform/translation_process/icu_message_format) package. diff --git a/js-sdk_versioned_docs/version-5.x.x/api/core_package/observer_options.mdx b/js-sdk_versioned_docs/version-5.x.x/api/core_package/observer_options.mdx new file mode 100644 index 00000000..42ccc984 --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/api/core_package/observer_options.mdx @@ -0,0 +1,138 @@ +--- +id: observer_options +title: Observer options +sidebar_label: Observer options +slug: observer-options +--- + +Tolgee Observer options which are part of [tolgee options](./options). Allows you to influence `ObserverPlugin` if present. + +### targetElement + +Element where wrapped strings are expected in development mode. + +```ts +targetElement: Node; +``` + +Default: `document` + +### fullKeyEncode + +Encode full key info into the wrapped translation (read more about [wrapping](/js-sdk/wrapping)). This option allows you to wrap translations on the server and then unwrap on the client. The option is important for the wrapping side (server), the unwrapping side can handle both cases. + +> By default Tolgee encodes only key indexes and that requires the usage of the same instance for wrapping and unwrapping. + +Default: `false` + + +### tagAttributes + +Tolgee is able to watch also for wrapped localization strings in attributes of DOM elements. +These attributes must be specified in these configuration properties. + +```ts +tagAttributes: Record<string, string[]>; +``` + +Default: + +```ts +tagAttributes: { + textarea: ['placeholder'], + input: ['value', 'placeholder'], + img: ['alt'], + '*': ['aria-label', 'title'], +} +``` + +### highlightKeys + +By default, in development mode, when you move mouse over an element containing translated text and key ALT is down, this element is highlighted by changing its background color. To modify the key use highlightKeys property. + +```ts +highlightKeys: ModifierKey[]; +``` + +Example: + +```ts +import { ModifierKey } from '../clients/js/packages/core/lib/index'; + +highlightKeys: [ModifierKey.Shift, ModifierKey.Alt]; +``` + +Default: `[ModifierKey.Alt]` + +### highlightColor + +Highlighter border color. + +```ts +highlightColor: string; +``` + +Default: `rgb(255 0 0)` <div style={{ +border: "5px solid rgb(255 0 0)", +borderRadius: "4px", +width: "20px", +height: "20px", +display: "inline-block", +verticalAlign: "middle" +}}></div> + +### highlightWidth + +Border width of highlighter. + +```ts +highlightWidth: number; +``` + +Default: `5px` + +### restrictedElements + +Array of elements in which you don't want Tolgee to replace wrapped strings. + +```ts +restrictedElements: string[]; +``` + +Default: `['script', 'style']` + +### inputPrefix and inputSuffix + +Only for `TextObserver` + +In development mode, strings to be translated are wrapped by `@tolgee/core` library at first and then parsed and replaced with +translated value. This mechanism is called [wrapping](/wrapping.mdx). + +`inputPrefix` is inserted before the encoded string and `inputSuffix` is inserted after the string. By those 2 strings +Tolgee recognises strings, which are meant to be translated, so its good idea to make them unique enough not to collide +with any other strings, which can appear in DOM. + +Example: + +```typescript +inputPrefix = '%-%tolgee:'; +inputSuffix = '%-%'; +``` + +These strings are unique enough to not clash with any other strings in your DOM, so it will not break your document. + +```ts +inputPrefix: string; +``` + +### passToParent + +There are elements which can contain wrapped string to be translated, but user is not able to click on them. For example +an option of `select` HTML element cannot be used for capturing click even with `ALT` down. For these reasons you can +configure Tolgee to "pass" these strings to parent and listen for click events on the parent. + +```ts +passToParent: (keyof HTMLElementTagNameMap)[] | ((node: Element) => boolean); +``` + +Default: `["option", "optgroup"]` \ No newline at end of file diff --git a/js-sdk_versioned_docs/version-5.x.x/api/core_package/options.mdx b/js-sdk_versioned_docs/version-5.x.x/api/core_package/options.mdx new file mode 100644 index 00000000..cfb4c997 --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/api/core_package/options.mdx @@ -0,0 +1,163 @@ +--- +id: options +title: Core Options +sidebar_label: Options +--- + +Initial configuration object of tolgee. + +### language + +Initial language, you need to specify this, unless there is LanguageDetector plugin present. + +```ts +language: string; +``` + +### defaultLanguage + +Used when LanguageDetector plugin fails. + +```ts +defaultLanguage: string; +``` + +### fallbackLanguage + +A language(s) that is used when no translation is available for the current one. + +```ts +fallbackLanguage: string | string[] | Object; +``` + +You can also specify which language should fallback to which individually: + +```ts +fallbackLanguage: { + 'en-GB': 'en', + 'en-IN': ['en-GB', 'en'], + 'es-MX': 'es', +} +``` + +All the fallback languages will be fetched at the start of the application. + +### apiUrl + +Tolgee instance url (e.g. https://app.tolgee.io) + +```ts +apiUrl: string; +``` + +### apiKey + +Project API key (PAK) or Personal Access Token (PAT) + +```ts +apiKey: string; +``` + +### projectId + +Project id is necessary if you are using PAT + +```ts +projectId: number | string; +``` + +### availableLanguages + +Languages which can be used for language detection +and also limits which values can be stored. Is derrived from `staticData` keys if not provided. + +```ts +availableLanguages: string[]; +``` + +### ns + +Namespaces which should be always fetched + +```ts +ns: string[]; +``` + +### fallbackNs + +Namespaces to search when translation is not found. + +```ts +fallbackNs: FallbackNs; +``` + +### defaultNs + +Default namespace when no namespace defined (default: empty string) + +```ts +defaultNs: string; +``` + +### staticData + +These data go directly to cache or you can specify async +function which will be used to get the data. Use `:` to add namespace: + +```ts +staticData: TolgeeStaticData; +``` + +Example: + +```ts +{ + 'locale': { + 'key': 'translation' + }, + // or + 'locale': () => fetchTranslations(), + // or + 'locale:namespace': ... +} +``` + +### onFormatError + +Defines what gets displayed when formatter throws an error. (Default: "invalid") + +```ts +onFormatError: string +onFormatError(error: string, info: TranslationInfo): string +``` + +### onTranslationMissing + +Is called every time translation is missing. +If no orEmpty or defaultValue are defined, return value is rendered. (function is called regardless) + +```ts +onTranslationMissing(info: TranslationInfo): string +``` + +### tagNewKeys + +Specify tags that will be preselected for non-existent keys + +```ts +tagNewKeys: string[] +``` + + +### observerType + +Switches between invisible and text observer if present. (Default: "invisible") + +```ts +observerType: 'invisible' | 'text'; +``` + +### observerOptions + +[Observer options](./observer-options) object. + diff --git a/js-sdk_versioned_docs/version-5.x.x/api/core_package/other_tools.mdx b/js-sdk_versioned_docs/version-5.x.x/api/core_package/other_tools.mdx new file mode 100644 index 00000000..b6ec59af --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/api/core_package/other_tools.mdx @@ -0,0 +1,38 @@ +--- +id: other_tools +title: Other tools +slug: other-tools +--- + +Other helper functions exported in `@tolgee/core`. + +### getTranslateProps + +Takes arguments of `t` function and returns them in standard object. +Use this if you need to wrap `t` function and use it's arguments. + +Example: + +```ts +function myT(...args) { + const props = getTranslateProps(...args); + console.log(props.key); + return tolgee.t(props); +} +``` + +### getFallback + +Used for parameters that can be single value or array or empty. (e.g. `ns`). + +```ts +getFallback(value: FallbackGeneral): string[] | undefined +``` + +### getFallbackArray + +Same as getFallback, but always returns array. + +```ts +getFallbackArray(value: FallbackGeneral): string[] +``` diff --git a/js-sdk_versioned_docs/version-5.x.x/api/core_package/plugin.mdx b/js-sdk_versioned_docs/version-5.x.x/api/core_package/plugin.mdx new file mode 100644 index 00000000..90eeaf2d --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/api/core_package/plugin.mdx @@ -0,0 +1,157 @@ +--- +id: plugin +title: Plugin +slug: plugin-api +description: Plugin is a function which receives tolgee instance and additional `tools` object, where you have access to additional methods for adding different middlewares. +--- + +## TolgeePlugin interface + +Plugin is a function which receives Tolgee instance and additional `tools` object, where you have access +to additional methods for adding different middlewares, it also needs to return tolgee instance at the end. + +```ts +function (tolgee: TolgeeInstance, tools: PluginTools): TolgeeInstance +``` + +## PluginTools + +Tools to manipulate different middleware interfaces. + +### Formatter + +#### Methods + +```ts +tools.setFinalFormatter(formatter: FormatterMiddleware): void; +tools.addFormatter(formatter: FormatterMiddleware): void; +``` + +#### Inteface + +```ts +interface FormatterMiddleware { + format(props: { + translation: string; + language: string; + params: Record<string, any>; + }): string; +} +``` + +Formats translation, allows you to add custom formatter. +There can be multiple formatters, they will be applied in order in which they were added. +`FinalFormatter` is applied last and can return different value than string. + +### Observer + +#### Methods + +```ts +tools.setObserver(observer: ObserverMiddleware): void; +tools.hasObserver(): boolean; +``` + +#### Interface + +```ts +type ObserverMiddleware = (props: ObserverProps) => { + unwrap: (text: string) => Unwrapped; + wrap: WrapperWrapFunction; + retranslate: () => void; + stop: () => void; + run: (props: ObserverRunProps) => void; + highlight: HighlightInterface; + outputNotFormattable: boolean; +}; +``` + +Middleware which enables in-context translating. Check [Observer options](./observer-options). + +### UI + +#### Methods + +```ts +tools.setUi(ui: UiMiddleware): void; +tools.hasUi(): boolean; +``` + +Tolgee UI enables in-context translating. + +### Backend + +#### Methods + +```ts +tools.addBackend(backend: BackendMiddleware): void; +tools.setDevBackend(backend: BackendMiddleware): void; +``` + +#### Interface + +```ts +interface BackendMiddleware { + getRecord(props: { + language: string; + namespace?: string; + }): Promise<TreeTranslationsData | undefined>; +} +``` + +`Backend` middleware is used when `Tolgee` needs to fetch record (identified by language and namespace). +`Backend` can be skipped if `getRecord` returns `undefined`, in that case next backend is used. + +`DevBackend` is used when in dev mode and only difference in interface is that `getRecord` will also +recieve `apiUrl`, `apiKey` and `projectId`. It's used to connect to Tolgee platform. + +### Language detector + +```ts +tools.setLanguageDetector( + languageDetector: LanguageDetectorMiddleware +): void +``` + +#### Interface + +```ts +interface LanguageDetectorMiddleware { + getLanguage: (props: { + availableLanguages: string[]; + }): string | Promise<string>; +} +``` + +Language detector, use for detection from user locale/cookies, etc. + +### Language storage + +```ts +tools.setLanguageStorage( + languageStorage: LanguageStorageMiddleware +): void +``` + +#### Interface + +```ts +interface LanguageStorageMiddleware { + getLanguage(): strin | Promise<string>; + setLanguage(language: string): void | Promise<void>; +} +``` + +Language storage, use for storing language in LocalStorage or on custom server. + +### Override credentials + +```ts +tools.overrideCredentials(credentials: { + apiUrl?: string; + apiKey?: string; + projectId?: string | number; +}): void; +``` + +Method which overrides user credentials to tolgee platform. diff --git a/js-sdk_versioned_docs/version-5.x.x/api/core_package/tolgee.mdx b/js-sdk_versioned_docs/version-5.x.x/api/core_package/tolgee.mdx new file mode 100644 index 00000000..eb8e52b9 --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/api/core_package/tolgee.mdx @@ -0,0 +1,434 @@ +--- +id: tolgee +title: Tolgee +description: TolgeeCore allows you to gradually initialize Tolgee instance. You can repeatedly call `use` and `updateDefaults`. +--- + +## TolgeeCore + +Allows you to gradually initialize Tolgee instance. You can repeatedly call `use` and `updateDefaults`. Finally when you call `init` it will apply everything at once and return `TolgeeInstance`. + +```ts +function TolgeeCore(): TolgeeChainer; +``` + +Basic usage: + +```ts +import { TolgeeCore } from '@tolgee/core'; + +const tolgee = TolgeeCore() + .use(...) + .updateDefaults(...) + .init(...); +``` + +:::info +Constructor called [`Tolgee`](../web_package/plugins#tolgee) is located in `@tolgee/web` package as it automatically includes browser-specific features, which can't be included directly in the core. Use that if you run Tolgee in the browser. +::: + +### use + +Add tolgee plugin. + +```ts +TolgeeCore().use(plugin: TolgeePlugin): TolgeeChainer +``` + +Plugins are applied after `init` is called. To see how TolgeePlugin interface work check [Plugin API](./plugin-api). + +### updateDefaults + +Updates [Tolgee options](./options) before `init` is called. Extends existing options, +so it only changes the fields, that are listed. + +```ts +TolgeeCore().updateDefaults(options: TolgeeOptions): TolgeeChainer +``` + +You can call it multiple times and rewrite only part of the configuration: + +```ts +const tolgee = TolgeeCore() + .updateDefaults({ apiKey: 'key' }) + .updateDefaults({ language: 'en' }) + .init({ apiUrl: 'url' }); +// resulting configuration will be: +{ + apiUrl: 'url', + apiKey: 'key', + language: 'en' +} +``` + +## TolgeeInstance + +Represents initialized tolgee instance. Allows you to read translations and manipulate lanugage or cache. + +### run + +Changes internal state to `running: true` and loads initial files. Starts `Observer` if present. + +```ts +tolgee.run(): Promise<void> +``` + +### stop + +Changes internal state to `running: false` and stops runnable plugins. + +```ts +tolgee.stop(): void +``` + +```ts +tolgee.init(options: TolgeeOptions): TolgeeInstance +``` + +### on + +Allows you to listen to tolgee events. + +```ts +tolgee.on(event: TolgeeEvent, handler: ListenerHandler): Listener +``` + +Returned object has `tolgee.unsubscribe`, call it to stop listening. + +```ts +const listner = tolgee.on(...) +listener.unsubscribe() +``` + +Check [Events](./events) for details. + +### onNsUpdate + +Allows you to listen to key changes of namespaces that you pick. + +```ts +tolgee.onNsUpdate(handler: ListenerHandler): ListenerSelective +``` + +Returns object, which allows you to subscribe to namespaces. + +```ts +const listener = tolgee.onNsUpdate(...) +// subscribes namespace +listener.subscribeNs(ns) +// unsubscribe completely +listener.unsubscribe() +``` + +Use this when you want to make sure, you always update translation when it's necessary. +It internally stores list of namespaces that you are interested in and calls the handler, when necessary. + +### t + +Returns formatted translation based on current language. If `Observer` is present and tolgee is running, `wraps` the result to be identifiable in the DOM. + +```ts +tolgee.t(key: string, defaultValue?: string, options?: CombinedOptions): string +tolgee.t(key: string, options?: CombinedOptions): string +tolgee.t(props: TranslateProps): string +``` + +`t` function provides flexibility in how to pass the options: + +```ts +// with arguments +const translation = t('key', 'default value', { + ns: 'test', + // any unknown property in CombinedOptions is taken as param + parameter: 'parameter', +}); +// with props object +const translation = t({ + key: 'key', + defaultValue: 'default value', + ns: 'test', + params: { parameter: 'parameter' }, +}); +``` + +All the options: + +- `key`: `string` - translation key +- `defaultValue`: `string` - value displayed when no translation is available +- `noWrap`: `boolean` - returns translation without wrapping (default: false) +- `orEmpty`: `boolean` - return empty string instead of key if translation doesn't exist (default: false) +- `params`: `Record<string, value>` object with parameters for the formatter +- `ns`: `string` - namespace, if not provided default namespace is used +- `language`: `string` - override current Tolgee language. This way you can override current language and use different one from the cache. **Language needs to be loaded manually by [`tolgee.loadRecord`](/api/core_package/tolgee.mdx#loadrecord)**. + +> `t` function serves only for reading, not for loading new namespaces or languages. Use [`addActiveNs`](#addactivens) for loading additional namespaces. + +### changeLanguage + +Change current language. + +```ts +tolgee.changeLanguage(language: string): Promise<void> +``` + +- if tolgee is not running sets `pendingLanguage`, `language` to the new value +- if tolgee is running sets `pendingLanguage` to the value, fetches necessary data and then changes `language` + +Returns promise which is resolved when `language` is changed. + +### getLanguage + +Returns current `language` if set. + +```ts +tolgee.getLanguage(): string | undefined +``` + +### getPendingLanguage + +Returns current `pendingLanguage` if set. + +```ts +tolgee.getPendingLanguage(): string | undefined +``` + +`pendingLanguage` represents language which is currently being loaded. + +### addActiveNs + +Adds namespace(s) list of active namespaces and if tolgee is `running`, loads required data. Active namespaces are also loaded automatically when language is changed. + +```ts +tolgee.addActiveNs(ns: FallbackNsTranslation, forget?: boolean): Promise<void> +``` + +- `ns`: `string` | `string[]` - namespace(s) +- `forget`: `boolean` - if true, tolgee only fetches the data, but won't remember namespaces as active, so it won't get loaded automatically on language change + +### removeActiveNs + +Remove namespace(s) from active namespaces. + +```ts +tolgee.removeActiveNs(ns: FallbackNsTranslation): void +``` + +Tolgee internally counts how many times was each active namespace added, +so this method will remove namespace only if the counter goes down to 0. + +```ts +tolgee.addActiveNs('common'); +tolgee.addActiveNs(['common', 'component']); +// active namespaces: {common: 2, component: 1} +tolgee.removeActiveNs(['common', 'component']); +// active namespaces: {common: 1} +tolgee.removeActiveNs('common'); +// active namespaces: {} +``` + +This is used in component lifecycles, where we want to keep track which namespaces are needed, when language changes. + +### isRunning + +Returns `true` if tolgee is running. + +```ts +tolgee.isRunning(): boolean +``` + +### isInitialLoading + +Returns `true` if tolgee is loading initial data (triggered by `run`). + +```ts +tolgee.isInitialLoading(): boolean +``` + +### isFetching + +Returns `true` if tolgee is fetching any data. + +```ts +tolgee.isFetching(ns?: FallbackNsTranslation): boolean +``` + +- `ns`: `string` | `string[]` - optional list of namespaces that you are interested in + +### isLoading + +Returns `true` if tolgee is loading initial data or when new namespace is added. When you are changing language +this won't get triggered. Basically indicates, that Tolgee doesn't have all the neccessary data available. + +```ts +tolgee.isLoading(ns?: FallbackNsTranslation): boolean +``` + +- `ns`: `string` | `string[]` - optional list of namespaces that you are interested in + +### isLoaded + +Similar to `isLoading`, but can be called before the actual loading starts. This function is mostly useful +when you need to find out if tolgee has all the necessary data before `run` function is triggered. + +```ts +tolgee.isLoaded(ns?: FallbackNsTranslation): boolean +``` + +### getRequiredRecords + +Returns records needed for instance to be `loaded` + +```ts +tolgee.getRequiredRecords(): CacheDescriptor[] +``` + +- `ns`: `string` | `string[]` - optional list of namespaces that you are interested in + +### isDev + +Returns `true` if tolgee is in dev mode. +Tolgee is in dev mode if `DevTools` plugin is used and `apiKey` + `apiUrl` is specified. + +```ts +tolgee.isDev(): boolean +``` + +### setEmitterActive + +Turn off/on events emitting. Is on by default. + +```ts +tolgee.setEmitterActive(active: boolean) +``` + +### getInitialOptions + +Returns current [Tolgee options](./options). + +```ts +tolgee.getInitialOptions(): TolgeeOptions +``` + +### highlight + +Highlights keys that match selection. + +```ts +tolgee.highlight(key?: string, ns?: FallbackNsTranslation): Highlighter +``` + +Returns object with `unhighlight` method. + +### wrap + +Wraps translation if there is `Observer plugin`. + +```ts +tolgee.wrap(params: TranslatePropsInternal): string | undefined +``` + +### unwrap + +Returns wrapped translation info. + +```ts +tolgee.unwrap(text: string): Unwrapped +``` + +### loadRecord + +Manually load record from `Backend` (or `DevBackend` when in dev mode). + +```ts +tolgee.loadRecord(descriptors: CacheDescriptor): Promise<TranslationsFlat> +``` + +### loadRecords + +Manually load multiple records from `Backend` (or `DevBackend` when in dev mode). + +```ts +tolgee.loadRecords(descriptors: CacheDescriptor[]): Promise<TranslationsFlat[]> +``` + +It loads data together and adds them to cache in one operation, to prevent partly loaded state. + +### getRecord + +Get record from cache. + +```ts +tolgee.getRecord(descriptors: CacheDescriptor[]): TranslationsFlat | undefined +``` + +### getAllRecords + +Get all records from cache. + +```ts +tolgee.getAllRecords(): CachePublicRecord[] +``` + +### addStaticData + +Add data to cache. It will only rewrite cache if there are no dev data loaded. + +Example: + +```ts +tolgee.addStaticData({ + 'locale': { + 'key': 'translation' + }, + // or + 'locale': () => fetchTranslations(), + // or + 'locale:namespace': ... +}) +``` + +```ts +tolgee.addStaticData(data: TolgeeStaticData): CachePublicRecord[] +``` + +### changeTranslation + +Temporarily change translation in cache. + +```ts +tolgee.changeTranslation(descriptor: CacheDescriptor, key: string, value: string): TranslationChanger +``` + +Returns object with `revert` method. + +### overrideCredentials + +Override creadentials passed on initialization. When called in running state, tolgee stops and runs again. + +```ts +tolgee.overrideCredentials(credentials: DevCredentials) +``` + +```ts +type DevCredentials = { + apiUrl?: string; + apiKey?: string; + projectId?: string | number; +}; +``` + +### addPlugin + +Add tolgee plugin after initialization. When called in running state, tolgee stops and runs again. To see how TolgeePlugin interface work check [Plugin API](./plugin-api). + +```ts +tolgee.addPlugin(plugin: TolgeePlugin | undefined) +``` + +### updateOptions + +Updates [Tolgee options](./options) after instance creation. Extends existing options, so it only changes the fields, that are listed. When called in `running` state, tolgee stops and runs again. + +```ts +tolgee.updateOptions(options?: TolgeeOptions) +``` diff --git a/js-sdk_versioned_docs/version-5.x.x/api/packages.mdx b/js-sdk_versioned_docs/version-5.x.x/api/packages.mdx new file mode 100644 index 00000000..c0173c9d --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/api/packages.mdx @@ -0,0 +1,32 @@ +--- +id: packages +title: Packages +sidebar_label: Packages +slug: /sdk/packages +--- + +Tolgee SDK is split into several npm packages. + +## Dependency graph + + + +### @tolgee/core + +Main `Tolgee` module, which is highly extensible with plugins. Its main purpose is to manage the translations cache +and provide access to it through the `t` method (which returns translation by key). It also allows you to listen +to language changes, translation changes, cache changes etc. + +### @tolgee/web + +Extends `@tolgee/core` with web-specific modules. Mainly it contains `InContextTools`/`DevTools` plugins. +These plugins allow you to connect to `tolgee platform` and edit your translations directly in your app +(read more in [In-context translating](/in_context.mdx)). + +### Integration libraries + +Provide framework/library specific wrappers around `Tolgee`. + +### @tolgee/format-icu + +Provides plugin for [Icu message format](/platform/translation_process/icu_message_format). diff --git a/js-sdk_versioned_docs/version-5.x.x/api/web_package/about.mdx b/js-sdk_versioned_docs/version-5.x.x/api/web_package/about.mdx new file mode 100644 index 00000000..dc082a05 --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/api/web_package/about.mdx @@ -0,0 +1,29 @@ +--- +id: about +title: About +sidebar_label: About +--- + +## Tolgee web + +Tolgee web package contains all general web-related tools. Mainly connected to in-context translating as it is tightly coupled to the DOM and web environment. Tolgee exports everything from `@tolgee/core`, so you can just install this package if you use Tolgee on the web. + +It contains these basic parts: + +- [`Tolgee`](./plugins#tolgee) +- [`LanguageStorage`](./plugins#languagestorage) +- [`LanguageDetector`](./plugins#languagedetector) +- [`BackendFetch`](./plugins#backendfetch) +- [`DevTools`](./tools#devtools) +- [`DevBackend`](./plugins#devbackend) +- [`ObserverPlugin`](./plugins#observerplugin) +- [`BrowserExtensionPlugin`](./plugins#browserextensionplugin) +- [Constants](./constants) +- \+ everything from [`@tolgee/core`](../core_package/about) + +Plus in-context tools: + +- [`InContextTools`](./tools#incontexttools) +- [`ContextUi`](./tools#contextui) + + diff --git a/js-sdk_versioned_docs/version-5.x.x/api/web_package/constants.mdx b/js-sdk_versioned_docs/version-5.x.x/api/web_package/constants.mdx new file mode 100644 index 00000000..bcdd8a60 --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/api/web_package/constants.mdx @@ -0,0 +1,19 @@ +--- +id: constants +title: Constants +slug: constants +--- + +```ts +// name of attribute, which is used on html elements +// that are active for user to click in-context +const TOLGEE_ATTRIBUTE_NAME = '_tolgee'; + +// use this attribute on any html element with translation key +// and it will be in-context clickable +const TOLGEE_WRAPPED_ONLY_DATA_ATTRIBUTE = 'data-tolgee-key-only'; + +// use this attribute when you want to disable tolgee observer +// on html element and all it's children +const TOLGEE_RESTRICT_ATTRIBUTE = 'data-tolgee-restricted'; +``` diff --git a/js-sdk_versioned_docs/version-5.x.x/api/web_package/plugins.mdx b/js-sdk_versioned_docs/version-5.x.x/api/web_package/plugins.mdx new file mode 100644 index 00000000..56b75189 --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/api/web_package/plugins.mdx @@ -0,0 +1,110 @@ +--- +id: plugins +title: Plugins +sidebar_label: Plugins +--- + +## Tolgee + +[`TolgeeCore`](../core_package/tolgee#tolgeecore) with added [`BrowserExtensionPlugin`](./plugins#browserextensionplugin). + +Usage: + +```ts +const tolgee = Tolgee() + .use(...) + .updateDefaults(...) + .init(...) +``` + +## `LanguageStorage` + +Plugin for storing current language in `localStorage`. It remembers the language if the user changed it. + +```ts +tolgee.use(LanguageStorage()); +``` + +:::info +Don't use [`language`](https://tolgee.io/js-sdk/api/core_package/options#language) property with this plugin, as it will hard-override the languge. Instead use [`defaultLanguage`](https://tolgee.io/js-sdk/api/core_package/options#defaultlanguage). +::: + +## `LanguageDetector` + +Plugin for language detection from the user's browser locale. It requires `staticData` or `availableLanguages` to be defined in Tolgee options, as it matches the locale with it. + +```ts +tolgee.use(LanguageDetector()); +``` + +:::info +Don't use [`language`](https://tolgee.io/js-sdk/api/core_package/options#language) property with this plugin, as it will hard-override the languge. Instead use [`defaultLanguage`](https://tolgee.io/js-sdk/api/core_package/options#defaultlanguage). +::: + +## `BackendFetch` + +Plugin for fetching translations JSON files. + +```ts +tolgee.use(BackendFetch(options?: BackendOptions)); +``` + +Pass `BackendOptions` to customize the behavior: + +### `options.prefix` + +Pass string to change URL prefix, use can use relative or absolute paths (Default: `/i18n`) + +### `options.getPath` + +Combines prefix, namespace and language and generates file path. + +```ts +function ({ prefix, namespace, language }): string +``` + +Default returns `{prefix}/{namespace}/{language}.json` or `{prefix}/{language}.json` when namespace is empty. + +### `options.getData` + +Parses data from response, by default it returns `r.json()`. + +```ts +function (r: Response): Promise<any>; +``` + +### `options.headers` + +Pass custom headers. Default: `{ Accept: 'application/json' }` + +## `DevTools` + +It's a combination [`ObserverPlugin`](./plugins#observerplugin), [`ContextUi`](./tools#contextui) and [`DevBackend`](./plugins#devbackend) in one plugin, intended to enable in-context capabilities. It only applies plugins if there they are not already applied. + +`DevTools` are automatically omitted in production builds (based on `NODE_ENV` variable). + +If you need include in-context tools in your production build check [`InContextTools`](/api/web_package/tools.mdx#incontexttools), which are completely equivalent to `DevTools`, only without auto-omitting logic. + + +## `DevBackend` + +Plugin for communication with Tolgee platform uses `apiUrl`, `apiKey` (+ `projectId`) from Tolgee options. + +```ts +tolgee.use(DevBackend()); +``` + +## `ObserverPlugin` + +Plugin which wraps translations and observes the DOM, so it's able to locate translations on the page. Read more in [this article](/blog/2021/12/17/invisible-characters-for-better-localization). + +```ts +tolgee.use(ObserverPlugin()); +``` + +You can influence the behavior of this plugin through [`observer options`](../core_package/observer-options). + + +## `BrowserExtensionPlugin` + +Plugin which connects Tolgee to [Tolgee Tools browser extension](https://chrome.google.com/webstore/detail/tolgee-tools/hacnbapajkkfohnonhbmegojnddagfnj). This plugin is automatically included in Tolgee, if you import it from `@tolgee/web`. diff --git a/js-sdk_versioned_docs/version-5.x.x/api/web_package/tools.mdx b/js-sdk_versioned_docs/version-5.x.x/api/web_package/tools.mdx new file mode 100644 index 00000000..820ca928 --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/api/web_package/tools.mdx @@ -0,0 +1,50 @@ +--- +id: tools +title: Tools +sidebar_label: Tools +slug: tools +--- + + +As `DevTools` are automatically omitted on production, `@tolgee/web/tools` can be used to include it unconditionally. + +:::info +Tools were moved from `@tolgee/web` in version 5.2.0. +::: + +## `InContextTools` + + +Similar to [`DevTools`](./plugins#devtools). Use `InContextTools` only if you know what you are doing. + +It's a combination [`ObserverPlugin`](./plugins#observerplugin), [`ContextUi`](./tools#contextui) and [`DevBackend`](./plugins#devbackend) in one plugin, which you can use when you want to enable in-context capability anywhere. It only applies plugins if there they are not already applied. You can optionally provide credentials to Tolgee platform, which will override anything that was set before. + +This plugin is automatically downloaded and applied by [`BrowserExtensionPlugin`](./plugins#browserextensionplugin) when you enable in-context translating. + +```ts +import { InContextTools } from '@tolgee/web/tools' + +tolgee.use(InContextTools(props?: InContextOptions)); +``` + +```ts +type InContextOptions = { + credentials: { + apiUrl?: string; + apiKey?: string; + projectId?: string | number; + }; +}; +``` + +Can be applied even when `Tolgee` is already running. + +## `ContextUi` + +Tolgee in-context modal, which allows you to edit translation in-context. + +```ts +import { ContextUi } from '@tolgee/web/tools' + +tolgee.use(ContextUi()); +``` diff --git a/js-sdk_versioned_docs/version-5.x.x/filter_by_tags.mdx b/js-sdk_versioned_docs/version-5.x.x/filter_by_tags.mdx new file mode 100644 index 00000000..4b473a6e --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/filter_by_tags.mdx @@ -0,0 +1,17 @@ +--- +id: filter_by_tags +title: Filter keys by tags +description: '' +--- + +You can configure Tolgee to only use keys with certain tags. This can be useful if you are sharing translations e.g. between multiple platforms (e.g. web and mobile). + +```ts +const tolgee = Tolgee() + .init({ + filterTag: ['web'] + ... + }) +``` + +With this setup, Tolgee SDK will only load keys with the given tag. If you specify multiple tags, keys with any of the specified tags will be loaded. \ No newline at end of file diff --git a/js-sdk_versioned_docs/version-5.x.x/formatting.mdx b/js-sdk_versioned_docs/version-5.x.x/formatting.mdx new file mode 100644 index 00000000..457b1412 --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/formatting.mdx @@ -0,0 +1,56 @@ +--- +id: formatting +title: Formatting +description: 'Learn how to use in-context translating feature in Tolgee tool and how to enable in-context translating on production.' +--- + +Formating is a way how to render translation into a final string, with variable parameters. Formatters are supported in form of [plugin](./plugins.mdx). + +## Simple formatter + +[`FormatSimple`](./api/core_package/format-simple) plugin if you just need to include variables in your translations. It is very minimalistic, only intended to interpolate your parameters and save your bundle size. + +```ts +import { FormatSimple } from '@tolgee/web'; +... +tolgee.use(FormatSimple()); +``` + +### Example + +```ts +tolgee.t('basket_items', '{count} items in the basket', { count: 10 }) +// -> 10 items in the basket +``` + +## Icu formatter + +For advanced formatting functionality install `FormatIcu` plugin, which is shipped in separate package. + +import { InstallationTabs } from '../../src/component/InstallationTabs'; + +<InstallationTabs lib="@tolgee/format-icu" /> + +Use it like this: + +```ts +import { FormatIcu } from '@tolgee/format-icu'; + +tolgee.use(FormatIcu()); +``` + +### Examples + +```ts +tolgee.t('progress', 'Progress: {progress, number, percent}', { progress: 0.1 }) +// -> Progress: 10% + +tolgee.t('basket_items', '{count, plural, one {# item} other {# items}} in the basket', { count: 10 }) +// -> 10 items in the basket +``` + +Read more about [ICU message format](/platform/translation_process/icu_message_format) + +:::info +For react-native you might need to polyfill `Intl` object. Use [`@formatjs/intl-locale`](https://formatjs.github.io/docs/polyfills/intl-locale) and [`@formatjs/intl-pluralrules`](https://formatjs.github.io/docs/polyfills/intl-pluralrules) to make plurals work. +::: diff --git a/js-sdk_versioned_docs/version-5.x.x/get_started.mdx b/js-sdk_versioned_docs/version-5.x.x/get_started.mdx new file mode 100644 index 00000000..784e5e19 --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/get_started.mdx @@ -0,0 +1,20 @@ +--- +id: get_started +title: Get started +description: 'Learn how to get started with the Tolgee SDK for seamless localization. Use framework-specific SDKs or the vanilla JavaScript SDK to easily integrate localization into your application.' +--- + +Tolgee SDK supports multiple frameworks and libraries. These specific SDKs are all based on the [`@tolgee/web`](./api/web_package/about) package. Tolgee also integrates seamlessly with [i18next](https://www.i18next.com/). Use [Tolgee's i18next plugin](./integrations/i18next/installation) if you are already using i18next or need more advanced featured offered by i18next. You can also use Tolgee with [Vanilla JavaScript](./integrations/vanilla/installation). + +Below is a list of all the available frameworks and libraries Tolgee supports today. To get started, install the package and follow the instructions for the respective framework or library. + +## Integrations + +- [React](./integrations/react/overview) + - [Next.js](./integrations/react/next/introduction) + - [React Native](./integrations/react/react_native) +- [Angular](./integrations/angular/overview) +- [Svelte](./integrations/svelte/overview) +- [Vue](./integrations/vue/overview) +- [i18next library](./integrations/i18next/installation) +- [Vanilla JS](./integrations/vanilla/installation) diff --git a/js-sdk_versioned_docs/version-5.x.x/in_context.mdx b/js-sdk_versioned_docs/version-5.x.x/in_context.mdx new file mode 100644 index 00000000..c0eab3c8 --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/in_context.mdx @@ -0,0 +1,98 @@ +--- +id: in_context +title: In-context translating +slug: in-context +description: 'Learn how to use in-context translating feature in Tolgee tool and how to enable in-context translating on production.' +--- + +For local development, supply `apiUrl`, `apiKey` options (see [Integration](/platform/integrations/about_integrations)) and [`DevTools`](./api/web_package/tools#devtools) plugin. If you set everything properly, you can use in-context translating: + +1. Press and hold `Alt`/`Option` key +2. Navigate mouse over any translation on your website +3. It should get highlighted +4. Click on it to open "Quick translation" dialog +5. You can edit translations (changes will get stored to Tolgee platform) + +> NOTE: If you use Tolgee without any integration, make sure you call [`run`](./api/core_package/tolgee.mdx#run) method. + +## One-click screenshots + +To generate screenshots automatically, you have to have installed +[Tolgee Tools](https://chrome.google.com/webstore/detail/tolgee-tools/hacnbapajkkfohnonhbmegojnddagfnj) plugin +for Google Chrome browser. With this plugin, you can generate screenshots by clicking camera icon in Tolgee UI +translation dialog. + +:::info +[`DevTools`](./api/web_package/tools#devtools) are automatically omitted in production builds (based on `NODE_ENV` variable). +::: + +## In-context on production + +If you want to enable in-context on production build, there are two options: + +### 1. Tolgee Chrome plugin + +To enable in-context translating on production you can pass `apiKey` and `apiUrl` through [Tolgee Tools](https://chrome.google.com/webstore/detail/tolgee-tools/hacnbapajkkfohnonhbmegojnddagfnj) plugin, that way Tolgee will switch to development mode (plugin will also supply `@tolgee/ui` package automatically). + +:::warning +Never include `apiKey` in Tolgee configuration on production. +This property is intended only for local development, as it's not meant to be publicly visible. +::: + +1. Install [Tolgee Tools](https://chrome.google.com/webstore/detail/tolgee-tools/hacnbapajkkfohnonhbmegojnddagfnj) plugin +2. Go to the production version of your website +3. Click on Tolgee Tools extension and apply your API key (you might need to reload if you just installed the plugin) +4. In-context translating should work + +> You can also check [Step-by-step tutorial](/blog/in-context-production) + +#### A few notes about Tolgee Tools plugin + +- You can turn off development mode by switching "Applied" toggle, which will turn it off, but stores credentials locally so you don't have to fill it again next time +- Plugin will supply `apiUrl` from Tolgee configuration if it's present (if not you can fill it manually) +- Plugin changes its icon if Tolgee is present on the page or if credentials are set + +### 2. Using InContextTools instead of DevTools + +DevTools are automatically omitted in production build (based on `NODE_ENV` variable), if you want to enable In-context unconditionally, you can use [`InContextTools`](/api/web_package/tools.mdx#incontexttools) (from `@tolgee/web/tools` package). + +Note that [`InContextTools`](/api/web_package/tools.mdx#incontexttools) will significantly increase your bundle size, so we recommend using dynamic import and only including them when needed. + +:::warning +In-context on production should be always behind some authentication or in a private network. Make sure you are not exposing your credentials publicly. +::: + +```ts +// initialize tolgee without DevTools +const tolgee = Tolgee() + .use(FormatSimple()) + .init({ + ... + }); + +// include in-context tools only if needed +if (shouldIncludeInContextTools) { + import('@tolgee/web/tools').then((module) => { + tolgee.addPlugin(module.InContextTools()) + }) +} +``` + +#### Using parts of InContextTools functionality + +[`InContextTools`](/api/web_package/tools.mdx#incontexttools) (or `DevTools` in development) are a combination of multiple plugins, which you can include independently, check [`InContextTools`](/api/web_package/tools.mdx#incontexttools) documentation for more info. + +## Modals, popovers and other focus-stealing elements +Some elements like modals or popovers can steal focus from the Tolgee dev tools, +so you can't type in the translation input fields. + +Fortunately, you can still use the dev tools by opening them in a separate popup window by clicking the icon next to the `Quick translation` dialog title. + +Your browser might block the popup, so you have to allow it. + +import { ScreenshotWrapper } from '../../platform/shared/_ScreenshotWrapper'; + +<ScreenshotWrapper + src="/img/docs/sdk/in_context_modal.webp" + alt="Open new window button" +/> diff --git a/js-sdk_versioned_docs/version-5.x.x/integrations/angular/api.mdx b/js-sdk_versioned_docs/version-5.x.x/integrations/angular/api.mdx new file mode 100644 index 00000000..5c8f2e2c --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/integrations/angular/api.mdx @@ -0,0 +1,187 @@ +--- +id: api +title: API +sidebar_label: API +description: "Tolgee enables you to implement localization in your Angular application with ease. You can integrate Tolgee in your Angular application using Tolgee's integration library for Angular. Learn about NgxTolgeeModule, TranslateService, T-component, and other APIs." +--- + +The `@tolgee/ngx` library exports the following components and all available components from [`@tolgee/web`](/api/web_package/about.mdx). + +## NgxTolgeeModule + +This is Tolgee Module. The module exports [`TranslatePipe`] and [`TComponent`]. To use Tolgee in your Angular application, you must import the `NgxTolgeeModule` in your application module. + +Example usage: + +```ts +@NgModule({ + imports: [ + NgxTolgeeModule, + ... + ], + providers: [ + { + provide: TOLGEE_INSTANCE, + ... + }, + ], + ... +}) +``` + +## TOLGEE_INSTANCE + +The injection token to provide [Tolgee instance](/api/core_package/tolgee.mdx). + +```ts +@NgModule({ + imports: [ + NgxTolgeeModule, + ... + ], + providers: [ + { + provide: TOLGEE_INSTANCE, + useFactory: () => { + return Tolgee() + .use(LanguageDetector()) + .use(FormatIcu()) + .use(DevTools()) + .init({ + staticData: { + en: () => import('../i18n/en.json'), + cs: () => import('../i18n/cs.json'), + }, + apiUrl: environment.tolgeeApiUrl, + apiKey: environment.tolgeeApiKey, + fallbackLanguage: 'en', + defaultLanguage: 'en', + }); + }, + }, + ], + ... +}) +``` + +## TranslateService + +Contains methods to translate text used by other components. + +### property `tolgee` + +The [Tolgee instance](/api/core_package/tolgee.mdx). + +### property `language` + +Returns `string` containing current language. + +```ts +this.translateService.language // "en" +``` + +### property `languageAsync` + +Returns `Observable<string>` emitting current language. When language is changed and loaded, the new value is emitted. + +### method `changeLanguage` + +Sets current language. + +```ts +this.translateService.setLang('en'); +``` + +### method `translate` + +Returns `Observable` emitting current translation for specified parameters and current language. When the current value changes due to an event (e.g. language change), the new value gets emitted. + +```ts +this.subscription = this.translateService + .translate('this_is_a_key_with_params', { key: 'value' }, 'Default value') + .subscribe((val) => (this.translated = val)); +``` + +This method accepts the same arguments as [`Tolgee.t`](/api/core_package/tolgee.mdx#t) method. + +```ts +translate(key: string, defaultValue?: string, options?: CombinedOptions): Observable<string> +translate(key: string, options?: CombinedOptions): Observable<string> +translate(props: TranslateProps): Observable<string> +``` + +### method `instant` + +Returns `string` providing current translation value depending on the current language. + +```ts +const translated = this.translateService + .instant('this_is_a_key_with_params', { key: 'value' }, 'Default value') +``` + +This method accepts the same arguments as [`Tolgee.t`](/api/core_package/tolgee.mdx#t) method. + +```ts +instant(key: string, defaultValue?: string, options?: CombinedOptions): string +instant(key: string, options?: CombinedOptions): string +instant(props: TranslateProps): string +``` + +#### parameter language + +The language to be set. + +returns `Promise<void>` relved when language data is loaded + +### method `on` + +Listens to Tolgee events. + +#### parameter `event` + +The event to listen to + +returns `Observable<?>` emitting when the event is triggered, providing [event-specific data](/api/core_package/events.mdx). + +Read more in [Events API](/api/core_package/events.mdx) + +### method start + +Runs the `Tolgee.run` method from the `@tolgee/core` library outside Angular's NgZone. + +### TComponent + +Component with `t` attribute selector. Replaces the content of the element with the translated value. + +- Input `key` - Key to translate +- Input `ns` - The namespace of the key +- Input `params` - Object of parameters to interpolate +- Input `default` - Default value +- Input `isHtml` - Whether the input should be treated as HTML. +- Input `noWrap` - Disable wrapping +- Input `language` - Override current Tolgee language. This way you can switch to different language for separate translation. Load the language manually with [`tolgee.loadRecord`](/api/core_package/tolgee.mdx#loadrecord). + +```html +<div + t + key="this_is_a_key_with_params" + [params]="{key: 'value', key2: 'value2'}" +></div> +``` + +### `translate` pipe + +Translates a key with specific parameters or default value. The transform method of `translate` pipe accepts the same arguments as the [`tolgee.t`](/api/core_package/tolgee.mdx#t) method. + +Example usages: + +```html +{{ 'this_key_does_not_exist' | translate:'This is default'}} +{{ 'this_is_a_key_with_params' | translate:{key: 'value', key2: 'value2'} }} +{{ 'this_is_a_key_with_params' | translate:"Default value":{key: 'value', key2: 'value2'} }} +{{ { key: 'this_is_a_key', defaultValue: 'Jeeey!' } | translate}} +``` + +## NamespaceResolver + +A resolver to load namespaces while loading lazy module. Set `data.tolgeeNamespace` property to set the namespace to load. diff --git a/js-sdk_versioned_docs/version-5.x.x/integrations/angular/html_tags.mdx b/js-sdk_versioned_docs/version-5.x.x/integrations/angular/html_tags.mdx new file mode 100644 index 00000000..9f6ad597 --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/integrations/angular/html_tags.mdx @@ -0,0 +1,35 @@ +--- +id: html_tags +title: Strings with HTML Tags +sidebar_label: Strings with HTML Tags +description: "Tolgee enables you to implement localization in your Angular application with ease. You can integrate Tolgee in your Angular application using Tolgee's integration library for Angular. Learn how to render i18n strings with HTML tags in Angular." +--- + +You can render HTML tags in translations using the [`t` attribute](./translating#t-attribute) or the [`translate` pipe](./translating#translate-pipe). + +To render a translation containing HTML tags using pipe, you must set the translated value via the `innerHTML` attribute of the wrapping component. + +Consider a translation for the key `hello_peter` with the English value `Hello <b>Peter</b>!` + +You can render it using the `translate` pipe as follows: +```html +<div [innerHTML]="'hello_peter' | translate"></div> +``` + +To render a translation containing HTML tags using the `t` attribute, you must set the translated value via the `innerHTML` attribute of the wrapping component. + +```html +<div t key="hello_peter" [isHtml]="true"></div> +``` + +## Security + +Tolgee sanitizes HTML tags in translations. It removes all HTML tags and attributes that are not allowed. + +The HTML is automatically sanitized for both `t` component and `translate` pipe. However, if you don't expect HTML strings in your code, avoid passing the strings using innerHtml. + +```html +<b onmouseover=alert('XSS testing!')>Hello Peter!</b> +``` + +The above code is sanitized to: `<b>Hello Peter!</b>` diff --git a/js-sdk_versioned_docs/version-5.x.x/integrations/angular/installation.mdx b/js-sdk_versioned_docs/version-5.x.x/integrations/angular/installation.mdx new file mode 100644 index 00000000..8d645d6c --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/integrations/angular/installation.mdx @@ -0,0 +1,93 @@ +--- +id: installation +title: Installation +sidebar_label: Installation +description: "Tolgee enables you to implement localization in your Angular application with ease. You can integrate Tolgee in your Angular application using Tolgee's integration library for Angular. To use this library, start by installing Tolgee." +--- + +import { InstallationTabs } from '../../../../src/component/InstallationTabs'; +import PreparingForProduction from '../../shared/_PreparingForProduction.mdx'; +import ExampleBanner from '../../shared/ExampleBanner'; + +To use Tolgee in your Angular application, you need to follow these steps: + +1. [Install the Tolgee integration library](#install-the-tolgee-integration-library) +2. [Configure the Tolgee API](#configure-the-tolgee-module) +3. [Set up the environment variables](#set-up-the-environment-variables) +4. [Preparing for production](#preparing-for-production) + +## Install the Tolgee integration library + +To install Tolgee integration library, run the following command: + +<InstallationTabs lib="@tolgee/ngx" /> + +## Configure the Tolgee module + +Once the library is installed, you need to import and initialize the `NgxTolgeeModule` in your module file (`app.module.ts` or other). + +The updated code should look like this: + +```typescript +... +import { + DevTools, + NgxTolgeeModule, + Tolgee, + TOLGEE_INSTANCE, + FormatSimple +} from '@tolgee/ngx'; +... +@NgModule({ + declarations: [ + ... + ], + imports: [ + NgxTolgeeModule, + ... + ], + providers: [ + { + provide: TOLGEE_INSTANCE, + useFactory: () => { + return Tolgee() + .use(DevTools()) + .use(FormatSimple()) + // replace with .use(FormatIcu()) for rendering plurals, foramatted numbers, etc. + .init({ + language: 'en' + + // for development + apiUrl: environment.tolgeeApiUrl, + apiKey: environment.tolgeeApiKey, + + // for production + staticData: { + ... + } + }); + }, + }, + ], + bootstrap: [AppComponent], +}) +export class AppModule {} +``` + +The above code does the following: + +- Imports the required moudle, classes, and plugins from the integration library. +- Configures the module +- Configures the Tolgee instance to use the [DevTools](../../api/web_package/plugins#devtools) and [FormatSimple](../../api/core_package/format-simple) plugins, and initializes it using the credentials. + +> You can configure more options and plugins during initialization. Learn about these other [options](../../api/core_package/options) and [Tolgee plugins](../../plugins) in their respective documentation. + +## Set up the environment variables + +Follow the instructions mentioned in the [angular application environments documentation](https://angular.io/guide/build#configuring-application-environments) to configure `apiUrl` and `apiKey`. + +## Preparing for production + +<PreparingForProduction /> + +<ExampleBanner framework="Angular" appName="ngx" /> \ No newline at end of file diff --git a/js-sdk_versioned_docs/version-5.x.x/integrations/angular/namespaces.mdx b/js-sdk_versioned_docs/version-5.x.x/integrations/angular/namespaces.mdx new file mode 100644 index 00000000..241ab94f --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/integrations/angular/namespaces.mdx @@ -0,0 +1,40 @@ +--- +id: namespaces +title: Namespaces +sidebar_label: Namespaces +description: "Tolgee enables you to implement localization in your Angular application with ease. You can integrate Tolgee in your Angular application using Tolgee's integration library. You can split your i18n data into multiple namespaces using Tolgee. Learn more about using namespaces." +--- + +Tolgee allows you to split your i18n data into multiple namespaces. When using the [`translate pipe`](./translating#translate-pipe), [`t attribute`](./translating#t-attribute), or [`translation methods`](./translating#translation-methods), Tolgee automatically loads the namespace data for you. + +Ideally, you should split translations for each module into different namespaces. For a lazy module, wait for the i18n data to be fetched before loading the lazy module. You can achieve this with `NamespaceResolver`. + +```ts +... +import { NamespaceResolver } from '@tolgee/ngx'; + +const routes: Routes = [ + ... + { + path: 'lazy', + loadChildren: () => import('./lazy/lazy.module').then((m) => m.LazyModule), + data: { tolgeeNamespace: 'my-loaded-namespace' }, + resolve: { + _namespace: NamespaceResolver, + }, + }, +]; + +@NgModule({ + imports: [ + RouterModule.forRoot(routes, ...), + ], + exports: [RouterModule], +}) +export class AppRoutingModule {} +``` + +When using `NamespaceResolver`, provide `tolgeeNamespace` property to the `data` object +of your route configuration as defined in the above example. + +You can learn more in the [namespaces documentation](../../namespaces.mdx). diff --git a/js-sdk_versioned_docs/version-5.x.x/integrations/angular/overview.mdx b/js-sdk_versioned_docs/version-5.x.x/integrations/angular/overview.mdx new file mode 100644 index 00000000..8a54de7b --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/integrations/angular/overview.mdx @@ -0,0 +1,11 @@ +--- +id: overview +title: Tolgee with Angular +sidebar_label: Overview +description: "Get started with Tolgee's integration for Angular. Learn how to add localization to your Angular applications." +--- + +Tolgee provides an SDK for Angular, based on the [`@tolgee/web`](../../api/web_package/about) package. Using the SDK [@tolgee/ngx](https://www.npmjs.com/package/@tolgee/ngx), you can connect your Angular application to the Tolgee platform. This SDK enables you to implement [in-context translations](../../in-context), [language detection](../../language#language-detection), interpolation, and other advanced features. + +- Follow the [installation guide](./installation) to add the Tolgee Angular SDK to your existing Angular application. +- You can also check the [example application](https://github.com/tolgee/ngx-example) to see how to integrate Tolgee with Angular. diff --git a/js-sdk_versioned_docs/version-5.x.x/integrations/angular/switching_language.mdx b/js-sdk_versioned_docs/version-5.x.x/integrations/angular/switching_language.mdx new file mode 100644 index 00000000..b832c5b9 --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/integrations/angular/switching_language.mdx @@ -0,0 +1,38 @@ +--- +id: switching_language +title: Switching language +sidebar_label: Switching language +slug: switching-language +description: "Tolgee enables you to implement localization in your Angular application with ease. You can integrate Tolgee in your Angular application using Tolgee's integration library for Angular. Learn to manage language change using the TranslationService" +--- + +To manage an event like language change, the Tolgee integration provides the [`TranslationService`](./api#translateservice). + +Initialize the `TranslationService` in your component as follows: + +```ts title="language.component.ts" +import { Component } from '@angular/core'; +import { TranslateService } from '@tolgee/ngx'; + +@Component({ + ... +}) +export class AppComponent { + constructor(public translateService: TranslateService) {} + ... +} +``` + +Next, in template use the [`changeLanguage` method](./api#method-changelanguage) and [`languageAsync` property](./api#property-languageasync) from `TranslateService` to handle the language change. + +```html title="language.component.html" +<select + [value]="translateService.languageAsync | async" + (change)="translateService.changeLanguage($event.target.value)" +> + <option value="en">🇬🇧 English</option> + <option value="cs">🇨🇿 Česky</option> +</select> +``` + +> Learn more about language change, detection and storage on the [Language documentation page](../../language). \ No newline at end of file diff --git a/js-sdk_versioned_docs/version-5.x.x/integrations/angular/translating.mdx b/js-sdk_versioned_docs/version-5.x.x/integrations/angular/translating.mdx new file mode 100644 index 00000000..6dd79098 --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/integrations/angular/translating.mdx @@ -0,0 +1,126 @@ +--- +id: translating +title: Translating +sidebar_label: Translating +description: "Tolgee enables you to implement localization in your Angular application with ease. You can integrate Tolgee in your Angular application using Tolgee's integration library for Angular. Learn to impelement translation using the various methods." +--- + +import TFunctionHint from '../../shared/_TFunctionHint.mdx'; +import NamespacesHint from '../../shared/_NamespacesHint.mdx'; +import ExampleBanner from '../../shared/ExampleBanner'; + +You can implement translation in your Angular application in the following ways. + +- Using the [translate pipe](#translate-pipe) +- Using the [`t` attribute](#t-attribute) +- Using the [Translations methods](#translation-methods) + +## Translate pipe + +You can translate a string using the [`translate pipe`](/integrations/angular/api.mdx#translate-pipe). It accepts specific parameters and an optional default value. + +```html +<h1>{{'hello_world' | translate}}</h1> +``` + +To provide parameters for translation, pass them as the first parameter of the `translate` pipe. + +:::info +To enable parameter interpolation, you need to use a [message formatter](/formatting.mdx). +::: + +```html +<h1>{{'hello' | translate:{ name: 'John Doe' }}}</h1> +``` + +You can also provide a default value. + +```html +// with params +<h1>{{'hello' | translate:{ name: 'John Doe' }:'Default!'}}</h1> + +// or without params +<h1>{{'hello' | translate:'Default!'}}</h1> +``` + +To disable wrapping, provide a `noWrap` option. + +```html +<h1>{{ 'hello' | translate:{ noWrap: true } }}</h1> +``` + +## `t` attribute + +You can also use a [`t` attribute](/integrations/angular/api.mdx#tcomponent) with an element for translation. Angular will render Tolgee component with `t` attribute selector. + +```html +<h1 t key="providing_default_values"></h1> +``` + +To provide parameters for translation, pass them via the params attribute. + +:::info +To enable parameter interpolation, you need to use a [message formatter](/formatting.mdx). +::: + +```html +<p t key="using_t_with_params" [params]="{ name: 'John Doe' }"></p> +``` + +You can also provide a default value using the `default` attribute. + +```html +<p t key="using_t_with_default" default="This is default"></p> +``` + +## Translation methods + +To translate texts in your component code, you can use [`translate`](/integrations/angular/api.mdx#method-translate) or [`instant`](/integrations/angular/api.mdx#method-instant) methods. + +These methods are part of `TranslateService` which can be injected using dependency injection as shown in the following example. + +```typescript +import { Component, OnInit } from '@angular/core'; +import { TranslateService } from '@tolgee/ngx'; + +@Component({ + selector: 'app-root', + templateUrl: './app.component.html', + styleUrls: ['./app.component.css'], +}) +export class AppComponent implements OnInit { + constructor(private translateService: TranslateService) {} + + helloWorld: string; + + async ngOnInit(): Promise<void> { + this.translateService + .translate('hello_world') + .subscribe((r) => (this.helloWorld = r)); + } +} +``` + +`translate` method returns an [**Observable**](https://rxjs-dev.firebaseapp.com/guide/observable). As a result, the provided listener is called every time the translation changes due to language changes or other reasons. + +```typescript +this.translateService + .get('hello_world') + .subscribe((r) => (this.helloWorld = r)); +``` + +If you are unable to use this asynchronous approach for any reason, you can use the +`instant` method. + +:::warning +Don't overuse the `instant` method. Whenever possible, use the `translate` method. +When translations are not loaded, `instant` method will not provide a valid result. +::: + +```typescript +this.helloWorld = this.translateService.instant('hello_world'); +``` + +Both the `instant` and `translate` methods accept the same parameters as [`tolgee.t`](/api/core_package/tolgee.mdx#t). + +<ExampleBanner framework="Angular" appName="ngx" /> \ No newline at end of file diff --git a/js-sdk_versioned_docs/version-5.x.x/integrations/i18next/api.mdx b/js-sdk_versioned_docs/version-5.x.x/integrations/i18next/api.mdx new file mode 100644 index 00000000..a1562ddb --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/integrations/i18next/api.mdx @@ -0,0 +1,45 @@ +--- +id: api +title: Tolgee i18next API Reference +sidebar_label: API Reference +description: 'Full integration options and custom integration functions for granular control over i18next and Tolgee integration.' +--- + +## Full integration + +### function `withTolgee(i18next, tolgee)` + +Ensures complete integration between i18next and Tolgee. + +- `i18next` - the i18next instance +- `tolgee` - A [`TolgeeInstance`](/api/core_package/tolgee.mdx) + +## Custom integration + +For more granular control over the integration process, you can use the following functions individually instead of `withTolgee`. + +### function `tolgeeBackend(tolgee)` + +Creates a Tolgee [backend](https://www.i18next.com/misc/creating-own-plugins#backend) plugin for i18next. + +- `tolgee` - A Tolgee instance + +### function `tolgeeProcessor(tolgee)` + +Creates a Tolgee [postProcessor](https://www.i18next.com/misc/creating-own-plugins#post-processor) plugin for i18next. +Applies wrapping to each translation, making it detectable for in-context translation in development mode. + +- `tolgee` - A Tolgee instance + +### function `tolgeeApply(tolgee, i18next)` + +Registers necessary callbacks (`tolgee.onTranslationChange` and `i18next.on('languageChanged')`) on both Tolgee instance and i18next. + +- `tolgee` - A Tolgee instance +- `i18next` - An i18next instance + +### function `tolgeeOptions(options)` + +Extends i18next's [`InitOptions`](https://www.i18next.com/overview/configuration-options) with options necessary for Tolgee to function properly. This includes enabling the `tolgeeProcessor` globally and also reacting to store `added` event to refresh the UI when translations are changed through in-context translation. + +- `options` - i18next [`InitOptions`](https://www.i18next.com/overview/configuration-options) diff --git a/js-sdk_versioned_docs/version-5.x.x/integrations/i18next/installation.mdx b/js-sdk_versioned_docs/version-5.x.x/integrations/i18next/installation.mdx new file mode 100644 index 00000000..61e9a540 --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/integrations/i18next/installation.mdx @@ -0,0 +1,88 @@ +--- +id: installation +title: Installation +sidebar_label: Installation +description: 'Learn how to integrate Tolgee with i18next to enhance your internationalization workflow while maintaining familiar i18next features.' +--- + +import PreparingForProduction from '../../shared/_PreparingForProduction.mdx'; +import { InstallationTabs } from '../../../../src/component/InstallationTabs'; + +To use Tolgee with i18next, you need to follow these steps: + +1. [Install the Tolgee integration library](#installation) +2. [Set up the environment variables](#set-up-the-environment-variables) +3. [Initialize Tolgee](#initialize-tolgee) +4. [Language Detection and Switching](#language-detection-and-switching) +5. [Preparing for production](#preparing-for-production) + +## Installation + +To install the Tolgee i18next integration library, run the following command. + +<InstallationTabs lib="@tolgee/i18next" /> + +## Set up the environment variables + +Once the library is installed, you need to initialize it. For initialization, you need the Tolgee API URL, and the Tolgee API Key. To generate the API Key, follow the step-by-step instructions mentioned on the [API keys and PAT tokens page](../../../../../platform/account_settings/api_keys_and_pat_tokens). + +:::danger +Make sure you don't leak your API key. If the API key is leaked, visitors can edit the translations on your site. +::: + +After generating the API key, add these credentials in an environment variable file (`.env` or `.env.local`). + +## Initialize Tolgee + +Next, initialize Tolgee and wrap your i18next instance using [`withTolgee`](./api#function-withtolgeei18next-tolgeeconfig). + +```ts +import i18n from 'i18next'; +import { withTolgee, Tolgee, I18nextPlugin, DevTools } from '@tolgee/i18next'; + +const tolgee = Tolgee() + .use(DevTools()) + .use(I18nextPlugin()) + .init({ + // for development + apiUrl: ..., + apiKey: ..., + + // for production + staticData: { + 'en:translation': ..., + 'cs:translation': ... + } + }); + +withTolgee(i18n, tolgee) + .use(...) + .init(...) + +``` + +The above code does the following: +- Initializes Tolgee with the provided configuration. +- Wraps the i18next instance with the `withTolgee` function. +- Initializes i18next with the provided configuration. + + +> You can configure more options and plugins during initialization. Learn about these other [options](../../api/core_package/options) and [Tolgee plugins](../../plugins) in their respective documentation. + +:::info Namespace Mapping +Tolgee maps `i18next` namespaces to its own namespaces. Since i18next doesn't support empty namespaces, ensure your translations are within a namespace in the Tolgee platform. By default, i18next uses the "translation" namespace. +::: + +## Language Detection and Switching + +Tolgee follows i18next's configuration for language detection. You can use i18next language detectors or set the language manually. + +To change the active language, use the `i18next.changeLanguage` function: + +```ts +i18next.changeLanguage(lng, callback); +``` + +## Preparing for production + +<PreparingForProduction /> diff --git a/js-sdk_versioned_docs/version-5.x.x/integrations/i18next/react_integration.mdx b/js-sdk_versioned_docs/version-5.x.x/integrations/i18next/react_integration.mdx new file mode 100644 index 00000000..7697e434 --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/integrations/i18next/react_integration.mdx @@ -0,0 +1,50 @@ +--- +id: react +title: React integration using i18next +sidebar_label: React integration +slug: react-integration +description: 'Learn how to integrate Tolgee with React applications using i18next and react-i18next. This guide covers installation, setup, and best practices for internationalization in React projects.' +--- + +import {InstallationTabs} from "../../../../src/component/InstallationTabs"; +import ExampleBanner from '../../shared/ExampleBanner'; + +## Overview + +You can integrate Tolgee with React applications using `i18next` and `react-i18next`. It is recommend to use the ICU message formatter, since the Tolgee platform natively supported it. + +## Installation + +To get started, install the necessary packages: + +<InstallationTabs lib="react-i18next i18next-icu" /> + +## Setup + +After installation, set up your i18next instance with Tolgee and React integration: + +```ts +import { withTolgee, Tolgee, I18nextPlugin, DevTools } from '@tolgee/i18next'; +import i18n from 'i18next'; +import ICU from 'i18next-icu'; +import { initReactI18next } from 'react-i18next'; + +const tolgee = Tolgee().use(DevTools()).use(I18nextPlugin()).init({ + apiUrl: process.env.VITE_APP_TOLGEE_API_URL, + apiKey: process.env.VITE_APP_TOLGEE_API_KEY, +}); + +withTolgee(i18n, tolgee) + .use(ICU) + .use(initReactI18next) + .init({ + lng: 'en', // or use i18next language detector + supportedLngs: ['cs', 'en', 'fr', 'de'], + }); +``` + +You can now use the features of [react-i18next](https://react.i18next.com/). + +Feel free to explore the example application for more advanced usage and integration patterns. + +<ExampleBanner framework="i18next" appName="react-i18next" /> \ No newline at end of file diff --git a/js-sdk_versioned_docs/version-5.x.x/integrations/i18next/vue_integration.mdx b/js-sdk_versioned_docs/version-5.x.x/integrations/i18next/vue_integration.mdx new file mode 100644 index 00000000..05f97d32 --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/integrations/i18next/vue_integration.mdx @@ -0,0 +1,63 @@ +--- +id: vue +title: Vue integration using i18next +sidebar_label: Vue integration +slug: vue-integration +description: 'Learn how to integrate Tolgee with Vue 2 applications using i18next and @panter/vue-i18next. This guide covers installation, setup, and usage for effective internationalization in Vue 2 projects.' +--- + +import {InstallationTabs} from "../../../../src/component/InstallationTabs"; +import ExampleBanner from '../../shared/ExampleBanner'; + +:::caution +This integration is specifically for Vue 2. +::: + +## Overview + +You can integrate Tolgee with Vue2 applications using `i18next` and `@panter/vue-i18next`. It is recommend to use the ICU message formatter, since the Tolgee platform natively supported it. + +## Installation + +To get started, install the necessary packages: + +<InstallationTabs lib="@panter/vue-i18next i18next-icu" /> + + +## Setup + +After installation, set up your i18next instance with Tolgee and Vue integration: + +```ts +import { withTolgee, I18nextPlugin, DevTools } from '@tolgee/i18next'; +import i18next from 'i18next'; +import ICU from 'i18next-icu'; +import VueI18Next from '@panter/vue-i18next'; + +Vue.use(VueI18Next); + +const tolgee = Tolgee().use(DevTools()).use(I18nextPlugin()).init({ + apiUrl: process.env.VUE_APP_TOLGEE_API_URL, + apiKey: process.env.VUE_APP_TOLGEE_API_KEY, +}); + +withTolgee(i18next, tolgee) + .use(ICU) + .init({ + lng: 'en', // or use i18next language detector + supportedLngs: ['cs', 'en', 'fr', 'de'], + }); + +const i18n = new VueI18Next(i18next); + +new Vue({ + i18n, + ... +}).$mount('#app'); +``` + +You can now use the features of [@panter/vue-i18next](https://panter.github.io/vue-i18next/). + +Feel free to explore the example application for more advanced usage and integration patterns. + +<ExampleBanner framework="i18next" appName="vue-i18next" /> \ No newline at end of file diff --git a/js-sdk_versioned_docs/version-5.x.x/integrations/react/api.mdx b/js-sdk_versioned_docs/version-5.x.x/integrations/react/api.mdx new file mode 100644 index 00000000..9e861a0c --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/integrations/react/api.mdx @@ -0,0 +1,176 @@ +--- +id: api +title: API (React) +sidebar_label: API +description: 'API documentation for React integration: TolgeeProvider, T-component and different hooks ( useCurrentLanguage, useSetLanguage, useTranslate).' +--- + +## TolgeeProvider + +Provides Tolgee context and takes care of running/stopping tolgee. Accepts [`Tolgee`](/api/core_package/tolgee.mdx) instance. + +```jsx +import { TolgeeProvider } from '@tolgee/react'; + +<TolgeeProvider tolgee={tolgee} fallback="Loading..."> + <App /> +</TolgeeProvider>; +``` + +> You can use Tolgee without TolgeeProvider, but you'll have to run `tolgee.run` yourself and handle initial loading. + +### Prop `fallback?` + +`React.Node` - it is rendered when Tolgee is loading translations instead of provided content. + +### Prop `options?` + +```ts +{ + useSuspense?: boolean +} +``` + +- useSuspense: boolean - `TolgeeProvider` and `useTranslate` will use suspense pattern (default: true) + +## T component + +```jsx +import { T } from '@tolgee/react'; + +<T keyName="..." params={{ param: '...' }}> + default value ... +</T>; +``` + +### Prop `keyName?` + +`String` - translation key. + +### Prop `defaultValue?` + +`String` - default value if translation is not present. + +### Prop `params?` + +`Record<string, string | number | ReactElement | (val) => ReactNode>` - variable parameters, which can be used in translation value +(read more about [ICU message format](/platform/translation_process/icu_message_format)). + +### Prop `ns?` + +`string` - translation namespace + +### Prop `noWrap?` + +`Boolean` (default: `false`) + +- `false` - in development mode translation will be [wrapped](/wrapping.mdx) +- `true` - use when wrapping in dev mode causes problems, in this case in-context translation won't work + +### Prop `language?` + +`String` - override current Tolgee language. This way you can switch to different language for separate translation. Load the language manually with [`tolgee.loadRecord`](/api/core_package/tolgee.mdx#loadrecord). + +### Children `defaultValue?` | `keyName?` + +`String` - If `keyName` property is not defined, child is taken as `keyName`. If it is present child can be used as `defaultValue`. + +## Hook `useTranslate` + +Use this hook to get `t` function for translating. It also serves for loading namespaces. + +```ts +function useTranslate(ns?: string | string[]): { + t: TFnType; + isLoading: boolean; +}; +``` + +This hook triggers suspense if specified namespace(s) are not yet available. Use it for loading namespaces for specific components/pages (returned `t` function uses first namespace from the list automatically). + +### Parameter `ns` + +- `string` | `string[]` - namespace(s) which will be loaded + +### Property `isLoading` + +- `boolean` - is true if any of listed namespaces is not loaded yet + +Use this property if you manually disable `useSuspense`, to make sure you won't display translation keys. + +### Function `t` + +Returns requested translation and also subscribes component to translation/language changes, so component will be re-rendered every time translation changes. If you use namespaces, `t` function will automatically use first of the namespaces given to `useTranslate` function. You can override this by `ns` option. + +```ts +t('key', 'Default value', <options>); +``` + +> `t` function has the same API as [`tolgee.t`](/api/core_package/tolgee.mdx#t). + +## Hook `useTolgee` + +```ts +function useTolgee(events?: TolgeeEvent[]): TolgeeInstance; +``` + +Returns tolgee instance. Allows subscription to different [`events`](/api/core_package/events.mdx), which will trigger re-render. + +```tsx +const RenderingLanguage = () => { + // will update the component on "language" event + const tolgee = useTolgee(['language']); + + return <div>Language: {tolgee.getLanguage()}</div> +}; + +const JustGettingTolgeeInstance = () => { + // won't trigger rerender + const tolgee = useTolgee(); + + ... +}; + +const WorksAlsoWithOtherEvents = () => { + const tolgee = useTolgee(['loading']); + + return <div>Tolgee is loading: {tolgee.isLoading()}</div> +}; +``` + +## Hook `useTolgeeSSR` + +```ts +function useTolgeeSSR( + tolgee: TolgeeInstance, + language?: string, + staticData?: TolgeeStaticData +): TolgeeInstance; +``` + +Safely syncs tolgee language and adds static data to tolgee cache for the initial SSR render. + +It returns a "shallow copy" of tolgee instance which will ensure the first render is the same on server and client. So make sure you pass this copy to `TolgeeProvider`. + +:::info +`staticData` need to be in tolgee format which is accepted by [`tolgee.addStaticData`](/api/core_package/tolgee.mdx#addstaticdata) +::: +Usage: + +```tsx + +const tolgee = ... + +function App() { + const locale = // server provided locale + const staticData = // server provided static data + + const ssrTolgee = useTolgeeSSR(tolgee, locale, staticData); + + return ( + <TolgeePrivider tolgee={ssrTolgee}> + ... + </TolgeeProvider> + ) +} +``` diff --git a/js-sdk_versioned_docs/version-5.x.x/integrations/react/installation.mdx b/js-sdk_versioned_docs/version-5.x.x/integrations/react/installation.mdx new file mode 100644 index 00000000..c6c6d853 --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/integrations/react/installation.mdx @@ -0,0 +1,94 @@ +--- +id: installation +title: Installation +sidebar_label: Installation +description: "Tolgee enables you to implement localization in your React application with ease. You can integrate Tolgee in your React application using Tolgee's SDK for React. To use this SDK, start by installing Tolgee for React." +--- + +To use Tolgee in your React application, you need to follow these steps: + +1. [Install the Tolgee SDK](#install-the-tolgee-sdk) +2. [Configure the Tolgee API](#configure-the-tolgee-api) +3. [Add the Tolgee Provider](#add-the-tolgee-provider) + +## Install the Tolgee SDK + +To install Tolgee's React integration SDK, execute the following command: + +import { InstallationTabs } from '../../../../src/component/InstallationTabs'; + +<InstallationTabs lib="@tolgee/react" /> + +## Configure the Tolgee API + +Once the SDK is installed, you need to initialize it. For the initialization, you need the Tolgee API URL, and the Tolgee API Key. To generate the API Key, follow the step-by-step instructions mentioned on the [API keys and PAT tokens page](../../../../../platform/account_settings/api_keys_and_pat_tokens). + +:::danger +Make sure you don't leak your API key. If the API key is leaked, visitors can edit the translations on your site. +::: + +After generating the API key, add these credentials in your `.env` file. Your `.env` should look like this: + +```env +VITE_APP_TOLGEE_API_URL=https://app.tolgee.io +VITE_APP_TOLGEE_API_KEY=tgpak_gfpwiojtnrztqmtbna3dczjxny2ha3dmnu4tk4tnnjvgc +``` + +:::note +If you are using a React-based framework like Next.js, make sure you paste these credentials in the correct file. +::: + +## Add the Tolgee Provider + +Next, use the above credentials to initialize Tolgee in your React application. You can use Tolgee across your React application by using the [`TolgeeProvider`](./api#tolgeeprovider). + +Wrap your `App` component within the TolgeeProvider, as show in the code below. + +```tsx +import { Tolgee, DevTools, TolgeeProvider, FormatSimple } from "@tolgee/react"; + +const tolgee = Tolgee() + .use(DevTools()) + .use(FormatSimple()) + // replace with .use(FormatIcu()) for rendering plurals, foramatted numbers, etc. + .init({ + language: 'en', + + // for development + apiUrl: process.env.VITE_APP_TOLGEE_API_URL, + apiKey: process.env.VITE_APP_TOLGEE_API_KEY, + + // for production + staticData: { + ... + } + }); + +... + +<TolgeeProvider + tolgee={tolgee} + fallback="Loading..." // loading fallback +> + <App/> +</TolgeeProvider> +``` + +The above code does the following: + +- Imports the required classes, plugins and the TolgeeProvider from the SDK. +- Creates a new instance of Tolgee, configures it to use the [DevTools](../../api/web_package/plugins#devtools) and [FormatSimple](../../api/core_package/format-simple) plugins, and initializes it using the credentials. +- Passes the instance to the TolgeeProvider and sets a fallback. +- Uses TolgeeProvider to wrap the component. + +> You can configure more options and plugins during initialization. Learn about these other [options](../../api/core_package/options) and [Tolgee plugins](../../plugins) in their respective documentation. + +## Prepare for production + +import PreparingForProduction from '../../shared/_PreparingForProduction.mdx'; + +<PreparingForProduction /> + +import ExampleBanner from '../../shared/ExampleBanner'; + +<ExampleBanner framework="React" /> diff --git a/js-sdk_versioned_docs/version-5.x.x/integrations/react/next/app_router.mdx b/js-sdk_versioned_docs/version-5.x.x/integrations/react/next/app_router.mdx new file mode 100644 index 00000000..07908339 --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/integrations/react/next/app_router.mdx @@ -0,0 +1,305 @@ +--- +id: app-router +sidebar_label: App router +title: Next.js with App Router +description: "Get started with Tolgee's integration for Next.js. Learn how to add localization to your Next.js applications that uses the App Router." +--- + +import AppRouterTranslating from './shared/_AppRouterTranslating.mdx' +import ExampleBanner from '../../../shared/ExampleBanner'; +import LimitationsOfServerComponents from './shared/_LimitationsOfServerComponents.mdx' + + +<ExampleBanner framework="Next app router" appName="next-app" /> + +Follow the below instructions to learn to implement localization to your Next.js App Router app with Tolgee. + +In this example we'll store language in cookies, which is a simple to implement, but is not ideal for SEO. If you want a more robust solution with language in url, see [App router with next-intl](./app_router_next_intl.mdx) + +## Prerequisites + +1. An existing Next.js project. +2. An existing [project](../../../../../platform/getting_started/creating_project) on Tolgee platform with at least 2 languages. This guide uses English (en) and Czech (cs). +3. Add localization keys and translations for both the languages. This guide uses the key name `hello_world`. +4. [API key](../../../../../platform/account_settings/api_keys_and_pat_tokens) of your Tolgee project. + +## Install the required packages + +To implement localization to your app, you need to install the `@tolgee/react` package: + +```sh +npm install @tolgee/react +``` + +:::info +Use `@tolgee/react` version `5.30.0` and higher +::: + +## Folder structure + +The folder structure of your project should resemble the following: + +``` +├── .env.development.local # ignored by git +├── next.config.js +├── messages +│ ├── en.json +│ └── cs.json +└── src + ├── tolgee + │ ├── shared.ts + │ ├── language.ts + │ ├── client.tsx + │ └── server.tsx + └── app + ├── layout.tsx + └── page.tsx +``` + +## Set up your environment + +Create the `.env.development.local` file if it does not exist. You will store the Tolgee credentials securely in this file. + +Paste the following in the newly created file. Replace `<your api key>` with your Tolgee API key. + +```sh title=".env.development.local" +NEXT_PUBLIC_TOLGEE_API_KEY=<your api key> +NEXT_PUBLIC_TOLGEE_API_URL=https://app.tolgee.io +``` + +## Save exported data + +Create an `messages` folder in the root of your project directory, if it does not already exists. Move the exported localization json files to the `messages` folder. + + +## Set up Tolgee + +You need to set up Tolgee for both the client and the server. You can create shared configuration that can be used for both client and server. + +### Shared configuration + +In your `tolgee/shared.ts` file, add the following code. + +```ts title="src/tolgee/shared.ts" +import { DevTools, Tolgee, FormatSimple } from '@tolgee/web'; + +const apiKey = process.env.NEXT_PUBLIC_TOLGEE_API_KEY; +const apiUrl = process.env.NEXT_PUBLIC_TOLGEE_API_URL; + +export const ALL_LANGUAGES = ['en', 'cs']; + +export const DEFAULT_LANGUAGE = 'en'; + +export async function getStaticData( + languages: string[], + namespaces: string[] = [''] +) { + const result: Record<string, any> = {}; + for (const lang of languages) { + for (const namespace of namespaces) { + if (namespace) { + result[`${lang}:${namespace}`] = ( + await import(`../../messages/${namespace}/${lang}.json`) + ).default; + } else { + result[lang] = (await import(`../../messages/${lang}.json`)).default; + } + } + } + return result; +} + +export function TolgeeBase() { + return Tolgee() + .use(FormatSimple()) + // replace with .use(FormatIcu()) for rendering plurals, foramatted numbers, etc. + .use(DevTools()) + .updateDefaults({ + apiKey, + apiUrl, + }); +} +``` + +### Client configutation + +The client configuration is very similar to the [Pages Router set up](./pages-router). It serves the purpose of translating client components and also enables the in-context functionality for server-rendered components. + +```tsx title="src/tolgee/client.tsx" +'use client'; + +import { TolgeeBase } from './shared'; +import { TolgeeProvider, TolgeeStaticData } from '@tolgee/react'; +import { useRouter } from 'next/navigation'; +import { useEffect } from 'react'; + +type Props = { + language: string; + staticData: TolgeeStaticData; + children: React.ReactNode; +}; + +const tolgee = TolgeeBase().init(); + +export const TolgeeNextProvider = ({ + language, + staticData, + children, +}: Props) => { + const router = useRouter(); + + useEffect(() => { + const { unsubscribe } = tolgee.on('permanentChange', () => { + router.refresh(); + }); + return () => unsubscribe(); + }, [tolgee, router]); + + return ( + <TolgeeProvider + tolgee={tolgee} + options={{ useSuspense: false }} + fallback="Loading" + ssr={{ language, staticData }} + > + {children} + </TolgeeProvider> + ); +}; +``` + +### Storing language in cookies + +To store user language create file `language.ts`, important part here is the `"use server"` directive, so we can call `setLanguage` method from frontend as server action. + +```tsx title="src/tolgee/language.ts" +'use server'; + +import { detectLanguageFromHeaders } from '@tolgee/react/server'; +import { cookies, headers } from 'next/headers'; +import { ALL_LANGUAGES, DEFAULT_LANGUAGE } from './shared'; + +const LANGUAGE_COOKIE = 'NEXT_LOCALE'; + +export async function setLanguage(locale: string) { + const cookieStore = cookies(); + cookieStore.set(LANGUAGE_COOKIE, locale, { + maxAge: 1000 * 60 * 60 * 24 * 365, // one year in milisecods + }); +} + +export async function getLanguage() { + const cookieStore = cookies(); + const locale = cookieStore.get(LANGUAGE_COOKIE)?.value; + if (locale && ALL_LANGUAGES.includes(locale)) { + return locale; + } + + // try to detect language from headers or use default + const detected = detectLanguageFromHeaders(headers(), ALL_LANGUAGES); + return detected || DEFAULT_LANGUAGE; +} +``` + + +### Server configuration + +Your app will utilize the React server cache for sharing Tolgee instance across components in a single render. This allows the app to use the Tolgee instance anywhere in the server components. + +One important difference from the client setup is the utilization of [`fullKeyEncode`](../../../api/core_package/observer-options#fullkeyencode). `fullKeyEncode` ensures that translations rendered on the server are correctly picked up and interactive for in-context mode. + +```tsx title="src/tolgee/server.tsx" +import { TolgeeBase, ALL_LANGUAGES, getStaticData } from './shared'; +import { createServerInstance } from '@tolgee/react/server'; +import { getLanguage } from './language'; + +export const { getTolgee, getTranslate, T } = createServerInstance({ + getLocale: getLanguage, + createTolgee: async (locale) => + TolgeeBase().init({ + // including all locales + // on server we are not concerned about bundle size + staticData: await getStaticData(ALL_LANGUAGES), + observerOptions: { + fullKeyEncode: true, + }, + language: locale, + fetch: async (input, init) => + fetch(input, { ...init, next: { revalidate: 0 } }), + }), +}); +``` + +## Use the `TolgeeNextProvider` + +The next step is to wrap the children with the `TolgeeNextProvider`. Update the `layout.tsx` file with the following code: + +```tsx title="src/app/layout.tsx" +import { ReactNode } from 'react'; +import { TolgeeNextProvider } from '@/tolgee/client'; +import { getStaticData } from '@/tolgee/shared'; +import { getLanguage } from '@/tolgee/language'; +import './style.css'; + +type Props = { + children: ReactNode; + params: { locale: string }; +}; + +export default async function LocaleLayout({ children }: Props) { + const locale = await getLanguage(); + // it's important you provide all data which are needed for initial render + // so current language and also fallback languages + necessary namespaces + const staticData = await getStaticData([locale]); + + return ( + <html lang={locale}> + <body> + <TolgeeNextProvider language={locale} staticData={staticData}> + {children} + </TolgeeNextProvider> + </body> + </html> + ); +} +``` + +The above code loads relevant locale available on the server and pass it to the client component through props. + +:::info +Make sure you are not using `export const dynamic = 'force-static'` on your pages, as that makes it impossible to use cookies ([more info](https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config)). +::: + +<AppRouterTranslating /> + +## Switching Languages + +For switching languages use `setLanguage` server action from `language.ts`, which will just update our cookie. + +```tsx +'use client'; + +import React from 'react'; +import { useTolgee } from '@tolgee/react'; +import { setLanguage } from '@/tolgee/language'; + +export const LangSelector: React.FC = () => { + const tolgee = useTolgee(['language']); + const language = tolgee.getLanguage(); + + function onSelectChange(e) { + setLanguage(e.target.value); + } + + return ( + <select onChange={onSelectChange} value={language}> + <option value="en">🇬🇧 English</option> + <option value="cs">🇨🇿 Česky</option> + </select> + ); +}; +``` + +<LimitationsOfServerComponents /> + +<ExampleBanner framework="Next app router" appName="next-app" /> diff --git a/js-sdk_versioned_docs/version-5.x.x/integrations/react/next/app_router_next_intl.mdx b/js-sdk_versioned_docs/version-5.x.x/integrations/react/next/app_router_next_intl.mdx new file mode 100644 index 00000000..d6e07bfc --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/integrations/react/next/app_router_next_intl.mdx @@ -0,0 +1,363 @@ +--- +id: app-router-next-intl +sidebar_label: App router with next-intl +title: Next.js with App Router & router-based localizaton +description: "Get started with Tolgee's integration for Next.js. Learn how to add localization to your Next.js applications that uses next-intl package with router-based localization." +--- + +import AppRouterTranslating from './shared/_AppRouterTranslating.mdx' +import ExampleBanner from '../../../shared/ExampleBanner'; +import LimitationsOfServerComponents from './shared/_LimitationsOfServerComponents.mdx' + +This guide shows how to include language information into the page URL, so your application is SEO friendly. + +<ExampleBanner framework="Next app router with next-intl" appName="next-app-intl" /> + +## Installation + +The Next.js App Router does not provide native support for `i18n` routing as the Page Router does. However, you can use the [`next-intl`](https://next-intl-docs.vercel.app/) library, for routing and locale detection. + +We are not using an entire functionality of the library, so the setup is missing some pieces from official documentation of [next-intl](https://next-intl-docs.vercel.app/docs/getting-started/app-router/with-i18n-routing). + +Follow the below instructions to learn to implement localization to your Next.js App Router app with Tolgee. + +## Prerequisites + +1. An existing Next.js project. +2. An existing [project](../../../../../platform/getting_started/creating_project) on Tolgee platform with at least 2 languages. This guide uses English (en) and Czech (cs). +3. Add localization keys and translations for both the languages. This guide uses the key name `hello_world`. +4. [API key](../../../../../platform/account_settings/api_keys_and_pat_tokens) of your Tolgee project. + +## Install the required packages + +To implement localization to your app, you need to install the `next-intl` and `@tolgee/react` package. Execute the following command to install the package. + +```sh +npm install next-intl @tolgee/react +``` + +:::info +Use `@tolgee/react` version `5.30.0` and higher +::: + +## Folder structure + +The folder structure of your project should resemble the following: + +``` +├── .env.development.local # ignored by git +├── next.config.js +├── messages +│ ├── en.json +│ └── cs.json +└── src + ├── middleware.ts + ├── navigation.ts + ├── i18n + │ └── request.ts + ├── tolgee + │ ├── shared.ts + │ ├── client.tsx + │ └── server.tsx + └── app + └── [locale] + ├── layout.tsx + └── page.tsx +``` + +## Set up your environment + +Create the `.env.development.local` file if it does not exist. You will store the Tolgee credentials securely in this file. + +Paste the following in the newly created file. Replace `<your api key>` with your Tolgee API key. + +```sh title=".env.development.local" +NEXT_PUBLIC_TOLGEE_API_KEY=<your api key> +NEXT_PUBLIC_TOLGEE_API_URL=https://app.tolgee.io +``` + +## Save exported data + +Create an `messages` folder in the root of your project directory, if it does not already exists. Move the exported localization json files to the `messages` folder. + + +## Set up Tolgee + +You need to set up Tolgee for both the client and the server. You can create shared configuration that can be used for both client and server. + +### Shared configuration + +In your `tolgee/shared.ts` file, add the following code. + +```ts title="src/tolgee/shared.ts" +import { DevTools, Tolgee, FormatSimple } from '@tolgee/web'; + +const apiKey = process.env.NEXT_PUBLIC_TOLGEE_API_KEY; +const apiUrl = process.env.NEXT_PUBLIC_TOLGEE_API_URL; + +export const ALL_LANGUAGES = ['en', 'cs', 'de', 'fr']; + +export const DEFAULT_LANGUAGE = 'en'; + +export async function getStaticData( + languages: string[], + namespaces: string[] = [''] +) { + const result: Record<string, any> = {}; + for (const lang of languages) { + for (const namespace of namespaces) { + if (namespace) { + result[`${lang}:${namespace}`] = ( + await import(`../../messages/${namespace}/${lang}.json`) + ).default; + } else { + result[lang] = (await import(`../../messages/${lang}.json`)).default; + } + } + } + return result; +} + +export function TolgeeBase() { + return Tolgee() + .use(FormatSimple()) + .use(DevTools()) + // replace with .use(FormatIcu()) for rendering plurals, foramatted numbers, etc. + .updateDefaults({ + apiKey, + apiUrl, + }); +} + +``` + +### Client configutation + +The client configuration is very similar to the [Pages Router set up](./pages-router). It serves the purpose of translating client components and also enables the in-context functionality for server-rendered components. + +```tsx title="src/tolgee/client.tsx" +'use client'; + +import { useEffect } from 'react'; +import { TolgeeProvider, TolgeeStaticData } from '@tolgee/react'; +import { useRouter } from 'next/navigation'; +import { TolgeeBase } from './shared'; + +type Props = { + staticData: TolgeeStaticData; + language: string; + children: React.ReactNode; +}; + +const tolgee = TolgeeBase().init(); + +export const TolgeeNextProvider = ({ + language, + staticData, + children, +}: Props) => { + const router = useRouter(); + + useEffect(() => { + const { unsubscribe } = tolgee.on('permanentChange', () => { + router.refresh(); + }); + return () => unsubscribe(); + }, [tolgee, router]); + + return ( + <TolgeeProvider + tolgee={tolgee} + options={{ useSuspense: false }} + fallback="Loading" + ssr={{ language, staticData }} + > + {children} + </TolgeeProvider> + ); +}; + +``` + +### Server configuration + +Your app will utilize the React server cache for sharing Tolgee instance across components in a single render. This allows the app to use the Tolgee instance anywhere in the server components. + +One important difference from the client setup is the utilization of [`fullKeyEncode`](../../../api/core_package/observer-options#fullkeyencode). `fullKeyEncode` ensures that translations rendered on the server are correctly picked up and interactive for in-context mode. + +```tsx title="src/tolgee/server.tsx" +import { getLocale } from 'next-intl/server'; + +import { TolgeeBase, ALL_LANGUAGES, getStaticData } from './shared'; +import { createServerInstance } from '@tolgee/react/server'; + +export const { getTolgee, getTranslate, T } = createServerInstance({ + getLocale: getLocale, + createTolgee: async (language) => + TolgeeBase().init({ + // including all languages + // on server we are not concerned about bundle size + staticData: await getStaticData(ALL_LANGUAGES), + observerOptions: { + fullKeyEncode: true, + }, + language, + // using custom fetch to avoid aggressive caching + fetch: async (input, init) => + fetch(input, { ...init, next: { revalidate: 0 } }), + }), +}); +``` + +## Use the `TolgeeNextProvider` + +The next step is to wrap the children with the `TolgeeNextProvider`. Update the `layout.tsx` file with the following code: + +```tsx title="src/app/[locale]/layout.tsx" +import { notFound } from 'next/navigation'; +import { ReactNode } from 'react'; +import { TolgeeNextProvider } from '@/tolgee/client'; +import { ALL_LANGUAGES, getStaticData } from '@/tolgee/shared'; + +type Props = { + children: ReactNode; + params: { locale: string }; +}; + +export default async function LocaleLayout({ + children, + params: { locale }, +}: Props) { + if (!ALL_LANGUAGES.includes(locale)) { + notFound(); + } + + // it's important you provide all data which are needed for initial render + // so current language and also fallback languages + necessary namespaces + const staticData = await getStaticData([locale, 'en']); + + return ( + <html lang={locale}> + <body> + <TolgeeNextProvider language={locale} staticData={staticData}> + {children} + </TolgeeNextProvider> + </body> + </html> + ); +} +``` + +The above code loads relevant locale available on the server and pass it to the client component through props. + +> This example provides translation globally. If you want to provide each page with a different namespace, you can move the provider to the relevant page files. + +## Set up `next-intl` + +To use `next-intl` for routing and language detection, you need to set `middleware` and `navigation`. Create a `src/middleware.ts` file if it does not exist. Add the following code in this file. + +```tsx title="src/middleware.ts" +import createMiddleware from 'next-intl/middleware'; +import { ALL_LANGUAGES, DEFAULT_LANGUAGE } from '@/tolgee/shared'; + +// read more about next-intl middleware configuration +// https://next-intl-docs.vercel.app/docs/routing/middleware#locale-prefix +export default createMiddleware({ + locales: ALL_LANGUAGES, + defaultLocale: DEFAULT_LANGUAGE, + localePrefix: 'as-needed', +}); + +export const config = { + // Skip all paths that should not be internationalized + matcher: ['/((?!api|_next|.*\\..*).*)'], +}; +``` + +Next, create a `src/navigation.ts` file. This provides easy access to the navigation APIs in your components. + +```ts title="src/navigation.ts" +import { createSharedPathnamesNavigation } from 'next-intl/navigation'; +import { ALL_LANGUAGES } from './tolgee/shared'; + +// read more about next-intl library +// https://next-intl-docs.vercel.app +export const { Link, redirect, usePathname, useRouter } = + createSharedPathnamesNavigation({ locales: ALL_LANGUAGES }); +``` + +> To gain a comprehensive understanding of how `next-intl` operates, read [their documentation](https://next-intl-docs.vercel.app/docs/getting-started/app-router-server-components). This example utilizes the necessary setup for proper routing. Not all the listed configurations are required. + +### Update `next.config.js` + +You also need to update the `next.config.js` file as follows. + +```js title="next.config.js" +import createNextIntlPlugin from 'next-intl/plugin'; + +const withNextIntl = createNextIntlPlugin(); + +/** @type {import('next').NextConfig} */ +const nextConfig = {}; + +export default withNextIntl(nextConfig); +``` + +### Add `i18n/request.ts` file + +The `i18n/request.ts` is required by `next-intl` package, we don't actually need it, so we are only doing necessary actions to stop `next-intl` from complaining. + +```ts title="src/i18n.ts" +import { getRequestConfig } from 'next-intl/server'; +import { getStaticData } from '../tolgee/shared'; + +export default getRequestConfig(async ({ locale }) => { + return { + // do this to make next-intl not emitting any warnings + messages: { locale }, + }; +}); +``` + +<AppRouterTranslating /> + +## Switching Languages + +For switching languages you should use the `next-intl` router helpers. + +```tsx +'use client'; + +import React, { ChangeEvent, useTransition } from 'react'; +import { usePathname, useRouter } from '@/navigation'; +import { useTolgee } from '@tolgee/react'; + +export const LangSelector: React.FC = () => { + const tolgee = useTolgee(['language']); + const locale = tolgee.getLanguage(); + const router = useRouter(); + const pathname = usePathname(); + const [isPending, startTransition] = useTransition(); + + function onSelectChange(event: ChangeEvent<HTMLSelectElement>) { + const newLocale = event.target.value; + startTransition(() => { + router.replace(pathname, { locale: newLocale }); + }); + } + return ( + <select onChange={onSelectChange} value={locale}> + <option value="en">🇬🇧 English</option> + <option value="cs">🇨🇿 Česky</option> + </select> + ); +}; +``` + +:::info +Make sure you use navigation-related components from `@/navigation` instead natively from Next.js. This ensures that the correct locale is passed to the route. +::: + +<LimitationsOfServerComponents /> + +<ExampleBanner framework="Next app router with next-intl" appName="next-app-intl" /> diff --git a/js-sdk_versioned_docs/version-5.x.x/integrations/react/next/introduction.mdx b/js-sdk_versioned_docs/version-5.x.x/integrations/react/next/introduction.mdx new file mode 100644 index 00000000..99ba09bf --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/integrations/react/next/introduction.mdx @@ -0,0 +1,19 @@ +--- +id: introduction +sidebar_label: Overview +title: Tolgee with Next.js +description: "Get started with Tolgee's integration for Next.js. Learn how to add localization to your Next.js applications." +--- + +You can use the [Tolgee React SDK](../overview) to implement localization to your Next.js application. The SDK provides additional helper functions on top of React integration for easy setup. These helper functions allow you to use the SDK suiting every use case. + +## Integration guides + + - [Next.js with pages router](./pages-router) + - [Next.js with app router](./app-router) + +Advanced + - [Next.js with next-intl and app router](./app-router-next-intl) - route based localization + + +> To learn to install the SDK follow the [React installation](../installation) documentation. diff --git a/js-sdk_versioned_docs/version-5.x.x/integrations/react/next/pages_router.mdx b/js-sdk_versioned_docs/version-5.x.x/integrations/react/next/pages_router.mdx new file mode 100644 index 00000000..55c97fe4 --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/integrations/react/next/pages_router.mdx @@ -0,0 +1,193 @@ +--- +id: pages-router +sidebar_label: Pages router +title: Next.js with Pages Router +description: "Get started with Tolgee's integration for Next.js. Learn how to add localization to your Next.js applications that uses the Pages Router." +--- + +import ExampleBanner from '../../../shared/ExampleBanner'; + +<ExampleBanner framework="Next pages router" appName="next" /> + +## Prerequisites + +1. An existing Next.js project. Install the [`@tolgee/react`](https://www.npmjs.com/package/@tolgee/react) package. +2. An existing [project](../../../../../platform/getting_started/creating_project) on Tolgee platform with at least 2 languages. This guide uses English (en) and Czech (cs). +3. Add localization keys and translations for both the languages. This guide uses the key name `hello_world`. +4. [API key](../../../../../platform/account_settings/api_keys_and_pat_tokens) of your Tolgee project. +5. Exported localization data in JSON format. + +## Install the required packages + +To implement localization to your app, you need to install the `@tolgee/react` package: + +```sh +npm install @tolgee/react +``` + +:::info +Use `@tolgee/react` version `5.30.0` and higher +::: + +## Folder structure + +The folder structure of your project should resemble the following: + +``` +├── .env.development.local # ignored by git +├── next.config.js +├── messages +│ ├── en.json +│ └── cs.json +└── src + ├── tolgee.ts + └── pages + └── _app.tsx +``` + +## Prepare your next-config + +Add the [`i18n` config](https://nextjs.org/docs/pages/building-your-application/routing/internationalization) into your `next-config.js` file as follow. + +```js title="next.config.js" +module.exports = { + reactStrictMode: true, + i18n: { + locales: ['en', 'cs'], + defaultLocale: 'en', + }, +}; +``` + +## Set up your environment + +Create the `.env.development.local` file if it does not exist. You will store the Tolgee credentials securely in this file. + +Paste the following in the newly created file. Replace `<your api key>` with your Tolgee API key. + +```sh title=".env.development.local" +NEXT_PUBLIC_TOLGEE_API_KEY=<your api key> +NEXT_PUBLIC_TOLGEE_API_URL=https://app.tolgee.io +``` + +## Save exported data + +Create an `messages` folder in the root of your project directory, if it does not already exists. Move the exported localization json files to the `messages` folder. + +## Create Tolgee setup file + +This file contains tolgee setup and helper function for loading static files. + +```ts title="src/tolgee.ts" +import { FormatIcu } from '@tolgee/format-icu'; +import { Tolgee, DevTools } from '@tolgee/react'; + +export async function getStaticData( + languages: string[], + namespaces: string[] = [''] +) { + const result: Record<string, any> = {}; + for (const lang of languages) { + for (const namespace of namespaces) { + if (namespace) { + result[`${lang}:${namespace}`] = ( + await import(`../messages/${namespace}/${lang}.json`) + ).default; + } else { + result[lang] = (await import(`../messages/${lang}.json`)).default; + } + } + } + return result; +} + +export const tolgee = Tolgee() + .use(FormatIcu()) + .use(DevTools()) + .init({ + availableLanguages: ['en', 'cs'], + defaultLanguage: 'en', + apiKey: process.env.NEXT_PUBLIC_TOLGEE_API_KEY, + apiUrl: process.env.NEXT_PUBLIC_TOLGEE_API_URL, + }); + +``` + + +## Add the TolgeeProvider + +The next step is to wrap the application's main component with the [`TolgeeProvider` component](../api#tolgeeprovider). + +Import the localization data and provide them to the `TolgeeProvider` using the `staticData` prop. + +```tsx title="src/pages/_app.tsx" +import type { AppContext, AppInitialProps, AppProps } from 'next/app'; +import { getStaticData, tolgee } from '../tolgee'; +import App from 'next/app'; +import { TolgeeProvider, TolgeeStaticData } from '@tolgee/react'; +import { useRouter } from 'next/router'; + +type AppOwnProps = { staticData: TolgeeStaticData }; + +export default function MyApp({ + Component, + pageProps, + staticData, +}: AppProps & AppOwnProps) { + const router = useRouter(); + return ( + <TolgeeProvider + tolgee={tolgee} + ssr={{ language: router.locale, staticData }} + > + <Component {...pageProps} /> + </TolgeeProvider> + ); +} + + +MyApp.getInitialProps = async ( + context: AppContext +): Promise<AppOwnProps & AppInitialProps> => { + const ctx = await App.getInitialProps(context); + return { ...ctx, staticData: await getStaticData([context.ctx.locale!]) }; +}; +``` + +Similarly, you can use [`getServerSideProps`](https://nextjs.org/docs/pages/building-your-application/data-fetching/get-server-side-props) or [`getStaticProps`](https://nextjs.org/docs/pages/building-your-application/data-fetching/get-static-props) on each page. + +## Change language with the Next.js router + +The application needs locale information both on server and client. The application can get this infromation native way as follows. + +```tsx +import { useRouter } from 'next/router'; + +export const LangSelector: React.FC = () => { + const router = useRouter(); + const setLanguage = (lang: string) => { + router.replace(router.pathname, undefined, { locale: lang }); + }; + + return ( + <select onChange={(e) => setLanguage(e.target.value)} value={router.locale}> + <option value="en">🇬🇧 English</option> + <option value="cs">🇨🇿 Česky</option> + </select> + ); +}; +``` + +## Use T component for translation + +The next step is to render the translated text for the selected locale. Use the [`T` component](../api#t-component) to translate the text in your app. + +```tsx +<h1> + <T key_name="hello_world" /> +</h1> +``` + +That's it! You have successfully implemented translation to your Next.js applicaiton. You can also use translation methods described in the [React Translating documentation](../translating.mdx). + +<ExampleBanner framework="Next pages router" appName="next" /> diff --git a/js-sdk_versioned_docs/version-5.x.x/integrations/react/next/shared/_AppRouterTranslating.mdx b/js-sdk_versioned_docs/version-5.x.x/integrations/react/next/shared/_AppRouterTranslating.mdx new file mode 100644 index 00000000..e3064d37 --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/integrations/react/next/shared/_AppRouterTranslating.mdx @@ -0,0 +1,45 @@ + +## Localizing Server components + +Now that everything is setup, you can use the `getTranslate` function to render the translated text. Since this is a server component, you use `getTranslate` instead of the `useTranslate` hook. + +```tsx title="src/page.tsx" +import { getTranslate } from '@/tolgee/server'; + +export default async function IndexPage() { + // because this is server component, use `getTranslate` + // not useTranslate from '@tolgee/react' + const t = await getTranslate(); + return ( + <main> + <h1>{t('hello_world')}</h1> + </main> + ); +} +``` + +If everything is set up correctly, you could use in-context translation. Press and holde the `alt` (or `option`) key, and click `hello_world`. This will open the in-context pop-up window. + +## Localizing Client components + +For client components, you can use the `useTranslate` hook or the `t-component`. + +```tsx +'use client'; + +import { useTranslate } from '@tolgee/react'; + +export const ExampleClientComponent = () => { + const { t } = useTranslate(); + + return ( + <section> + <span>{t('example-key-in-client-component')}</span> + </section> + ); +}; +``` + +:::info +Make sure to use `@/tolgee/server` in server components and `@tolgee/react` in client components. +::: diff --git a/js-sdk_versioned_docs/version-5.x.x/integrations/react/next/shared/_LimitationsOfServerComponents.mdx b/js-sdk_versioned_docs/version-5.x.x/integrations/react/next/shared/_LimitationsOfServerComponents.mdx new file mode 100644 index 00000000..0a5883de --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/integrations/react/next/shared/_LimitationsOfServerComponents.mdx @@ -0,0 +1,5 @@ +## Limitations of Server Components + +Although in-context translation works with server components, there are some limitations compared to client components. The Tolgee cache on the server is separate. This prevents Tolgee from automatically changing the translation when creating a screenshot (unlike with client components, which swap the content if you've modified it in a dialog). + +Furthermore, if you're using the [Tolgee browser plugin](https://chrome.google.com/webstore/detail/tolgee-tools/hacnbapajkkfohnonhbmegojnddagfnj), it won't affect the server's transition to dev mode. As a result, only the client switches, leaving server components non-editable in this mode. \ No newline at end of file diff --git a/js-sdk_versioned_docs/version-5.x.x/integrations/react/overview.mdx b/js-sdk_versioned_docs/version-5.x.x/integrations/react/overview.mdx new file mode 100644 index 00000000..9bd663b5 --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/integrations/react/overview.mdx @@ -0,0 +1,13 @@ +--- +id: overview +title: Tolgee with React +sidebar_label: Overview +description: "Get started with Tolgee's integration for React. Learn how to add localization to your React applications, including support for Next.js and React Native." +--- + +Tolgee provides an SDK for React, based on the [`@tolgee/web`](../../api/web_package/about) package. Using the SDK [@tolgee/react](https://www.npmjs.com/package/@tolgee/react), you can connect your React application to the Tolgee platform. This SDK enables you to implement [in-context translations](../../in-context), [language detection](../../language#language-detection), interpolation, and other advanced features. + +- Follow the [installation guide](./installation) to add the Tolgee React SDK to your existing React application. +- You can also check the [example application](https://github.com/tolgee/react-example) to see how to integrate Tolgee with React. +- If you are building your application with [Next.js](https://nextjs.org/), follow our [Next.js documentation](./next/introduction) for guidance. +- For React Native applications, view our [React Native documentation](./react_native) to learn how to use Tolgee. diff --git a/js-sdk_versioned_docs/version-5.x.x/integrations/react/react_native.mdx b/js-sdk_versioned_docs/version-5.x.x/integrations/react/react_native.mdx new file mode 100644 index 00000000..d0bef4f8 --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/integrations/react/react_native.mdx @@ -0,0 +1,66 @@ +--- +id: react_native +title: React Native +description: "Learn how to use Tolgee with React Native. To get full image of working React integration check our React Native example application." +--- + +import ExampleBanner from '../../shared/ExampleBanner'; + +<ExampleBanner framework="React Native" appName="react-native" /> + +For React Native we recommend following setup (with [Expo](https://expo.dev/)): + +```tsx +import { + Tolgee, + DevTools, + TolgeeProvider, + FormatSimple +} from "@tolgee/react"; + +import en from "./i18n/en.json"; +import cs from "./i18n/cs.json"; +import { TOLGEE_API_KEY, TOLGEE_API_URL } from "@env"; + + +const tolgee = Tolgee() + // DevTools will work only for web view + .use(DevTools()) + .use(FormatSimple()) + // replace with .use(FormatIcu()) for rendering plurals, foramatted numbers, etc. + .init({ + language: 'en', + + // for development + apiUrl: TOLGEE_API_URL, + apiKey: TOLGEE_API_KEY, + + // include translations statically + staticData: { en, cs }, + }); + +... + +<TolgeeProvider + tolgee={tolgee} +> + <your-app-components> +</TolgeeProvider> +``` + +You can use [react-native-dotenv](https://www.npmjs.com/package/react-native-dotenv) to configure environment variables: + +```sh +TOLGEE_API_URL=https://app.tolgee.io +TOLGEE_API_KEY=tgpak_gfpwiojtnrztqmtbna3dczjxny2ha3dmnu4tk4tnnjvgc +``` + +> Obtaining Tolgee API key is described in [Integration](/platform/integrations/about_integrations) chapter. + +:::info +In-context tools won't have any effect in emulators, but can help you when you run the app in web mode. +::: + +## Production + +Make sure you don't include `TOLGEE_API_KEY` in production build. \ No newline at end of file diff --git a/js-sdk_versioned_docs/version-5.x.x/integrations/react/ssr.mdx b/js-sdk_versioned_docs/version-5.x.x/integrations/react/ssr.mdx new file mode 100644 index 00000000..5b2cc495 --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/integrations/react/ssr.mdx @@ -0,0 +1,43 @@ +--- +id: ssr +title: SSR support +sidebar_label: SSR support +--- + +Since version `SDK v5.30.0`, TolgeeProvider has `ssr` property, where you can pass `language` and optionally `staticData`. TolgeeProvider will then ensure, that tolgee instance is switched to this language for the first render immediately and loads static data directly into cache. Everything is then prepared for SSR rendering. + +Loading correct locale and static data is a operation that needs to be performed on the server and it's implementation depends on used framework. + +```jsx +const tolgee = Tolgee() + .use(DevTools()) + .use(FormatSimple()) + // replace with .use(FormatIcu()) for rendering plurals, foramatted numbers, etc. + .init({ + defaultLanguage: 'en', + }) + +const App = () => { + // this needs to work on server + const language = ? + const staticData = ? + + return ( + <TolgeeProvider + tolgee={tolgee} + ssr={{ + language, + staticData + }} + > + ... + </TolgeeProvider> + ) +} +``` + +## Language changing + +When we use SSR, we have to specify language in a way that is detectable by both client and server. There are basically two ways - either use cookie or include locale information directly in the url. + +Then for language change we use the native way of the framework. diff --git a/js-sdk_versioned_docs/version-5.x.x/integrations/react/switching_languages.mdx b/js-sdk_versioned_docs/version-5.x.x/integrations/react/switching_languages.mdx new file mode 100644 index 00000000..226bd160 --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/integrations/react/switching_languages.mdx @@ -0,0 +1,31 @@ +--- +id: switching_language +title: Switching Language +sidebar_label: Switching language +slug: switching-language +description: "Tolgee enables you to implement localization in your React application with ease. You can integrate Tolgee in your React application using Tolgee's SDK for React. Learn to manage language change using the useTolgee hook." +--- + +To manage an event like language change, the React SDK provides the [`useTolgee`](./api#hook-usetolgee) hook. + +Pass the [`language`](/api/core_package/events.mdx) event to the hook to re-render the component when the event emits. + +```jsx +import { useTolgee } from '@tolgee/react'; + +export const LangSelector = () => { + const tolgee = useTolgee(['language']); + + return ( + <select + onChange={(e) => tolgee.changeLanguage(e.target.value)} + value={tolgee.getLanguage()} + > + <option value="en">🇬🇧 English</option> + <option value="cs">🇨🇿 Česky</option> + </select> + ); +}; +``` + +> Learn more about language change, detection and storage on the [Language documentation page](../../language). diff --git a/js-sdk_versioned_docs/version-5.x.x/integrations/react/tags_interpolation.mdx b/js-sdk_versioned_docs/version-5.x.x/integrations/react/tags_interpolation.mdx new file mode 100644 index 00000000..0e1a0176 --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/integrations/react/tags_interpolation.mdx @@ -0,0 +1,65 @@ +--- +id: tags_interpolation +title: Tags Interpolation +sidebar_label: Tags interpolation +slug: tags-interpolation +description: "Tolgee enables you to implement localization in your React application with ease. You can integrate Tolgee in your React application using Tolgee's SDK for React. Moreover, the SDK supports Tags Interpolation. Learn more about Tags Interpolation and how to use them." +--- + +You might want to add formatting to certain part of the translated string. For example, let's take the translated string `Tolgee and React work well`. You want to add italics to the word `Tolgee` and bold to the word `React`. Using the React SDK, you can implement this easily. + +The React SDK, uses [`FormatIcu`](/formatting.mdx#icu-formatter) which supports tags interpolation. You can add custom tags in translations and map them to React elements to implement such formatting. + +There are two different ways to implement tags interpolation. + +## 1. Passing an element + +:::info +Currently, non-closing tags and self-closing tags are not supported [#3101](https://github.com/tolgee/tolgee-js/issues/3101). +::: + +### Example usage + +```jsx +import { FormatIcu } from '@tolgee/format-icu'; + +... + +tolgee.use(FormatIcu()) +``` + +```jsx +const Component = () => { + return ( + <div> + <T + keyName="translation_key" + params={{ i: <i /> }} + defaultValue="This is <i>formatted</i>" + /> + </div> + ); +}; +``` + +The above example code will render the following text. + + + +## 2. Passing a function + +### Example usage + +You can also pass a function that returns a React node. This function can take `content` as an argument such that `(content: React.ReactNode) => React.ReactNode` + +```tsx +const myFunction = (content) => <i title={content}>{content}</i>; + +<T + keyName="translation_key" + params={{ + i: myFunction, + }} + defaultValue="This is <i>formatted</i>" +/>; +``` diff --git a/js-sdk_versioned_docs/version-5.x.x/integrations/react/translating.mdx b/js-sdk_versioned_docs/version-5.x.x/integrations/react/translating.mdx new file mode 100644 index 00000000..baeb7dfd --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/integrations/react/translating.mdx @@ -0,0 +1,64 @@ +--- +id: translating +title: Translating +sidebar_label: Translating +description: "Tolgee enables you to implement localization in your React application with ease. You can integrate Tolgee in your React application using Tolgee's SDK for React. Learn to impelement translation using the useTranslate hook and the T-component." +--- + +import TFunctionHint from '../../shared/_TFunctionHint.mdx'; +import NamespacesHint from '../../shared/_NamespacesHint.mdx'; + +You can implement translation in your React application in two ways. + +- Using the [useTranslate hook](#usetranslate-hook) +- Using the [T-component](#t-component) + +## `useTranslate` hook + +The Tolgee React SDK provides the [`useTranslate`](./api#hook-usetranslate) hook, which comes with a translation function ([`t` function](./api#function-t)). Using this `t` function, you can render the actual translation. + +```js +import { useTranslate } from '@tolgee/react'; + +function Component() { + const { t } = useTranslate(); + + return <div>{t('key_to_translate', 'DEFAULT VALUE')}</div>; +} +``` + +<TFunctionHint /> + +## `T` component + +An alternative way is to use the [`T` component](./api#t-component). It has a very similar API to the `t` function mentioned above. + +```jsx +import { T } from "@tolgee/react"; + +... + +<T + keyName="translation_key" + defaultValue="User has {count} points" + params={{ count: 10 }} +/> +``` + +## useTranslate hook vs T-component + +The `T` component has a similar API to that of the `t` function mentioned above. However, there are some considerations when deciding which to use: + +- To apply translation in the component where you don't have access to React hooks, use the `T` component. +- If you want to use [Tags interpolation](./tags-interpolation), use the `T` component. +- For namespaces, use the `useTranslate` hook. Check the following example to learn more: + +```ts +const { t, isLoading } = useTranslate('common'); +``` + +<NamespacesHint /> + +import ExampleBanner from '../../shared/ExampleBanner'; + +<ExampleBanner framework="React" /> diff --git a/js-sdk_versioned_docs/version-5.x.x/integrations/svelte/api.mdx b/js-sdk_versioned_docs/version-5.x.x/integrations/svelte/api.mdx new file mode 100644 index 00000000..b27305c3 --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/integrations/svelte/api.mdx @@ -0,0 +1,128 @@ +--- +id: api +title: API +sidebar_label: API +description: "Explore Tolgee's Svelte API for localization. Learn about TolgeeProvider, T component, getTranslate and getTolgee functions. Includes props, parameters, and usage examples for efficient translation implementation." +--- + +## `TolgeeProvider` + +Provides the Tolgee context. Use in the root of the application. + +```jsx +import { TolgeeProvider } from '@tolgee/svelte'; + +... + +<TolgeeProvider> + <App /> +</TolgeeProvider> +``` + +### Prop `fallback?` + +`string` - rendered when translations are loading. + +### Prop `tolgee?` + +Provide a Tolgee instance. + +### Slot `fallback` + +Alternative for `fallback`. Use when you to pass components. + +```svelte +<TolgeeProvider> + <App /> + <div slot="fallback">Loading...</div> +</TolgeeProvider> +``` + +## `T` component + +Implement translation in your Svelte application. It has a very similar API to the `t` function. + +```svelte +import { T } from '@tolgee/svelte'; + +<T keyName="key" defaultValue="Default" /> +``` + +### Prop `keyName` + +`String` - translation key. + +### Prop `defaultValue?` + +`String` - Rendered if no translation for the specified key (in neither the selected language nor the base language) is present. If not provided, `keyName` gets rendered instead. + +### Prop `params?` + +`Record<string, string>` - variable params, which can be used in translation value +(read more about [ICU message format](/platform/translation_process/icu_message_format)). + +### Prop `ns?` + +`string` - translation namespace + +### Prop `noWrap?` + +`Boolean` (default: `false`) + +- `false` - in development mode translation will be [wrapped](/wrapping.mdx) +- `true` - use when wrapping in dev mode causes problems. In-context translation won't work. + +### Prop `language?` + +`String` - override current Tolgee language. Allows switching to different language for separate translation. Load the language manually with [`tolgee.loadRecord`](/api/core_package/tolgee.mdx#loadrecord). + +## Function `getTranslate` + +Use it for loading namespaces for specific components/pages or to get `t` function for translating (returned `t` function uses first namespace from the list automatically). + +```ts +function getTranslate(ns?: string | string[]): { + t: Readable<TFnType>; + isLoading: Readable<boolean>; +}; +``` + +### Parameter `ns` + +- `string` | `string[]` - namespace(s) to be loaded + +### Property `isLoading` (Readable) + +- `boolean` - is true if any of the listed namespaces is loading. Use this property to ensure translations are rendered after they are loaded. + +### Function `t` (Readable) + +Returns requested translation and also subscribes component to translation/language changes. Component will be re-rendered every time translation changes. If used with namespaces, `t` function will automatically use the first the namespace given to `useTranslate` function. Override this with the `ns` option. + +```ts +$t('key', 'Default value', <options>) +``` + +> Check [`tolgee.t`](/api/core_package/tolgee.mdx#t) function interface. + +## Function `getTolgee` + +Returns the Tolgee instance as a `Readable`. Allows subscription to different [`events`](/api/core_package/events.mdx). Most common usecase is for language switching. + +```svelte +<script> + import { getTolgee } from '@tolgee/svelte'; + + // gets updated on language change + const tolgee1 = getTolgee(['language']); + + // gets updated when loading changes + const tolgee2 = getTolgee(['loading']); + + // never gets updated + const tolgee3 = getTolgee(); +</script> + +<div>Language: {$tolgee1.getLanguage()}</div> +<div>Loading: {$tolgee2.isLoading()}</div> +``` diff --git a/js-sdk_versioned_docs/version-5.x.x/integrations/svelte/installation.mdx b/js-sdk_versioned_docs/version-5.x.x/integrations/svelte/installation.mdx new file mode 100644 index 00000000..30b40019 --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/integrations/svelte/installation.mdx @@ -0,0 +1,83 @@ +--- +id: installation +title: Installation +sidebar_label: Installation +description: "Learn how to install and configure Tolgee for Svelte localization. Step-by-step guide covers library installation, environment setup, TolgeeProvider configuration, and production preparation. Includes code examples." +--- + +import ExampleBanner from '../../shared/ExampleBanner'; +import PreparingForProduction from '../../shared/_PreparingForProduction.mdx'; +import { InstallationTabs } from '../../../../src/component/InstallationTabs'; + +To use Tolgee in your React application, you need to follow these steps: + +1. [Install the Tolgee integration library](#install-the-tolgee-integration-library) +2. [Set up the environment variables](#set-up-the-environment-variables) +3. [Configure the TolgeeProvider](#configure-the-tolgeeprovider) +4. [Preparing for production](#preparing-for-production) + +## Install the Tolgee integration library + +To install Tolgee Svelte integration library, run the following command. + +<InstallationTabs lib="@tolgee/svelte" /> + +## Set up the environment variables + + +Once the library is installed, you need to initialize it. For initialization, you need the Tolgee API URL, and the Tolgee API Key. To generate the API Key, follow the step-by-step instructions mentioned on the [API keys and PAT tokens page](../../../../../platform/account_settings/api_keys_and_pat_tokens). + +:::danger +Make sure you don't leak your API key. If the API key is leaked, visitors can edit the translations on your site. +::: + +After generating the API key, add these credentials. If you bootstrapped the application with SvelteKit, add them to the `.env.development.local` file. Your `.env.development.local` should look as follow. + +```env +VITE_TOLGEE_API_KEY=tgpak_gfpwiojtnrztqmtbna3dczjxny2ha3dmnu4tk4tnnjvgc +VITE_TOLGEE_API_URL=https://app.tolgee.io +``` + +## Configure the TolgeeProvider + +Next, initialize Tolgee and wrap the application in [`TolgeeProvider`](./api#tolgeeprovider). + +```svelte +<script> + import { TolgeeProvider, Tolgee, DevTools, FormatSimple } from '@tolgee/svelte'; + + const tolgee = Tolgee() + .use(DevTools()) + .use(FormatSimple()) + .init({ + language: 'en', + + // for development + apiUrl: import.meta.env.VITE_TOLGEE_API_URL, + apiKey: import.meta.env.VITE_TOLGEE_API_KEY, + + // for production + staticData: { + ... + } + }); +</script> + +<TolgeeProvider tolgee={tolgee}> + <div slot="fallback">Loading...</div> + <slot /> +</TolgeeProvider> +``` +The above code does the following: + +- Imports the required methods and plugins from the integration library. +- Configures the Tolgee instance to use the [DevTools](../../api/web_package/plugins#devtools) and [FormatSimple](../../api/core_package/format-simple) plugins, and initializes it using the credentials. It also sets the language to English. +- Wraps a component within the `TolgeeProvider`. + +> You can configure more options and plugins during initialization. Learn about other [options](../../api/core_package/options) and [Tolgee plugins](../../plugins) in their respective documentation. + +## Preparing for production + +<PreparingForProduction /> + +<ExampleBanner framework="Svelte" /> diff --git a/js-sdk_versioned_docs/version-5.x.x/integrations/svelte/overview.mdx b/js-sdk_versioned_docs/version-5.x.x/integrations/svelte/overview.mdx new file mode 100644 index 00000000..18baaab2 --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/integrations/svelte/overview.mdx @@ -0,0 +1,11 @@ +--- +id: overview +title: Tolgee with Svelte +sidebar_label: Overview +description: "Implement localization in your Svelte app with Tolgee. Features include in-context translations and language detection. Get started with our installation guide and examples." +--- + +Tolgee provides an integration library for Svelte, based on the [`@tolgee/web`](../../api/web_package/about) package. Using the [@tolgee/svelte](https://www.npmjs.com/package/@tolgee/svelte) library, you can connect your Svelte application to the Tolgee platform. This library enables you to implement [in-context translations](../../in-context), [language detection](../../language#language-detection), interpolation, and other advanced features. + +- Follow the [installation guide](./installation) to add the Tolgee Svelte integration library to your existing Svelte application. +- You can also check the [example application](https://github.com/tolgee/svelte-example) to see how to integrate Tolgee with Svelte. diff --git a/js-sdk_versioned_docs/version-5.x.x/integrations/svelte/switching_language.mdx b/js-sdk_versioned_docs/version-5.x.x/integrations/svelte/switching_language.mdx new file mode 100644 index 00000000..b7cd853f --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/integrations/svelte/switching_language.mdx @@ -0,0 +1,27 @@ +--- +id: switching_language +title: Switching language +sidebar_label: Switching language +slug: switching-language +description: "Learn to manage language switching in Svelte apps using Tolgee. Guide demonstrates how to use the getTolgee function and subscribe to language events, with code examples for implementation." +--- + +For language management, the Tolgee integration provides the [`getTolgee`](./api#function-gettolgee) function. Use this function with subscription to the `language` event. Below is an example of how to use it for switching languages. + +```svelte +<script> + import { getTolgee } from '@tolgee/svelte'; + + const tolgee = getTolgee(['language']) + + function handleLanguageChange(e) { + $tolgee.changeLanguage(e.currentTarget.value) + } +</script> + +<select value={$tolgee.getLanguage()} on:change={handleLanguageChange}> + ... +</select> +``` + +> Read more about [Language change, detection and storage](/language.mdx) diff --git a/js-sdk_versioned_docs/version-5.x.x/integrations/svelte/translating.mdx b/js-sdk_versioned_docs/version-5.x.x/integrations/svelte/translating.mdx new file mode 100644 index 00000000..52ff0743 --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/integrations/svelte/translating.mdx @@ -0,0 +1,63 @@ +--- +id: translating +title: Translating +sidebar_label: Translating +description: "Learn to implement translations in Svelte using Tolgee. Guide covers the getTranslate function and T component, with examples for basic usage and advanced features like namespaces and parameter interpolation." +--- + +import TFunctionHint from '../../shared/_TFunctionHint.mdx'; +import NamespacesHint from '../../shared/_NamespacesHint.mdx'; +import ExampleBanner from '../../shared/ExampleBanner'; + +You can implement translation in your Svelte application in the following ways. + +- Using the [`getTranslate` function](#gettranslate-function) +- Using the [`T` component](#the-t-component) + +## `getTranslate` function + +The [`getTranslate` function](./api#function-gettranslate) provides a `t` function. This `t` function should be used to render the respective translation. + +The below code demonstrates the implemention of the `getTranslate` and the `t` function. + +```svelte +<script> + import { getTranslate } from "@tolgee/svelte"; + + // t is store + const { t } = getTranslate(); +</script> + +<!-- use the translation function --> +{$t('key', 'Default value')} +``` + +<TFunctionHint /> + +### Using namespaces + +Moreover, you can load namespaces with the `getTranslate` function. + +```ts +const { t, isLoading } = getTranslate('common'); +``` + +<NamespacesHint /> + +## The `T` component + +You can also use the [`T` component](./api#t-component) for translation. It has an API similar to the `t` function mentioned above. + +```svelte +<script> + import { T } from "@tolgee/svelte"; +</script> + +<T + keyName="translation_key" + defaultValue="User has {count} points" + params={{ count: 10 }} +/> +``` + +<ExampleBanner framework="Svelte" /> \ No newline at end of file diff --git a/js-sdk_versioned_docs/version-5.x.x/integrations/vanilla/initialization.mdx b/js-sdk_versioned_docs/version-5.x.x/integrations/vanilla/initialization.mdx new file mode 100644 index 00000000..726ebd83 --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/integrations/vanilla/initialization.mdx @@ -0,0 +1,53 @@ +--- +id: initialization +title: Initialization +description: 'Tolgee initialization' +--- + +Standard way to initialize Tolgee is: + +```ts +import {Tolgee, DevTools, FormatSimple} from '@tolgee/web' + +const tolgee = Tolgee() + .use(DevTools()) + .use(FormatSimple()) + // replace with .use(FormatIcu()) for rendering plurals, foramatted numbers, etc. + .init({ + language: 'en' + + // for development mode + apiUrl: 'https://app.tolgee.io' + apiKey: '<your tolgee API key>' + + // for production + staticData: { + ... + } + }) + +// this part starts loading data +tolgee.run(); +``` + +:::warning +Never leak your API key! We strongly recommend against adding API key into git repository. +::: + +We use `DevTools` plugin which will provide in-context translating in dev mode. We also need to provide `apiUrl` and `apiKey` for the in-context to work. + +> Obtaining Tolgee API key is described in [Integration](/platform/integrations/about_integrations) chapter. + +> Check all [tolgee options](/api/core_package/options.mdx) and [tolgee plugins](/api/web_package/plugins.mdx). + +> Tolgee SDK can be used [without connection to Tolgee Platform](/usage_without_platform.mdx) + +## What does `run` do? + +:::info +In tolgee integrations `run` method is usually called automatically in tolgee provider, it is generally better to hook it into framework lifecycle because of SSR. +::: + +Tolgee [`run`](../../api/core_package/tolgee.mdx#run) method will start loading translations data (if necessary) and also activates in-context tools. + +You can use tolgee without running it (e.g. on server with ssr). That way tolgee won't activate in-context tools and will not load anything asynchronously, but you can still use [`tolgee.t`](../../api/core_package/tolgee.mdx#t) function with [`staticData`](../../api/core_package/options#staticdata). diff --git a/js-sdk_versioned_docs/version-5.x.x/integrations/vanilla/installation.mdx b/js-sdk_versioned_docs/version-5.x.x/integrations/vanilla/installation.mdx new file mode 100644 index 00000000..6eff84db --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/integrations/vanilla/installation.mdx @@ -0,0 +1,58 @@ +--- +id: installation +title: Installation +description: 'Explore multiple ways how to install Tolgee: with supported integrations, using dev tools without bundler and more.' +--- + +If you use vanilla javascript or an unsupported framework, use [`@tolgee/web`](../../api/web_package/about) package. + +import { InstallationTabs } from '../../../../src/component/InstallationTabs'; + +<InstallationTabs lib="@tolgee/web" /> + +```ts +import { Tolgee } from '@tolgee/web'; +``` + +### With script tag + +```jsx +<script src="https://cdn.jsdelivr.net/npm/@tolgee/web/dist/tolgee-web.production.umd.min.js"></script> +``` + +```ts +const { Tolgee } = window['@tolgee/web']; +``` + +### With native es import + +```ts +import { Tolgee } from 'https://cdn.jsdelivr.net/npm/@tolgee/web/dist/tolgee-web.production.esm.min.mjs' +``` + +## In-context (DevTools) + +To use In-context in development mode, you can simply use [`DevTools`](../../api/web_package/plugins#devtools) from `@tolgee/web` + +```ts +import { Tolgee, DevTools } from '@tolgee/web'; + +const tolgee = Tolgee().use(DevTools()).init(...) +``` + +If you use any standard FE setup with a bundler, `DevTools` will be automatically excluded in production (based on `process.env.NODE_ENV`). If you want the in-context to be always available, use [`InContextTools`](/api/web_package/tools.mdx#incontexttools) instead of `DevTools`- it is the same plugin, the only difference is that `DevTools` are exported conditionally. + +## Using dev tools without bundler + +You can use separately bundled `in-context-tools` however, you'll have to make sure you won't include it in production. + +```jsx +<script src="https://cdn.jsdelivr.net/npm/@tolgee/web/dist/tolgee-in-context-tools.umd.min.js"></script>; +const { InContextTools } = window['@tolgee/in-context-tools']; + +// or + +import { InContextTools } from 'https://cdn.jsdelivr.net/npm/@tolgee/web/dist/tolgee-in-context-tools.esm.min.mjs'; +``` + +Check the [complete list](https://cdn.jsdelivr.net/npm/@tolgee/web/dist/) of bundles. diff --git a/js-sdk_versioned_docs/version-5.x.x/integrations/vanilla/translating.mdx b/js-sdk_versioned_docs/version-5.x.x/integrations/vanilla/translating.mdx new file mode 100644 index 00000000..262b56ec --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/integrations/vanilla/translating.mdx @@ -0,0 +1,37 @@ +--- +id: translating +title: Translating +description: 'Tolgee translating with vanilla JS.' +--- + +Use [`tolgee.t`](../../api/core_package/tolgee.mdx#t) method to translate keys. + +```ts +domElement.textContent = tolgee.t('key', 'Default value'); +``` + +However this will not update translation in case you change language or update translation through in-context. + +### Listening for changes + +:::info +If you use Tolgee with any supported framework, this is solved for you automatically. +::: + +You can [listen](../../api/core_package/tolgee.mdx#on) for translation change with `update` event. + +```ts +tolgee.on('update', () => { + domElement.textContent = tolgee.t('key', 'Default value'); +}); +``` + +This event gets triggered when any translation need to be updated, so it might be inefficient if you use many namespaces. Therefore there is also [`onNsUpdate`](../../api/core_package/tolgee.mdx#onnsupdate) method, which allows you to subscribe only to selected namespaces. + +```ts +tolgee + .onNsUpdate(() => { + domElement.textContent = tolgee.t('key', 'Default value'); + }) + .subscribeNs('my_namespace'); +``` diff --git a/js-sdk_versioned_docs/version-5.x.x/integrations/vue/api.mdx b/js-sdk_versioned_docs/version-5.x.x/integrations/vue/api.mdx new file mode 100644 index 00000000..3171dc30 --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/integrations/vue/api.mdx @@ -0,0 +1,189 @@ +--- +id: api +title: API +sidebar_label: API +description: "Explore Tolgee's Vue API for easy localization. Learn about VueTolgee plugin, TolgeeProvider, T component, and composables. Includes usage examples and prop descriptions for efficient integration." +--- + +The `@tolgee/vue` library exports the following components and all available components from [`@tolgee/web`](/api/web_package/about.mdx). + +## VueTolgee plugin + +`VueTolgee` plugin attaches Tolgee to a Vue instance. This allows, you to use the `$t` function in any Vue component. + +```jsx +import { VueTolgee } from '@tolgee/vue'; + +... + +app.use(VueTolgee, { tolgee }); + +... + +// A child Vue component +<div> + {{ $t('key', 'Default value') }} +</div> +``` + +> For more refer to the [`tolgee.t`](/api/core_package/tolgee.mdx#t) function interface. + +You can also integrate Tolgee without using the `VueTolgee` plugin. In this case use the `TolgeeProvider` and the `useTranslate` method for translating. + +## `TolgeeProvider` + +Provides the Tolgee context. Use in root of the application. + +```jsx +import { TolgeeProvider } from '@tolgee/vue'; + +... + +<TolgeeProvider> + <App /> +</TolgeeProvider> +``` + +### Prop `fallback?` + +`String | JSX.Element` - rendered when Tolgee is loading translations instead of provided content. +Pass custom loading element when using Vue with JSX. + +```html +<TolgeeProvider fallback="Loading..."> + <App /> +</TolgeeProvider> +``` + +### Slot `fallback?` + +Alternative for `fallback`. Use when you are using Vue with templates: + +```html +<TolgeeProvider> + <App /> + <template v-slot:fallback> + <div>Loading...</div> + </template> +</TolgeeProvider> +``` + +### Prop `tolgee?` + +Provide a Tolgee instance. If you use `VueTolgee`, this is not necessary. + +## `T` component + +Implement translation in your Vue application. It has a very similar API to the `t` function. + +```js +import { T } from '@tolgee/vue'; +``` + +```html +<T keyName="..." :params="{ param: '...' }" /> +``` + +### Prop `keyName` + +`String` - translation key. + +### Prop `defaultValue?` + +`String` - Rendered if no translation for the specified key (in neither the selected language nor the base language) is present. If not provided, `keyName` gets rendered instead. + +### Prop `params?` + +`Record<string, string>` - variable params, which can be used in translation value +(read more about [ICU message format](/platform/translation_process/icu_message_format)). + +### Prop `ns?` + +`string` - translation namespace + +### Prop `noWrap?` + +`Boolean` (default: `false`) + +- `false` - in development mode translation will be [wrapped](/wrapping.mdx) +- `true` - use when wrapping in dev mode causes problems. In-context translation won't work. + +### Prop `language?` + +`String` - override current Tolgee language. Allows switching to different language for separate translation. Load the language manually with [`tolgee.loadRecord`](/api/core_package/tolgee.mdx#loadrecord). + +### Children + +:::info +Feature available from version 5.24.0 +::: + +Pass children to the `T` component that gets mapped to the translation parameters respective to their slot names. Allows implementation of custom components as a part of the translation. + +```html +<template> + <T + keyName="translation_with_link" + defaultValue="Click this {link}" + > + <template v-slot:link> + <a href="...">{{ $t('link_label', "link") }}</a> + </template> + </T> +</template> +``` + +## Composable `useTranslate` + +Use it for loading namespaces for specific components/pages or to get `t` function for translating (returned `t` function uses first namespace from the list automatically). + +```ts +function useTranslate(ns?: string | string[]): { + t: Ref<TFnType>; + isLoading: Ref<boolean>; +}; +``` + +### Parameter `ns` + +- `string` | `string[]` - namespace(s) which will be loaded + +### Property `isLoading` (Ref) + +- `boolean` - is true if any of listed namespaces is not loaded yet + +Use this property to ensure translations are rendered after they are loaded. + +### Function `t` (Ref) + +Returns requested translation and also subscribes component to translation/language changes. Component will be re-rendered every time translation changes. If used with namespaces, `t` function will automatically use the first the namespace given to `useTranslate` function. Override this with the `ns` option. + +```ts +t('key', 'Default value', <options>); +``` + +> Check [`tolgee.t`](/api/core_package/tolgee.mdx#t) function interface. + +## Composable `useTolgee` + +Returns Tolgee instance as a `Ref`. Allows subscription to different [`events`](/api/core_package/events.mdx), which will trigger re-render. Most common usecase is for language switching. + +```html +<template> + <div>Language: {{tolgee1.getLanguage()}}</div> + <div>Loading: {{tolgee2.isLoading()}}</div> +</template> + +<script setup> + import { useTolgee } from '@tolgee/vue'; + + // gets updated on language change + const tolgee1 = useTolgee(['language']); + + // gets updated when loading changes + const tolgee2 = useTolgee(['loading']); + + // never gets updated + const tolgee3 = useTolgee(); +</script> +``` diff --git a/js-sdk_versioned_docs/version-5.x.x/integrations/vue/component_interpolation.mdx b/js-sdk_versioned_docs/version-5.x.x/integrations/vue/component_interpolation.mdx new file mode 100644 index 00000000..14572d6a --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/integrations/vue/component_interpolation.mdx @@ -0,0 +1,57 @@ +--- +id: component_interpolation +title: Component interpolation +sidebar_label: Component interpolation +slug: component-interpolation +description: "Learn to use component interpolation in Vue with Tolgee. Guide covers implementing custom components within translations, using FormatIcu and the T component. Includes code examples and usage tips." +--- + +:::info +Feature available from version 5.24.0 +::: + +You might want to use a Component for certain part of the translated string. For example, let's take the translated string `Click this link`. You want to add the anchor tag to the word `link`. Using the integration library, you can implement this easily. + +The integration library, uses [`FormatIcu`](/formatting.mdx#icu-formatter) which supports component interpolation. You can map variables in translations to custom Vue components. + +:::info +Currently, non-closing tags and self-closing tags are not supported [#3101](https://github.com/tolgee/tolgee-js/issues/3101). +::: + +### Example usage + +```jsx +import { FormatIcu } from '@tolgee/format-icu'; + +... + +tolgee.use(FormatIcu()) +``` + +The above code configures Tolgee to use the `FormatIcu` formatter. + +Next, use the [`T` component](./translating#t-component) with named slots. These are mapped to the variables in the translation. + +```html +<template> + <T + keyName="translation_with_link" + defaultValue="Click this {link}" + > + <template v-slot:link> + <a href="...">{{ $t('link_label', "link") }}</a> + </template> + </T> +</template> + +<script setup> + import { T } from '@tolgee/vue'; +</script> +``` + + +The above example code will provide the following output. + +```html +Click this <a href="...">link</a> +``` \ No newline at end of file diff --git a/js-sdk_versioned_docs/version-5.x.x/integrations/vue/installation.mdx b/js-sdk_versioned_docs/version-5.x.x/integrations/vue/installation.mdx new file mode 100644 index 00000000..bf13e2ee --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/integrations/vue/installation.mdx @@ -0,0 +1,100 @@ +--- +id: installation +title: Installation +sidebar_label: Installation +description: "Step-by-step guide to install Tolgee in Vue apps. Covers library installation, environment setup, Tolgee initialization, and TolgeeProvider integration. Includes production preparation tips and code examples." +--- + +import ExampleBanner from '../../shared/ExampleBanner'; +import { InstallationTabs } from '../../../../src/component/InstallationTabs'; +import PreparingForProduction from '../../shared/_PreparingForProduction.mdx'; + +To use Tolgee in your Vue application, you need to follow these steps: + +1. [Install the Tolgee integration library](#install-the-tolgee-integration-library) +2. [Set up the environment variables](#set-up-the-environment-variables) +3. [Initialize Tolgee](#initialize-tolgee) +4. [Add the Tolgee Provider](#add-the-tolgee-provider) +5. [Preparing for production](#preparing-for-production) + + +## Install the Tolgee integration library + +To install Tolgee integration library, run the following command: + +<InstallationTabs lib="@tolgee/vue" /> + +## Set up the environment variables + +Once the library is installed, you need to initialize it. For initialization, you need the Tolgee API URL, and the Tolgee API Key. To generate the API Key, follow the step-by-step instructions mentioned on the [API keys and PAT tokens page](../../../../../platform/account_settings/api_keys_and_pat_tokens). + +:::danger +Make sure you don't leak your API key. If the API key is leaked, visitors can edit the translations on your site. +::: + +After generating the API key, add these credentials. If you bootstrapped the Vue application using the vue-cli, add them to the `.env.development.local` file. Your `.env.development.local` should look like this: + +```env +VITE_APP_TOLGEE_API_URL=https://app.tolgee.io +VITE_APP_TOLGEE_API_KEY=tgpak_gfpwiojtnrztqmtbna3dczjxny2ha3dmnu4tk4tnnjvgc +``` + +Otherwise, you can set these properties directly, or use plugins like [dotenv-webpack](https://www.npmjs.com/package/dotenv-webpack). + +## Initialize Tolgee + +Next initialize `Tolgee` and use [`VueTolgee`](./api#vuetolgee-plugin). The `VueTolgee` plugin makes [`$t`](./translating#global-t-function) function globally available. + +```ts +import { Tolgee, DevTools, VueTolgee, FormatSimple } from '@tolgee/vue'; + +const tolgee = Tolgee() + .use(DevTools()) + .use(FormatSimple()) + // replace with .use(FormatIcu()) for rendering plurals, foramatted numbers, etc. + .init({ + language: 'en', + + // for development + apiUrl: import.meta.env.VITE_APP_TOLGEE_API_URL, + apiKey: import.meta.env.VITE_APP_TOLGEE_API_KEY, + + // for production + staticData: { + ... + } + }); + +... + +app.use(VueTolgee, { tolgee }); +``` + +The above code does the following: + +- Imports the required classes, and plugins from the integration library. +- Configures the Tolgee instance to use the [DevTools](../../api/web_package/plugins#devtools) and [FormatSimple](../../api/core_package/format-simple) plugins, and initializes it using the credentials. It also sets the language to English. +- Registers the `VueTolgee` plugin with the Vue application. + +> You can configure more options and plugins during initialization. Learn about these other [options](../../api/core_package/options) and [Tolgee plugins](../../plugins) in their respective documentation. + +## Add the Tolgee Provider + +Wrap your application with the [`TolgeeProvider`](./api#tolgeeprovider) component. `TolgeeProvider` will initialize tolgee when it is ready and waits for initial data to be load. You can also provide a `fallback` slot to show custom loader while translations are being loaded. + +```html +<template> + <TolgeeProvider> + <template v-slot:fallback> + <div>Loading...</div> + </template> + <App /> + </TolgeeProvider> +</template> +``` + +## Preparing for production + +<PreparingForProduction /> + +<ExampleBanner framework="Vue" /> \ No newline at end of file diff --git a/js-sdk_versioned_docs/version-5.x.x/integrations/vue/overview.mdx b/js-sdk_versioned_docs/version-5.x.x/integrations/vue/overview.mdx new file mode 100644 index 00000000..3d3cc5ce --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/integrations/vue/overview.mdx @@ -0,0 +1,11 @@ +--- +id: overview +title: Tolgee with Vue +sidebar_label: Overview +description: "Discover Tolgee's Vue integration for localization. Learn to implement in-context translations, language detection, and more. Includes installation guide and example app for easy Vue integration." +--- + +Tolgee provides an SDK for Vue, based on the [`@tolgee/web`](../../api/web_package/about) package. Using the SDK [@tolgee/vue](https://www.npmjs.com/package/@tolgee/vue), you can connect your Vue application to the Tolgee platform. This SDK enables you to implement [in-context translations](../../in-context), [language detection](../../language#language-detection), interpolation, and other advanced features. + +- Follow the [installation guide](./installation) to add the Tolgee Vue SDK to your existing Vue application. +- You can also check the [example application](https://github.com/tolgee/vue-example) to see how to integrate Tolgee with Vue. diff --git a/js-sdk_versioned_docs/version-5.x.x/integrations/vue/ssr.mdx b/js-sdk_versioned_docs/version-5.x.x/integrations/vue/ssr.mdx new file mode 100644 index 00000000..7d5c811c --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/integrations/vue/ssr.mdx @@ -0,0 +1,79 @@ +--- +id: ssr +title: SSR support +sidebar_label: SSR support +--- + +To use Tolgee with your SSR framework such as Vike (vite-plugin-ssr), you can provide localization data imported as object +using `staticData` props of TolgeeProvider component, this data will be loaded directly into cache and immediately +available with first render for SSR. We also need to know user's locale already on the server and set it through TolgeeProvider `language` prop. + +```ts +import { Tolgee, DevTools, VueTolgee, FormatSimple } from '@tolgee/vue'; + +const tolgee = Tolgee() + .use(DevTools()) + .use(FormatSimple()) + .init({ + defaultLanguage: 'en', + }); + +... + +app.use(VueTolgee, { tolgee, enableSSR: true }); +``` + +and in the your root component + +```html +<script setup> +import localeEn from 'i18n/en.json'; +import localeDe from 'i18n/de.json'; + +const staticData = { + en: localeEn, + de: localeDe, +}; + +// we need to get these on server, which we'll need to implement +// differently for each framework +const language = ?; +</script> + +... + +<template> + <TolgeeProvider :language="language" :static-data="staticData" ...> + ... + </TolgeeProvider> +</template> +``` + +With this approach we include all translations directly in the bundle regardless user locale. For smaller projects this is not a big issue, however it might be significant for large applications with many translations and languages. + +For these cases we need to only provide statically the locale, that the user is currently using. We can also use async functions in `staticData` which will be used for fetching translations dynamically on client side (you can use this instead of having them in public folder). + +```html +<script setup> + +// we need to get these on server, which we'll need to implement +// differently for each framework +const language = ?; +const staticData = ?; +</script> + +... + +<template> + <TolgeeProvider :language="language" :static-data="staticData" ...> + ... + </TolgeeProvider> +</template> +``` + +## Language changing + +When we use SSR, we have to specify language in a way that is detectable by both client and server. Easiest way is to +include it directly in URL. + +Then for language change we use the native way of the framework. diff --git a/js-sdk_versioned_docs/version-5.x.x/integrations/vue/switching_languages.mdx b/js-sdk_versioned_docs/version-5.x.x/integrations/vue/switching_languages.mdx new file mode 100644 index 00000000..3c1bfbad --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/integrations/vue/switching_languages.mdx @@ -0,0 +1,29 @@ +--- +id: switching_language +title: Switching language +sidebar_label: Switching language +slug: switching-language +description: "Learn to manage language switching in Vue apps using Tolgee. Guide demonstrates how to use the useTolgee composable function and handle language events, with code examples for implementation." +--- + +For language management, the Tolgee integration provides the [`useTolgee`](./api#composable-usetolgee) composable function. Use this function with subscription to the `language` event. Below is an example of how to use it for switching languages. + +```html +<template> + <select :value="tolgee.getLanguage()" v-on:change="changeLanguage"> + ... + </select> +</template> + +<script setup> + import { useTolgee } from '@tolgee/vue'; + + const tolgee = useTolgee(['language']); + + const changeLanguage = (e) => { + tolgee.value.changeLanguage(e.target.value); + }; +</script> +``` + +> Read more about [Language change, detection and storage](/language.mdx) \ No newline at end of file diff --git a/js-sdk_versioned_docs/version-5.x.x/integrations/vue/translating.mdx b/js-sdk_versioned_docs/version-5.x.x/integrations/vue/translating.mdx new file mode 100644 index 00000000..db324daa --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/integrations/vue/translating.mdx @@ -0,0 +1,75 @@ +--- +id: translating +title: Translating +sidebar_label: Translating +description: "Learn to implement translations in Vue using Tolgee. Guide covers global $t function, useTranslate composable, and T component. Includes examples for basic usage, namespaces, and parameter interpolation." +--- + +import TFunctionHint from '../../shared/_TFunctionHint.mdx'; +import NamespacesHint from '../../shared/_NamespacesHint.mdx'; +import ExampleBanner from '../../shared/ExampleBanner'; + + +You can implement translation in your Vue application in the following ways. + +- Using the [global `$t` function](##global-t-function) +- Using the [`useTranslate` composable](#usetranslate-composable) +- Using the [`T` component](#the-t-component) + +## Global `$t` function + +The [`VueTolgee`](./api#vuetolgee-plugin) plugin provides a `$t` function that allows you to translate strings in your Vue application. If the `VueTolgee` plugin is registered, the `$t` function is available globally in your application. + +```html +<template> + <div>{{ $t('this_is_a_key') }}</div> +</template> +``` + +## `useTranslate` composable + +The Tolgee integration library provides the [`useTranslate`](./api#composable-usetranslate) composable, which comes with a translation function ([`t` function](./api#function-t-ref)). Using this `t` function, you can render the actual translation. + +```html +<template> + <div :title="t('key')">...</div> +</template> + +<script setup> + import { useTranslate } from '@tolgee/vue'; + + const { t } = useTranslate(); +</script> +``` + +<TFunctionHint /> + +### Using namespaces + +The `useTranslate` composable can be also used for loading additional namespaces. + +```ts +const { t, isLoading } = useTranslate('common'); +``` + +<NamespacesHint /> + +## The `T` component + +An alternative way is to use the [`T` component](./api#t-component). It has a very similar API to the `t` function mentioned above. + +```html +<template> + <T + keyName="translation_key" + defaultValue="User has {count} points" + :params="{ count: 10 }" + /> +</template> + +<script setup> + import { T } from '@tolgee/vue'; +</script> +``` + +<ExampleBanner framework="Vue" /> \ No newline at end of file diff --git a/js-sdk_versioned_docs/version-5.x.x/keys_tagging.mdx b/js-sdk_versioned_docs/version-5.x.x/keys_tagging.mdx new file mode 100644 index 00000000..c7f19286 --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/keys_tagging.mdx @@ -0,0 +1,23 @@ +--- +id: keys_tagging +title: Tagging new keys +description: 'Automatical pre-selecting tags for newly created keys.' +--- + +import { ScreenshotWrapper } from '../../platform/shared/_ScreenshotWrapper'; + + +For larger projects, it might be beneficial to keep track which keys are newly created and which are already used on production. + +Tolgee SDK offers a simple option to preselect a tag when creating new key through in-context UI. + +```ts +tolgee.init({ + ... + tagNewKeys: ['draft'] +}) +``` + +This will result in `draft` tag being preselected in In-context translating UI: + + \ No newline at end of file diff --git a/js-sdk_versioned_docs/version-5.x.x/language.mdx b/js-sdk_versioned_docs/version-5.x.x/language.mdx new file mode 100644 index 00000000..377437b4 --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/language.mdx @@ -0,0 +1,52 @@ +--- +id: language +title: Language +description: 'Language of the application UI with Tolgee. To change language use changeLanguage method.' +--- + +To change language use [`changeLanguage`](./api/core_package/tolgee.mdx#changelanguage) method. + +```ts +await tolgee.changeLanguage('es'); +``` + +## Getting current language + +When Tolgee is running, this will first change `pendingLanguage` property, loads required translation file(s) (when they are not already in the cache) and then changes `language` property. + +Use [`getLanguage`](./api/core_package/tolgee.mdx#getlanguage) or [`getPendingLanguage`](./api/core_package/tolgee.mdx#getpendinglanguage) methods to read current state. + +You can also listen to `language` and `pendingLanguage` [events](./api/core_package/events). + +> When Tolgee is not running, `changeLanguage` won't fetch translations, it only changes the internal state + +## Language detection + +Tolgee includes [`LanguageDetector`](./api/web_package/plugins#languagedetector) plugin, which tries to detect language from browser `window.navigator.language` property. + +If you use language detector Tolgee needs to know available languages which you can provide with `availableLanguages` property or if you provide `staticData` it will be taken from there. You also have to provide `defaultLanguage` property, so Tolgee knows which language should be picked if detection fails. + +```ts +const tolgee = Tolgee() + .use(LanguageDetector()) + .init({ + availableLanguages: ['en', 'cs', 'es', 'fr'], + defaultLanguage: 'en' + }) +``` + +## Language storage + +Once user selects his language Tolgee can remember it for the next time. Use [`LanguageStorage`](./api/web_package/plugins#languagestorage) plugin, for storing language settings in the browser local storage. + +Tolgee checks if the stored language is valid and because of that you need to specify `availableLanguages` or define language data through `staticData`. + +```ts +const tolgee = Tolgee() + .use(LanguageStorage()) + .init({ + availableLanguages: ['en', 'cs', 'es', 'fr'], + }) +``` + +> Read more about [Tolgee Plugins](./plugins.mdx). diff --git a/js-sdk/migration_to_v5/core.mdx b/js-sdk_versioned_docs/version-5.x.x/migration_to_v5/core.mdx similarity index 100% rename from js-sdk/migration_to_v5/core.mdx rename to js-sdk_versioned_docs/version-5.x.x/migration_to_v5/core.mdx diff --git a/js-sdk/migration_to_v5/i18next.mdx b/js-sdk_versioned_docs/version-5.x.x/migration_to_v5/i18next.mdx similarity index 100% rename from js-sdk/migration_to_v5/i18next.mdx rename to js-sdk_versioned_docs/version-5.x.x/migration_to_v5/i18next.mdx diff --git a/js-sdk/migration_to_v5/ngx.mdx b/js-sdk_versioned_docs/version-5.x.x/migration_to_v5/ngx.mdx similarity index 100% rename from js-sdk/migration_to_v5/ngx.mdx rename to js-sdk_versioned_docs/version-5.x.x/migration_to_v5/ngx.mdx diff --git a/js-sdk/migration_to_v5/react.mdx b/js-sdk_versioned_docs/version-5.x.x/migration_to_v5/react.mdx similarity index 100% rename from js-sdk/migration_to_v5/react.mdx rename to js-sdk_versioned_docs/version-5.x.x/migration_to_v5/react.mdx diff --git a/js-sdk/migration_to_v5/svelte.mdx b/js-sdk_versioned_docs/version-5.x.x/migration_to_v5/svelte.mdx similarity index 100% rename from js-sdk/migration_to_v5/svelte.mdx rename to js-sdk_versioned_docs/version-5.x.x/migration_to_v5/svelte.mdx diff --git a/js-sdk/migration_to_v5/vue.mdx b/js-sdk_versioned_docs/version-5.x.x/migration_to_v5/vue.mdx similarity index 100% rename from js-sdk/migration_to_v5/vue.mdx rename to js-sdk_versioned_docs/version-5.x.x/migration_to_v5/vue.mdx diff --git a/js-sdk_versioned_docs/version-5.x.x/namespaces.mdx b/js-sdk_versioned_docs/version-5.x.x/namespaces.mdx new file mode 100644 index 00000000..567af875 --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/namespaces.mdx @@ -0,0 +1,48 @@ +--- +id: namespaces +title: Namespaces +description: 'Tolgee namespaces with vanilla JS. Namespaces are a way how to separate translations into multiple files, which can be downloaded only when needed.' +--- + +Tolgee namespaces are a way how to separate translations into multiple files, which can be downloaded only when needed. By default `Tolgee` uses "" (empty string) namespace. You can change this through initial [`Options`](./api/core_package/options). + +```ts +const tolgee = Tolgee().init({ + // set default namespace + defaultNs: 'common', + + // define which namespaces should be fetched initially + ns: ['common', 'test'], +}); +``` + +## Definition through `staticData` + +You can tell Tolgee how to get namespaces through [`staticData`](./api/core_package/options#staticdata), ideally with async function: + +```ts +const tolgee = Tolgee().init({ + staticData: { + 'en:common': () => import('./i18n/common/en.json'), + 'en:test': () => import('./i18n/test/en.json'), + }, +}); +``` + +You can also use plugins for loading namespaces check [Providing static data](./providing-static-data). + +## Active namespaces + +To download new namespaces dynamically you can change active namespaces with [`addActiveNs`](./api/core_package/tolgee.mdx#addactivens) method. Active namespaces are automatically fetched and also when you change the languge (when tolgee is running). + +```ts +tolgee.addActiveNs('newNamespace'); +``` + +Removing active namespace: + +```ts +tolgee.removeActiveNs('newNamespace'); +``` + +Tolgee internally rembers how many times is each namespace used and removed, so it will only remove namespace if [`removeActiveNs`](./api/core_package/tolgee.mdx#removeactivens) was called the same time as [`addActiveNs`](./api/core_package/tolgee.mdx#addactivens). diff --git a/js-sdk_versioned_docs/version-5.x.x/plugins.mdx b/js-sdk_versioned_docs/version-5.x.x/plugins.mdx new file mode 100644 index 00000000..9855e894 --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/plugins.mdx @@ -0,0 +1,30 @@ +--- +id: plugins +title: Plugins +sidebar_label: Plugins +description: 'Plugins of the application UI with Tolgee in Vanilla JS.' +--- + +For adding further functionality Tolgee SDK contains a plugin system. You can add them at the Tolgee initialization: + +```ts +const tolgee = Tolgee() + .use(DevTools()) // <-– plugin + .use(FormatSimple()) // <-- another plugin + .init(...) +``` + +## Existing plugins + - [DevTools](./api/web_package/plugins#devtools) - for in-context translating in dev mode + +#### Formatters + - [FormatSimple](./api/core_package/format-simple) - bundle size friendly simple formatter + - [FormatIcu](./formatting#icu-formatter) - full ICU formatter + +#### Backends (data fetching) + - [BackendFetch](./api/web_package/plugins#backendfetch) - fetch data from custom backend + +#### Language helpers + - [LanguageStorage](./api/web_package/plugins#languagestorage) - store language in LocalStorage + - [LanguageDetector](./api/web_package/plugins#languagedetector) - detect user language from browser + diff --git a/js-sdk_versioned_docs/version-5.x.x/providing_static_data.mdx b/js-sdk_versioned_docs/version-5.x.x/providing_static_data.mdx new file mode 100644 index 00000000..3caae8d6 --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/providing_static_data.mdx @@ -0,0 +1,156 @@ +--- +id: providing_static_data +title: Providing static data +slug: providing-static-data +--- + +Provide static localization data in production mode or if you want to use it [without Tolgee platform](./usage-without-platform). + +## Load translations directly from Tolgee + +The easiest way to get to your localization files on production is to set up [Tolgee Content Delivery](/platform/projects_and_organizations/content_delivery) and fetch the translations directly from there. + +```ts +import { BackendFetch } from '@tolgee/react'; + +const tolgee = Tolgee() + ... + .use(BackendFetch({ prefix: '<your content storage link>'})) + ... +``` + +## Use localization files directly + +Other option is to export localization files Tolgee platform manually and bundle them directly with your application. + +### Export with CLI + + +Install [`@tolgee/cli`](/tolgee-cli) package: + +```bash +# install Tolgee cli +npm i -g @tolgee/cli + +# login to tolgee platform +tolgee login <Your-Personal-Access-Token> + +# pull translation files to ./i18n folder +tolgee pull ./i18n +``` + +### Providing data using dynamic import + +To provide your localization data using dynamic import you will need to add providers for every supported language to [`staticData`](./api/core_package/options#staticdata). + +```jsx +const tolgee = Tolgee().init({ + ... + staticData: { + en: () => import('./i18n/en.json'), + de: () => import('./i18n/de.json'), + + // or for namespaces + 'de:common': () => import('./i18n/common/de.json'), + } +}) +``` + +:::info +For some build systems you'll need to use <br/> +`en: () => import('./i18n/en.json').then(m => m.default)` +::: + + +Using this approach data will be fetched just when it's needed, so you will save some network traffic. + +### Using imported object + +```jsx +import localeEn from './i18n/en.json'; +import localeDe from './i18n/de.json'; + +import commonDe from './i18n/common/de.json' + +... + +const tolgee = Tolgee().init({ + ... + staticData: { + en: localeEn, + de: localeDe, + + // or for namespaces + 'de:common': commonDe, + } +}) +``` + +Using this approach, all localization data are bundled with your application. Don't use it, if our translations files are large. This approach is useful on SSR, when you need the translations to be available for initial render. + +### Providing data using backend plugin + +```jsx +import { BackendFetch } from '@tolgee/react'; + +tolgee.use(BackendFetch()); +``` + +[`BackendFetch`](./api/web_package/plugins#backendfetch) will fetch translation files (en.json, de.json) from `https://<your url>/i18n`, so you don't have to list all the files explicitly. + +If you don't use namespaces place your translation into `/i18n` folder: + +``` +├── i18n +│ ├── cs.json +│ └── en.json +├── index.html +``` + +If you use namespaces, it should look like this: + +``` +├── i18n +│ └── common +│ ├── en.json +│ └── de.json +├── index.html +``` + +> This is default behavior, it's possible to customize in [`BackendFetch`](./api/web_package/plugins#backendfetch) plugin. + + +## Data fallbacks + +You can provide local data as a fallback for CDN, for cases when network request fails. + +```ts +const tolgee = Tolgee() + .use(BackendFetch({ + prefix: '<your content storage link>', + fallbackOnFail: true + })) + .init({ + staticData: { + en: () => import('./i18n/en.json'), + de: () => import('./i18n/de.json'), + } + ... + }) +``` + +`fallbackOnFail` option will tell Tolgee to look for data in the next source, so it will fetch your local data. **Order of plugins is important here, they are used in the same order as they were added.** + +:::info Plugins are used in the same order as they were added. +Tolgee first checks if data aren't already in cache (data passed directly to `staticData`) then all the plugins and then dynamic data from `staticData` field. +::: + +You can also set a timeout, to only wait certain time for the data from CDN. + +```ts +BackendFetch({ + prefix: '<your content storage link>', + fallbackOnFail: true + timeout: 10_000 // 10 seconds +}) +``` \ No newline at end of file diff --git a/js-sdk_versioned_docs/version-5.x.x/shared/ExampleBanner.tsx b/js-sdk_versioned_docs/version-5.x.x/shared/ExampleBanner.tsx new file mode 100644 index 00000000..42789182 --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/shared/ExampleBanner.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import Link from '@docusaurus/Link'; +import Admonition from '@theme/Admonition'; + +export default function ExampleBanner({ framework, appName }) { + return ( + <Admonition type="tip"> + You can also check the{' '} + <Link + href={`https://github.com/tolgee/${ + appName || framework.toLowerCase() + }-example`} + > + {framework} example application + </Link>{' '} + to learn more. + </Admonition> + ); +} diff --git a/js-sdk_versioned_docs/version-5.x.x/shared/_NamespacesHint.mdx b/js-sdk_versioned_docs/version-5.x.x/shared/_NamespacesHint.mdx new file mode 100644 index 00000000..218fa2d6 --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/shared/_NamespacesHint.mdx @@ -0,0 +1,3 @@ +This example will load `common` namespace which can be then used with `t` function. + +> Read more about namespaces [here](../namespaces.mdx). \ No newline at end of file diff --git a/js-sdk_versioned_docs/version-5.x.x/shared/_PreparingForProduction.mdx b/js-sdk_versioned_docs/version-5.x.x/shared/_PreparingForProduction.mdx new file mode 100644 index 00000000..4413958f --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/shared/_PreparingForProduction.mdx @@ -0,0 +1,8 @@ +Tolgee will automatically omit [`DevTools`](../api/web_package/plugins.mdx#devtools) from your bundle when you build your app for production. So it won't fetch translations directly from Tolgee Platform and it won't allow users to modify translations. + +There are generally two ways how to use translations in production: + + - [Tolgee Content Delivery](/platform/projects_and_organizations/content_delivery) - translations are loaded dynamically from fast and reliable storage + - [Providing localization files directly](/providing_static_data.mdx#use-localization-files-directly) - your translations are bundled with your code + +**In production mode, you should never use localization data directly from Tolgee REST API**, because it can negatively affect your page performance. diff --git a/js-sdk_versioned_docs/version-5.x.x/shared/_TFunctionHint.mdx b/js-sdk_versioned_docs/version-5.x.x/shared/_TFunctionHint.mdx new file mode 100644 index 00000000..c7ce6eea --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/shared/_TFunctionHint.mdx @@ -0,0 +1,36 @@ +## `t` function + +This function allows you to render the actual translation. + +#### Simple usage + +```ts +t('app_title') +``` + +The `t` function looks into your translations finds an appropriate key and renders the translation for currently selected language + +> If you use Typescript [read about typed keys](../typed_keys.mdx) + +#### Default value + +You can pass the default value as second parameter, which will be rendered if the key doesn't exist yet. + +```ts +t('non_existant_key', 'Default value') +``` + +#### Parameter interpolation + +You can supply a variable parameters which will then be rendered in your translations. + +```ts +t('user_points', 'User has {count} points', { count: 10 }) + +// -> User has 10 points +``` + +There are more options you can do with the variable parameters, but it depends on selected [formatter plugin](../formatting.mdx). + +> To get the full `t` function specification [check it's API](../api/core_package/tolgee.mdx#t) + diff --git a/js-sdk_versioned_docs/version-5.x.x/text_observer.mdx b/js-sdk_versioned_docs/version-5.x.x/text_observer.mdx new file mode 100644 index 00000000..c88d48c8 --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/text_observer.mdx @@ -0,0 +1,57 @@ +--- +id: text_observer +title: Text observer +slug: text-observer +description: "Text observer an alternative observer to default InvisibleObserver: it uses text format instead of invisible characters." + +--- + +Text observer an alternative observer to the default invisible observer. It uses text format instead of invisible characters. Main difference is that initially we put a placeholder into the dom, which is replaced by correct translation by mutation observer. + +Advantage of this is that all necessary data are included in the placeholder itself, so you can e.g. render the translation on the server and if you use Tolgee on FE it will get picked up and can be edited. Text observer is able to update translation live on the page automatically, so in-context will work properly. + +Disadvantages of this approach are that translations will be invalid until `MutationObserver` finds them. So when you use this e.g. in page title it won't work. Also it can cause problems with things like tooltips, because their position is usually based on initial text size. You can generally use `noWrap` parameter where it causes problems: + +```ts +t('title', { noWrap: true }); +``` + +## Usage + +You can switch to text observer through [tolgee options](./api/core_package/options#observertype), where you can also define other options. + +```ts +const tolgee = Tolgee() + .use(DevTools()) + .init({ + ... + observerType: 'text' + observerOptions: { ... } + }); +``` + +## Format + +Placeholders are in following format: + +``` +<prefix><key>[|<namespace>][,<defaultValue>][:<param1>:<value1>,...]<suffix> +``` + +Prefix and suffix can be set through `inputPrefix` and `inputSuffix` options, by default it's `%-%tolgee:` and `%-%`. + +Example for `t('key', 'Default value', { ns: 'namespace', parameter: 'Test' })` will generate this placeholder: + +``` +%-%tolgee:key|namespace,Default value:parameter:Test%-% +``` + +If necessary, special characters are escaped with `\`. + +## When to use + +This wrapper is more universal, as it is able to register translations generated on server easily, however it is more invasive and translation parameters need to be serializable (so it won't work with tag interpolation in React). + +:::info +Text observer is part of [`ObserverPlugin`](./api/web_package/plugins#observerplugin), which is included in [`DevTools`](./api/web_package/plugins#observerplugin). +::: \ No newline at end of file diff --git a/js-sdk_versioned_docs/version-5.x.x/typed_keys.mdx b/js-sdk_versioned_docs/version-5.x.x/typed_keys.mdx new file mode 100644 index 00000000..e5a594f4 --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/typed_keys.mdx @@ -0,0 +1,40 @@ +--- +id: typed_keys +title: Typed translation keys +description: 'Adding type definitions to the translation keys.' +--- + +If you want your keys to be typed with TypeScript you can do so with the following `tolgee.d.ts` file: + +```ts +// tolgee.d.ts + +import type en from './i18n/en.json'; + +declare module '@tolgee/core/lib/types' { + type TranslationsType = typeof en; + + // ensures that nested keys are accessible with "." + type DotNotationEntries<T> = T extends object + ? { + [K in keyof T]: `${K & string}${T[K] extends undefined + ? '' + : T[K] extends object + ? `.${DotNotationEntries<T[K]>}` + : ''}`; + }[keyof T] + : ''; + + // enables both intellisense and new keys without an error + type LiteralUnion<LiteralType extends BaseType, BaseType extends Primitive> = + | LiteralType + | (BaseType & { _?: never }); + + export type TranslationKey = LiteralUnion< + DotNotationEntries<TranslationsType>, + string + >; +} +``` + +This setup will give you TypeScript intellisense for existing keys but also allow you to add non-existing keys. If you intentionally want TypeScript errors for non-existing keys, just remove `LiteralUnion`. diff --git a/js-sdk_versioned_docs/version-5.x.x/usage_without_platform.mdx b/js-sdk_versioned_docs/version-5.x.x/usage_without_platform.mdx new file mode 100644 index 00000000..6072fc60 --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/usage_without_platform.mdx @@ -0,0 +1,44 @@ +--- +id: usage_without_platform +slug: usage-without-platform +title: Usage without platform +description: 'Use Tolgee SDK as regular i18n library without Tolgee Platform.' +--- + +Tolgee SDK is designed as regular i18n library and therefore it can be used as such without integration with Tolgee Platform. If you won't include `apiUrl` and `apiKey` to the Tolgee options it will only fetch data locally. + +```ts +import { Tolgee, DevTools } from '@tolgee/web'; + +const tolgee = Tolgee() + .use(DevTools()) + .use(FormatSimple()) + .init({ + language: 'en', + staticData: { + ... + } + }); +``` + +> For more options check [Providing static data](./providing-static-data) + +### Static files structure + +You can manage static files manually and use DevTools for easier access to translation key. Tolgee accepts json files with either flat or nested structure: + +```json +{ + "nested.key": "Key" +} +``` + +This is also accepted: + +```json +{ + "nested": { + "key": "Key" + } +} +``` \ No newline at end of file diff --git a/js-sdk_versioned_docs/version-5.x.x/wrapping.mdx b/js-sdk_versioned_docs/version-5.x.x/wrapping.mdx new file mode 100644 index 00000000..cf5c3ec1 --- /dev/null +++ b/js-sdk_versioned_docs/version-5.x.x/wrapping.mdx @@ -0,0 +1,57 @@ +--- +id: wrapping +title: Wrapping and observing +description: 'Learn about two ways of wrapping in Tolgee: text wrapping and invisible wrapping. You can configure this through wrapperMode.' +--- + +## Invisible wrapping (default) + +Tolgee offers unique technology for in-context translating, it combines simplicity of regular i18n libraries with +comfort of in-context translating directly in your app. + +How it works? Try to run tolgee in development mode: + +```ts +import { Tolgee, DevTools } from '@tolgee/web'; + +const tolgee = Tolgee().use(DevTools()).init({ + language: 'en', + apiUrl: 'https://app.tolgee.io', + apiKey: '<your project API key>', +}); + +tolgee.run(); + +console.log(Array.from(tolgee.t('test'))); +``` + +You should see translation individual characters that were produced by [`t`](./api/core_package/tolgee.mdx#t) function. + +```ts +// [... translation value ... , "", "", "", "", "", "", "", "", ""] +``` + +What are these empty characters at the end? They are not actually empty, only zero width, so they are not visible. + +Tolgee passes secret information into each translation, which is then detectable in the dom. +We use [`MutationObserver`](https://developer.mozilla.org/en-US/docs/sdk/API/MutationObserver) +to check all dom changes and search for these secret characters, to find the exact locations +of translations. This method is very reliable and brings basically no overhead on the developer side. You can read more in this [blog post](/blog/2021/12/17/invisible-characters-for-better-localization). + +We call this mechanism wrapping. You can check the information, which is included with the translation by +calling [`tolgee.unwrap`](./api/core_package/tolgee.mdx#unwrap) method, which will give you the information about the translation. + +## Why this solution? + +We wanted something which is almost invisible to the developer, but reliable and doesn't break your app. + +Because we actually return the translation that should be rendered only with some extra characters, you can +use any custom formatter (even outside Tolgee) and modify the string. The secret information will stay intact as it's a valid part of the string. + +## Text wrapping + +There is also a more straightforward solution which is called [text observer](./text-observer), which uses plain text for encoding the key info and can be more practical in some cases. + +:::info +Wrapping is part of [`ObserverPlugin`](./api/web_package/plugins#observerplugin), which is included in [`DevTools`](./api/web_package/plugins#devtools). +::: diff --git a/js-sdk_versioned_sidebars/version-5.x.x-sidebars.json b/js-sdk_versioned_sidebars/version-5.x.x-sidebars.json new file mode 100644 index 00000000..5cbdf5b5 --- /dev/null +++ b/js-sdk_versioned_sidebars/version-5.x.x-sidebars.json @@ -0,0 +1,155 @@ +{ + "someSidebar": [ + "about", + "get_started", + { + "label": "Integrations", + "collapsed": false, + "type": "category", + "items": [ + { + "label": "React", + "type": "category", + "items": [ + "integrations/react/overview", + "integrations/react/installation", + "integrations/react/translating", + "integrations/react/tags_interpolation", + "integrations/react/switching_language", + { + "label": "Next.js", + "type": "category", + "items": [ + "integrations/react/next/introduction", + "integrations/react/next/pages-router", + "integrations/react/next/app-router", + "integrations/react/next/app-router-next-intl" + ] + }, + "integrations/react/ssr", + "integrations/react/react_native", + "integrations/react/api" + ] + }, + { + "label": "Angular", + "type": "category", + "items": [ + "integrations/angular/overview", + "integrations/angular/installation", + "integrations/angular/translating", + "integrations/angular/namespaces", + "integrations/angular/switching_language", + "integrations/angular/html_tags", + "integrations/angular/api" + ] + }, + { + "label": "Vue", + "type": "category", + "items": [ + "integrations/vue/overview", + "integrations/vue/installation", + "integrations/vue/translating", + "integrations/vue/component_interpolation", + "integrations/vue/switching_language", + "integrations/vue/ssr", + "integrations/vue/api" + ] + }, + { + "label": "Svelte", + "type": "category", + "items": [ + "integrations/svelte/overview", + "integrations/svelte/installation", + "integrations/svelte/translating", + "integrations/svelte/switching_language", + "integrations/svelte/api" + ] + }, + { + "label": "i18next", + "type": "category", + "items": [ + "integrations/i18next/installation", + "integrations/i18next/react", + "integrations/i18next/vue", + "integrations/i18next/api" + ] + }, + { + "label": "Vanilla JS", + "type": "category", + "items": [ + "integrations/vanilla/installation", + "integrations/vanilla/initialization", + "integrations/vanilla/translating" + ] + } + ] + }, + { + "label": "Core concepts", + "type": "category", + "collapsed": false, + "items": [ + "formatting", + "language", + "namespaces", + "in_context", + "wrapping", + "providing_static_data", + "filter_by_tags" + ] + }, + "keys_tagging", + "plugins", + "text_observer", + "typed_keys", + "usage_without_platform", + { + "label": "API", + "type": "category", + "items": [ + "api/packages", + { + "label": "Core package", + "type": "category", + "items": [ + "api/core_package/about", + "api/core_package/tolgee", + "api/core_package/options", + "api/core_package/format_simple", + "api/core_package/other_tools", + "api/core_package/events", + "api/core_package/plugin", + "api/core_package/observer_options" + ] + }, + { + "label": "Web package", + "type": "category", + "items": [ + "api/web_package/about", + "api/web_package/plugins", + "api/web_package/tools", + "api/web_package/constants" + ] + } + ] + }, + { + "type": "category", + "label": "Migration to v5", + "items": [ + "migration_to_v5/core", + "migration_to_v5/react", + "migration_to_v5/ngx", + "migration_to_v5/svelte", + "migration_to_v5/vue", + "migration_to_v5/i18next" + ] + } + ] +} diff --git a/js-sdk_versions.json b/js-sdk_versions.json index 4e4fc033..387979f1 100644 --- a/js-sdk_versions.json +++ b/js-sdk_versions.json @@ -1,3 +1,4 @@ [ + "5.x.x", "4.x.x" ] diff --git a/sidebarJsSdk.js b/sidebarJsSdk.js index 3814eda9..53af3466 100644 --- a/sidebarJsSdk.js +++ b/sidebarJsSdk.js @@ -101,6 +101,7 @@ module.exports = { 'wrapping', 'providing_static_data', 'filter_by_tags', + 'fetching_translations' ], }, 'keys_tagging', @@ -139,17 +140,6 @@ module.exports = { }, ], }, - { - type: 'category', - label: 'Migration to v5', - items: [ - 'migration_to_v5/core', - 'migration_to_v5/react', - 'migration_to_v5/ngx', - 'migration_to_v5/svelte', - 'migration_to_v5/vue', - 'migration_to_v5/i18next', - ], - }, + 'migration_to_v6' ], }; diff --git a/static/img/blog/sdk-v6/SDK6-dark.webp b/static/img/blog/sdk-v6/SDK6-dark.webp new file mode 100644 index 00000000..44d9fb07 Binary files /dev/null and b/static/img/blog/sdk-v6/SDK6-dark.webp differ diff --git a/static/img/blog/sdk-v6/SDK6-light.webp b/static/img/blog/sdk-v6/SDK6-light.webp new file mode 100644 index 00000000..90293df9 Binary files /dev/null and b/static/img/blog/sdk-v6/SDK6-light.webp differ