# gt-react: General Translation React SDK: Internationalize a Mini Shop URL: https://generaltranslation.com/en-US/docs/react/tutorials/mini-shop.mdx --- title: Internationalize a Mini Shop description: A hands-on React tutorial that internationalizes a simple shop using GT React components, hooks, and shared strings --- Get a small, fully local “mini shop” running and translated — no external services, no routing, no UI frameworks. You’ll use the core GT React features end-to-end and see how they fit together in a simple, realistic UI. Prerequisites: React, basic JavaScript/TypeScript What you’ll build - A single-page “shop” with a product grid and a simple in-memory cart - Language switcher and shared navigation labels - Properly internationalized numbers, currency, and pluralization - Optional: local translation storage for production builds Links used in this tutorial - Provider: [``](/docs/react/api/components/gtprovider) - Components: [``](/docs/react/api/components/t), [``](/docs/react/api/components/var), [``](/docs/react/api/components/num), [``](/docs/react/api/components/currency), [``](/docs/react/api/components/datetime), [``](/docs/react/api/components/branch), [``](/docs/react/api/components/plural), [``](/docs/react/api/components/locale-selector) - Strings and Shared Strings: [`useGT`](/docs/react/api/strings/use-gt), [`msg`](/docs/react/api/strings/msg), [`useMessages`](/docs/react/api/strings/use-messages) - Guides: [Variables](/docs/react/guides/variables), [Branching](/docs/react/guides/branches), [Strings](/docs/react/guides/strings), [Local Translation Storage](/docs/react/guides/local-tx), [Changing Languages](/docs/react/guides/languages) --- ## Install and Wrap Your App Install packages and wrap your app with the provider. ```bash npm i gt-react npm i --save-dev gtx-cli ``` ```bash yarn add gt-react yarn add --dev gtx-cli ``` ```bash bun add gt-react bun add --dev gtx-cli ``` ```bash pnpm add gt-react pnpm add --save-dev gtx-cli ``` Optional: Starter Project (Vite) If you’re starting from scratch, scaffold a Vite React + TypeScript app and then install GT packages: ```bash copy npm create vite@latest mini-shop -- --template react-ts cd mini-shop npm i gt-react npm i --save-dev gtx-cli ``` Then add the files in the sections below (e.g., `src/main.tsx`, `src/App.tsx`, `src/components/*`, `src/data.ts`, `src/nav.ts`). Create a minimal provider setup. ```tsx title="src/main.tsx" copy import { StrictMode } from 'react'; import { createRoot } from 'react-dom/client'; import { GTProvider } from 'gt-react'; // See: /docs/react/api/components/gtprovider import App from './App'; createRoot(document.getElementById('root')!).render( {/* Enable Spanish and French */} ); ``` Optionally add a `gt.config.json` now (useful later for CI and local storage): ```json title="gt.config.json" copy { "defaultLocale": "en", "locales": ["es", "fr"] } ``` ### Development API keys You can follow this tutorial without keys (it will render the default language). To see live translations and test language switching in development, add development keys. Learn more in [Production vs Development](/docs/react/concepts/environments). ```bash title=".env.local" copy VITE_GT_API_KEY="your-dev-api-key" VITE_GT_PROJECT_ID="your-project-id" ``` ```bash title=".env.local" copy REACT_APP_GT_API_KEY="your-dev-api-key" REACT_APP_GT_PROJECT_ID="your-project-id" ``` - Dashboard: https://dash.generaltranslation.com/signup - Or via CLI: ```bash copy npx gtx-cli auth ``` --- ## Seed data and app structure We’ll hardcode a tiny product array and keep everything client-side. No servers, no routing. ```ts title="src/data.ts" copy export type Product = { id: string; name: string; description: string; price: number; currency: 'USD' | 'EUR'; inStock: boolean; addedAt: string; // ISO date string }; export const products: Product[] = [ { id: 'p-1', name: 'Wireless Headphones', description: 'Noise-cancelling over-ear design with 30h battery', price: 199.99, currency: 'USD', inStock: true, addedAt: new Date().toISOString() }, { id: 'p-2', name: 'Travel Mug', description: 'Double-wall insulated stainless steel (12oz)', price: 24.5, currency: 'USD', inStock: false, addedAt: new Date().toISOString() } ]; ``` --- ## Shared navigation labels with msg and useMessages Use [`msg`](/docs/react/api/strings/msg) to mark shared strings in config, then decode them via [`useMessages`](/docs/react/api/strings/use-messages) at render time. ```tsx title="src/nav.ts" copy import { msg } from 'gt-react'; // See: /docs/react/api/strings/msg export const nav = [ { label: msg('Home'), href: '#' }, { label: msg('Products'), href: '#products' }, { label: msg('Cart'), href: '#cart' } ]; ``` ```tsx title="src/components/Header.tsx" copy import { LocaleSelector, T } from 'gt-react'; import { useMessages } from 'gt-react'; // See: /docs/react/api/strings/useMessages import { nav } from '../nav'; export default function Header() { const m = useMessages(); return (

Mini Shop

{/* See: /docs/react/api/components/t */}
{/* See: /docs/react/api/components/localeSelector */}
); } ``` --- ## Product cards with T, variables, Branch, and Currency Use [``](/docs/react/api/components/t) for JSX translation. Wrap dynamic content with variable components like [``](/docs/react/api/components/var), [``](/docs/react/api/components/num), [``](/docs/react/api/components/currency), and [``](/docs/react/api/components/datetime). Handle stock state via [``](/docs/react/api/components/branch). ```tsx title="src/components/ProductCard.tsx" copy import { T, Var, Num, Currency, DateTime, Branch } from 'gt-react'; import type { Product } from '../data'; export default function ProductCard({ product, onAdd }: { product: Product; onAdd: () => void; }) { return (

{product.name}

{product.description}

Price: {product.price}

Added: {product.addedAt}

In stock

} false={

Out of stock

} />
); } ``` --- ## Cart with Pluralization and Totals Use [``](/docs/react/api/components/plural) to express “X items in cart” and [``](/docs/react/api/components/currency) for totals. Combine with [``](/docs/react/api/components/t), [``](/docs/react/api/components/var), and [``](/docs/react/api/components/num). ```tsx title="src/components/Cart.tsx" copy import { T, Plural, Var, Num, Currency } from 'gt-react'; import type { Product } from '../data'; export default function Cart({ items, onClear }: { items: Product[]; onClear: () => void; }) { const total = items.reduce((sum, p) => sum + p.price, 0); const itemCount = items.length; return (

Cart

Your cart is empty

} one={

You have {itemCount} item

} other={

You have {itemCount} items

} /> {items.map((p) => (

{p.name}{p.price}

))}

Total: {total}

); } ``` --- ## Attributes and Placeholders with `useGT` Use [`useGT`](/docs/react/api/strings/use-gt) for plain string translations like input placeholders and ARIA labels. ```tsx title="src/components/Search.tsx" copy import { useGT } from 'gt-react'; export default function Search({ onQuery }: { onQuery: (q: string) => void; }) { const gt = useGT(); return ( onQuery(e.target.value)} style={{ padding: 8, width: '100%', maxWidth: 320 }} /> ); } ``` --- ## Put it together A single-page app with in-memory cart and simple search filter. ```tsx title="src/App.tsx" copy import { useMemo, useState } from 'react'; import Header from './components/Header'; import Search from './components/Search'; import ProductCard from './components/ProductCard'; import Cart from './components/Cart'; import { products } from './data'; export default function App() { const [query, setQuery] = useState(''); const [cart, setCart] = useState([]); const filtered = useMemo(() => { const q = query.toLowerCase(); return products.filter(p => p.name.toLowerCase().includes(q) || p.description.toLowerCase().includes(q) ); }, [query]); const items = products.filter(p => cart.includes(p.id)); return (
{filtered.map(p => ( setCart(c => (p.inStock ? [...new Set([...c, p.id])] : c))} /> ))}
setCart([])} />
); } ``` --- ## Run locally Add a simple dev script to your `package.json`, then start the app. ```json title="package.json" copy { "scripts": { "dev": "vite" } } ``` Run: ```bash npm run dev ``` ```json title="package.json" copy { "scripts": { "start": "react-scripts start" } } ``` Run: ```bash npm start ``` --- ## What you learned - Translating JSX with [``](/docs/react/api/components/t) and handling dynamic content via [``](/docs/react/api/components/var), [``](/docs/react/api/components/num), [``](/docs/react/api/components/currency), [``](/docs/react/api/components/datetime) - Expressing conditional content with [``](/docs/react/api/components/branch) and quantities with [``](/docs/react/api/components/plural) - Translating attributes with [`useGT`](/docs/react/api/strings/use-gt) - Sharing navigation/config strings using [`msg`](/docs/react/api/strings/msg) and decoding them with [`useMessages`](/docs/react/api/strings/use-messages) - Switching languages with [``](/docs/react/api/components/locale-selector) ## Next steps - Explore: [Variables Guide](/docs/react/guides/variables), [Branching Guide](/docs/react/guides/branches), [Strings Guide](/docs/react/guides/strings), [Changing Languages](/docs/react/guides/languages)