Skip to content

Commit 91191a3

Browse files
docs: reference docs for Lingo.dev Compiler (#1048)
* docs: reference docs for Lingo.dev Compiler * docs: update LocaleSwitcher docs * docs: improve * docs: improve * chore: remove rules * docs: removoe * docs: updates * docs: updates * docs: fix error * docs: clarify stubs * docs: minor tweak * fix: code examples * docs: fix React Router examples * docs: add init examples --------- Co-authored-by: Max Prilutskiy <[email protected]>
1 parent 85dfc10 commit 91191a3

File tree

10 files changed

+496
-1
lines changed

10 files changed

+496
-1
lines changed

packages/compiler/src/index.ts

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,28 @@ const unplugin = createUnplugin<Partial<typeof defaultParams> | undefined>(
156156
);
157157

158158
export default {
159+
/**
160+
* Initializes Lingo.dev Compiler for Next.js (App Router).
161+
*
162+
* @param compilerParams - The compiler parameters.
163+
*
164+
* @returns The Next.js configuration.
165+
*
166+
* @example Configuration for Next.js's default template
167+
* ```ts
168+
* import lingoCompiler from "lingo.dev/compiler";
169+
* import type { NextConfig } from "next";
170+
*
171+
* const nextConfig: NextConfig = {
172+
* /* config options here *\/
173+
* };
174+
*
175+
* export default lingoCompiler.next({
176+
* sourceRoot: "app",
177+
* models: "lingo.dev",
178+
* })(nextConfig);
179+
* ```
180+
*/
159181
next:
160182
(
161183
compilerParams?: Partial<typeof defaultParams> & {
@@ -250,6 +272,51 @@ export default {
250272

251273
return nextConfig;
252274
},
275+
/**
276+
* Initializes Lingo.dev Compiler for Vite.
277+
*
278+
* @param compilerParams - The compiler parameters.
279+
*
280+
* @returns The Vite configuration.
281+
*
282+
* @example Configuration for Vite's "react-ts" template
283+
* ```ts
284+
* import { defineConfig, type UserConfig } from "vite";
285+
* import react from "@vitejs/plugin-react";
286+
* import lingoCompiler from "lingo.dev/compiler";
287+
*
288+
* // https://vite.dev/config/
289+
* const viteConfig: UserConfig = {
290+
* plugins: [react()],
291+
* };
292+
*
293+
* export default defineConfig(() =>
294+
* lingoCompiler.vite({
295+
* models: "lingo.dev",
296+
* })(viteConfig)
297+
* );
298+
* ```
299+
*
300+
* @example Configuration for React Router's default template
301+
* ```ts
302+
* import { reactRouter } from "@react-router/dev/vite";
303+
* import tailwindcss from "@tailwindcss/vite";
304+
* import lingoCompiler from "lingo.dev/compiler";
305+
* import { defineConfig, type UserConfig } from "vite";
306+
* import tsconfigPaths from "vite-tsconfig-paths";
307+
*
308+
* const viteConfig: UserConfig = {
309+
* plugins: [tailwindcss(), reactRouter(), tsconfigPaths()],
310+
* };
311+
*
312+
* export default defineConfig(() =>
313+
* lingoCompiler.vite({
314+
* sourceRoot: "app",
315+
* models: "lingo.dev",
316+
* })(viteConfig)
317+
* );
318+
* ```
319+
*/
253320
vite: (compilerParams?: Partial<typeof defaultParams>) => (config: any) => {
254321
const mergedParams = _.merge(
255322
{},

packages/react/src/client/loader.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,32 @@
1+
/**
2+
* A placeholder function for loading dictionaries that contain localized content.
3+
*
4+
* This function:
5+
*
6+
* - Should be used in client-side rendered applications (e.g., Vite-based apps)
7+
* - Should be passed into the `LingoProviderWrapper` component
8+
* - Is transformed into functional code by Lingo.dev Compiler
9+
*
10+
* @param locale - The locale to load the dictionary for.
11+
*
12+
* @returns Promise that resolves to the dictionary object containing localized content.
13+
*
14+
* @example Use in a Vite application
15+
* ```tsx
16+
* import React from "react";
17+
* import ReactDOM from "react-dom/client";
18+
* import { LingoProviderWrapper, loadDictionary } from "lingo.dev/react/client";
19+
* import { App } from "./App.tsx";
20+
*
21+
* ReactDOM.createRoot(document.getElementById("root")!).render(
22+
* <React.StrictMode>
23+
* <LingoProviderWrapper loadDictionary={(locale) => loadDictionary(locale)}>
24+
* <App />
25+
* </LingoProviderWrapper>
26+
* </React.StrictMode>,
27+
* );
28+
* ```
29+
*/
130
export const loadDictionary = async (locale: string): Promise<any> => {
231
return {};
332
};

packages/react/src/client/locale-switcher.tsx

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,46 @@
33
import { useState, useEffect } from "react";
44
import { getLocaleFromCookies, setLocaleInCookies } from "./utils";
55

6+
/**
7+
* The props for the `LocaleSwitcher` component.
8+
*/
69
export type LocaleSwitcherProps = {
7-
className?: string;
10+
/**
11+
* An array of locale codes to display in the dropdown.
12+
*
13+
* This should contain both the source and target locales.
14+
*/
815
locales: string[];
16+
/**
17+
* A custom class name for the dropddown's `select` element.
18+
*/
19+
className?: string;
920
};
1021

22+
/**
23+
* An unstyled dropdown for switching between locales.
24+
*
25+
* This component:
26+
*
27+
* - Only works in environments that support cookies
28+
* - Gets and sets the current locale from the `"lingo-locale"` cookie
29+
* - Triggers a full page reload when the locale is changed
30+
*
31+
* @example Creating a locale switcher
32+
* ```tsx
33+
* import { LocaleSwitcher } from "lingo.dev/react/client";
34+
*
35+
* export function App() {
36+
* return (
37+
* <header>
38+
* <nav>
39+
* <LocaleSwitcher locales={["en", "es"]} />
40+
* </nav>
41+
* </header>
42+
* );
43+
* }
44+
* ```
45+
*/
1146
export function LocaleSwitcher(props: LocaleSwitcherProps) {
1247
const { locales } = props;
1348
const [locale, setLocale] = useState<string>("");

packages/react/src/client/provider.tsx

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,79 @@ import { useEffect, useState } from "react";
44
import { LingoContext } from "./context";
55
import { getLocaleFromCookies } from "./utils";
66

7+
/**
8+
* The props for the `LingoProvider` component.
9+
*/
710
export type LingoProviderProps<D> = {
11+
/**
12+
* The dictionary object that contains localized content.
13+
*/
814
dictionary: D;
15+
/**
16+
* The child components containing localizable content.
17+
*/
918
children: React.ReactNode;
1019
};
1120

21+
/**
22+
* A context provider that makes localized content from a preloaded dictionary available to its descendants.
23+
*
24+
* This component:
25+
*
26+
* - Should be placed at the top of the component tree
27+
* - Should be used in client-side applications that preload data from the server (e.g., React Router apps)
28+
*
29+
* @template D - The type of the dictionary object.
30+
* @throws {Error} When no dictionary is provided.
31+
*
32+
* @example Use in a React Router application
33+
* ```tsx
34+
* import { LingoProvider } from "lingo.dev/react/client";
35+
* import { loadDictionary } from "lingo.dev/react/react-router";
36+
* import {
37+
* Links,
38+
* Meta,
39+
* Outlet,
40+
* Scripts,
41+
* ScrollRestoration,
42+
* useLoaderData,
43+
* type LoaderFunctionArgs,
44+
* } from "react-router";
45+
* import "./app.css";
46+
*
47+
* export const loader = async ({ request }: LoaderFunctionArgs) => {
48+
* return {
49+
* lingoDictionary: await loadDictionary(request),
50+
* };
51+
* };
52+
*
53+
* export function Layout({ children }: { children: React.ReactNode }) {
54+
* const { lingoDictionary } = useLoaderData<typeof loader>();
55+
*
56+
* return (
57+
* <LingoProvider dictionary={lingoDictionary}>
58+
* <html lang="en">
59+
* <head>
60+
* <meta charSet="utf-8" />
61+
* <meta name="viewport" content="width=device-width, initial-scale=1" />
62+
* <Meta />
63+
* <Links />
64+
* </head>
65+
* <body>
66+
* {children}
67+
* <ScrollRestoration />
68+
* <Scripts />
69+
* </body>
70+
* </html>
71+
* </LingoProvider>
72+
* );
73+
* }
74+
*
75+
* export default function App() {
76+
* return <Outlet />;
77+
* }
78+
* ```
79+
*/
1280
export function LingoProvider<D>(props: LingoProviderProps<D>) {
1381
// TODO: handle case when no dictionary is provided - throw suspense? return null / other fallback?
1482
if (!props.dictionary) {
@@ -23,11 +91,51 @@ export function LingoProvider<D>(props: LingoProviderProps<D>) {
2391
);
2492
}
2593

94+
/**
95+
* The props for the `LingoProviderWrapper` component.
96+
*/
2697
export type LingoProviderWrapperProps<D> = {
98+
/**
99+
* A callback function that loads the dictionary for the current locale.
100+
*
101+
* @param locale - The locale code to load the dictionary for.
102+
*
103+
* @returns The dictionary object containing localized content.
104+
*/
27105
loadDictionary: (locale: string) => Promise<D>;
106+
/**
107+
* The child components containing localizable content.
108+
*/
28109
children: React.ReactNode;
29110
};
30111

112+
/**
113+
* A context provider that loads the dictionary for the current locale and makes localized content available to its descendants.
114+
*
115+
* This component:
116+
*
117+
* - Should be placed at the top of the component tree
118+
* - Should be used in purely client-side rendered applications (e.g., Vite-based apps)
119+
*
120+
* @template D - The type of the dictionary object containing localized content.
121+
*
122+
* @example Use in a Vite application
123+
* ```tsx file="src/main.tsx"
124+
* import { LingoProviderWrapper, loadDictionary } from "lingo.dev/react/client";
125+
* import { StrictMode } from 'react'
126+
* import { createRoot } from 'react-dom/client'
127+
* import './index.css'
128+
* import App from './App.tsx'
129+
*
130+
* createRoot(document.getElementById('root')!).render(
131+
* <StrictMode>
132+
* <LingoProviderWrapper loadDictionary={(locale) => loadDictionary(locale)}>
133+
* <App />
134+
* </LingoProviderWrapper>
135+
* </StrictMode>,
136+
* );
137+
* ```
138+
*/
31139
export function LingoProviderWrapper<D>(props: LingoProviderWrapperProps<D>) {
32140
const [dictionary, setDictionary] = useState<D | null>(null);
33141

packages/react/src/client/utils.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,53 @@
33
import { LOCALE_COOKIE_NAME, DEFAULT_LOCALE } from "../core";
44
import Cookies from "js-cookie";
55

6+
/**
7+
* Gets the current locale from the `"lingo-locale"` cookie.
8+
*
9+
* Defaults to `"en"` if:
10+
*
11+
* - Running in an environment that doesn't support cookies
12+
* - No `"lingo-locale"` cookie is found
13+
*
14+
* @returns The current locale code, or `"en"` as a fallback.
15+
*
16+
* @example Get the current locale
17+
* ```tsx
18+
* import { getLocaleFromCookies } from "lingo.dev/react/client";
19+
*
20+
* export function App() {
21+
* const currentLocale = getLocaleFromCookies();
22+
* return <div>Current locale: {currentLocale}</div>;
23+
* }
24+
* ```
25+
*/
626
export function getLocaleFromCookies(): string {
727
if (typeof document === "undefined") return DEFAULT_LOCALE;
828

929
return Cookies.get(LOCALE_COOKIE_NAME) || DEFAULT_LOCALE;
1030
}
1131

32+
/**
33+
* Sets the current locale in the `"lingo-locale"` cookie.
34+
*
35+
* Does nothing in environments that don't support cookies.
36+
*
37+
* @param locale - The locale code to store in the `"lingo-locale"` cookie.
38+
*
39+
* @example Set the current locale
40+
* ```tsx
41+
* import { setLocaleInCookies } from "lingo.dev/react/client";
42+
*
43+
* export function LanguageButton() {
44+
* const handleClick = () => {
45+
* setLocaleInCookies("es");
46+
* window.location.reload();
47+
* };
48+
*
49+
* return <button onClick={handleClick}>Switch to Spanish</button>;
50+
* }
51+
* ```
52+
*/
1253
export function setLocaleInCookies(locale: string): void {
1354
if (typeof document === "undefined") return;
1455

packages/react/src/core/const.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
/**
2+
* The default locale.
3+
*/
14
export const DEFAULT_LOCALE = "en";
5+
6+
/**
7+
* The name of the cookie that stores the current locale.
8+
*/
29
export const LOCALE_COOKIE_NAME = "lingo-locale";
10+
11+
/**
12+
* The name of the header that stores the current locale.
13+
*/
314
export const LOCALE_HEADER_NAME = "x-lingo-locale";

0 commit comments

Comments
 (0)