diff --git a/.locadex/LOCADEX.md b/.locadex/LOCADEX.md new file mode 100644 index 00000000000000..0139063b35e2e7 --- /dev/null +++ b/.locadex/LOCADEX.md @@ -0,0 +1,21 @@ +# 🌐 Locadex i18n + +This repository is configured to use Locadex for automated internationalization. + +## Configuration: + +- **Working Directory**: `.` +- **Branch Prefix**: `locadex/` +- **Configured Locales**: `en`, `es` +- **Local Translations**: Enabled + +## How it works: + +- Once this setup PR is merged, Locadex will automatically monitor your repository for changes +- Locadex will analyze your code for translatable content and internationalize your changes based on your configured settings +- You can configure when Locadex should run (PRs or commits) and whether it should create PRs or commit directly through the General Translation Dashboard + +--- + +Generated by [Locadex](https://generaltranslation.com) • [Documentation](https://generaltranslation.com/docs) +Timestamp: 11/4/2025 diff --git a/app/global-error.jsx b/app/global-error.jsx index 1e0bec88c38c3c..2bda4d07cba556 100644 --- a/app/global-error.jsx +++ b/app/global-error.jsx @@ -2,20 +2,22 @@ import 'prism-sentry/index.css'; -import {useEffect} from 'react'; +import { useEffect } from 'react'; import * as Sentry from '@sentry/nextjs'; import Error from 'next/error'; +import { GTProvider } from "gt-next"; -export default function GlobalError({error}) { + +export default function GlobalError({ error }) { useEffect(() => { Sentry.captureException(error); }, [error]); return ( - - + + - + ); -} +} \ No newline at end of file diff --git a/app/layout.tsx b/app/layout.tsx index 4a68dfda6a77fc..fd134e5e93901c 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,47 +1,52 @@ import './globals.css'; -import {Theme} from '@radix-ui/themes'; -import type {Metadata} from 'next'; -import {Rubik} from 'next/font/google'; +import { Theme } from '@radix-ui/themes'; +import type { Metadata } from 'next'; +import { Rubik } from 'next/font/google'; import Script from 'next/script'; import PlausibleProvider from 'next-plausible'; -import {ThemeProvider} from 'sentry-docs/components/theme-provider'; +import { ThemeProvider } from 'sentry-docs/components/theme-provider'; +import { getLocale, getGT } from "gt-next/server"; +import { GTProvider } from "gt-next"; const rubik = Rubik({ weight: ['400', '500', '700'], style: ['normal', 'italic'], subsets: ['latin'], - variable: '--font-rubik', + variable: '--font-rubik' }); -export const metadata: Metadata = { - title: 'Home', - icons: { - icon: - process.env.NODE_ENV === 'production' ? '/favicon.ico' : '/favicon_localhost.png', - }, - openGraph: { - images: '/og.png', - }, - other: { - 'zd-site-verification': 'ocu6mswx6pke3c6qvozr2e', - }, -}; +export async function generateMetadata(): Promise { + const gt = await getGT(); + return { + title: gt('Home'), + icons: { + icon: + process.env.NODE_ENV === 'production' ? '/favicon.ico' : '/favicon_localhost.png' + }, + openGraph: { + images: '/og.png' + }, + other: { + 'zd-site-verification': 'ocu6mswx6pke3c6qvozr2e' + } + }; +} -export default function RootLayout({children}: {children: React.ReactNode}) { +export default async function RootLayout({ children }: {children: React.ReactNode;}) { return ( - + - + + disableTransitionOnChange> + {children} @@ -58,9 +63,9 @@ export default function RootLayout({children}: {children: React.ReactNode}) { data-font-family="var(--font-rubik)" data-modal-disclaimer="Please note: This is a tool that searches publicly available sources. Do not include any sensitive or personal information in your queries. For more on how Sentry handles your data, see our [Privacy Policy](https://sentry.io/privacy/)." data-modal-example-questions="How to set up Sentry for Next.js?,What are tracePropagationTargets?" - data-user-analytics-cookie-enabled="false" - /> - + data-user-analytics-cookie-enabled="false" /> + + ); -} +} \ No newline at end of file diff --git a/app/not-found.tsx b/app/not-found.tsx index a08daad34eb14a..51604db824b54c 100644 --- a/app/not-found.tsx +++ b/app/not-found.tsx @@ -2,6 +2,7 @@ import {useEffect, useState} from 'react'; import {Button} from '@radix-ui/themes'; +import {T} from 'gt-next'; import {Header} from 'sentry-docs/components/header'; import {Search} from 'sentry-docs/components/search'; @@ -19,11 +20,17 @@ export default function NotFound() {
-

Page Not Found

-

We couldn't find the page you were looking for :(

+ +

Page Not Found

+
+ +

We couldn't find the page you were looking for :(

+
-

Let's give it another shot:

+ +

Let's give it another shot:

+
diff --git a/app/platform-redirect/page.tsx b/app/platform-redirect/page.tsx index 3cfd54088e637d..6f4570697db8e6 100644 --- a/app/platform-redirect/page.tsx +++ b/app/platform-redirect/page.tsx @@ -1,5 +1,6 @@ import {Metadata} from 'next'; import {redirect} from 'next/navigation'; +import {getGT} from 'gt-next/server'; import {Alert} from 'sentry-docs/components/alert'; import {DocPage} from 'sentry-docs/components/docPage'; @@ -10,17 +11,22 @@ import {setServerContext} from 'sentry-docs/serverContext'; import {sanitizeNext} from './utils'; -export const metadata: Metadata = { - robots: 'noindex', - title: 'Platform Specific Content', - description: - 'The page you are looking for is customized for each platform. Select your platform below and we’ll direct you to the most specific documentation on it.', -}; +export async function generateMetadata(): Promise { + const gt = await getGT(); + return { + robots: 'noindex', + title: gt('Platform Specific Content'), + description: gt( + "The page you are looking for is customized for each platform. Select your platform below and we'll direct you to the most specific documentation on it." + ), + }; +} export default async function Page(props: { searchParams: Promise<{[key: string]: string | string[] | undefined}>; }) { const searchParams = await props.searchParams; + const gt = await getGT(); let next = searchParams.next || ''; const platform = searchParams.platform; @@ -31,10 +37,11 @@ export default async function Page(props: { const pathname = sanitizeNext(next); const rootNode = await getDocsRootNode(); - const defaultTitle = 'Platform Specific Content'; + const defaultTitle = gt('Platform Specific Content'); let description = ''; - const platformInfo = - "The page you are looking for is customized for each platform. Select your platform below and we'll direct you to the most specific documentation on it."; + const platformInfo = gt( + "The page you are looking for is customized for each platform. Select your platform below and we'll direct you to the most specific documentation on it." + ); let title = defaultTitle; // get rid of irrelevant platforms for the `next` path diff --git a/gt-lock.json b/gt-lock.json new file mode 100644 index 00000000000000..fea3316ece38c1 --- /dev/null +++ b/gt-lock.json @@ -0,0 +1,11 @@ +{ + "version": 1, + "entries": { + "879f3a5f954ee8b75bf1e91f4ea9916b41c933e5beba7eb6362647a637c9c66d:es": { + "versionId": "8e6985b6cddc4ac55aeb4d0d6356dd80bc3b30561fee28fef32f73c9b6328220", + "fileId": "879f3a5f954ee8b75bf1e91f4ea9916b41c933e5beba7eb6362647a637c9c66d", + "fileName": "__INTERNAL_GT_TEMPLATE_NAME__", + "updatedAt": "2025-11-04T01:42:39.725Z" + } + } +} \ No newline at end of file diff --git a/gt.config.json b/gt.config.json new file mode 100644 index 00000000000000..80b835e53dccce --- /dev/null +++ b/gt.config.json @@ -0,0 +1,15 @@ +{ + "$schema": "https://assets.gtx.dev/config-schema.json", + "locales": [ + "en", + "es" + ], + "defaultLocale": "en", + "files": { + "gt": { + "output": "public/_gt/[locale].json" + } + }, + "framework": "next-app", + "_versionId": "8e6985b6cddc4ac55aeb4d0d6356dd80bc3b30561fee28fef32f73c9b6328220" +} \ No newline at end of file diff --git a/next.config.ts b/next.config.ts index c5a9d9ad67acc9..03e6422df521cd 100644 --- a/next.config.ts +++ b/next.config.ts @@ -1,51 +1,52 @@ -import {codecovNextJSWebpackPlugin} from '@codecov/nextjs-webpack-plugin'; -import {withSentryConfig} from '@sentry/nextjs'; - -import {REMOTE_IMAGE_PATTERNS} from './src/config/images'; -import {redirects} from './redirects.js'; - -const outputFileTracingExcludes = process.env.NEXT_PUBLIC_DEVELOPER_DOCS - ? { - '/**/*': [ - '**/*.map', - './.git/**/*', - './apps/**/*', - './.next/cache/mdx-bundler/**/*', - './.next/cache/md-exports/**/*', - 'docs/**/*', - ], - } - : { - '/**/*': [ - '**/*.map', - './.git/**/*', - './.next/cache/mdx-bundler/**/*', - './.next/cache/md-exports/**/*', - './apps/**/*', - 'develop-docs/**/*', - 'node_modules/@esbuild/*', - ], - '/platform-redirect': [ - '**/*.gif', - 'public/mdx-images/**/*', - 'public/og-images/**/*', - '**/*.pdf', - ], - '\\[\\[\\.\\.\\.path\\]\\]': [ - 'docs/**/*', - 'node_modules/prettier/plugins', - 'node_modules/rollup/dist', - 'public/og-images/**/*', - ], - 'sitemap.xml': [ - 'docs/**/*', - 'public/mdx-images/**/*', - 'public/og-images/**/*', - '**/*.gif', - '**/*.pdf', - '**/*.png', - ], - }; +import { withGTConfig } from "gt-next/config"; +import { codecovNextJSWebpackPlugin } from '@codecov/nextjs-webpack-plugin'; +import { withSentryConfig } from '@sentry/nextjs'; + +import { REMOTE_IMAGE_PATTERNS } from './src/config/images'; +import { redirects } from './redirects.js'; + +const outputFileTracingExcludes = process.env.NEXT_PUBLIC_DEVELOPER_DOCS ? +{ + '/**/*': [ + '**/*.map', + './.git/**/*', + './apps/**/*', + './.next/cache/mdx-bundler/**/*', + './.next/cache/md-exports/**/*', + 'docs/**/*'] + +} : +{ + '/**/*': [ + '**/*.map', + './.git/**/*', + './.next/cache/mdx-bundler/**/*', + './.next/cache/md-exports/**/*', + './apps/**/*', + 'develop-docs/**/*', + 'node_modules/@esbuild/*'], + + '/platform-redirect': [ + '**/*.gif', + 'public/mdx-images/**/*', + 'public/og-images/**/*', + '**/*.pdf'], + + '\\[\\[\\.\\.\\.path\\]\\]': [ + 'docs/**/*', + 'node_modules/prettier/plugins', + 'node_modules/rollup/dist', + 'public/og-images/**/*'], + + 'sitemap.xml': [ + 'docs/**/*', + 'public/mdx-images/**/*', + 'public/og-images/**/*', + '**/*.gif', + '**/*.pdf', + '**/*.png'] + +}; if (process.env.NODE_ENV !== 'development' && !process.env.NEXT_PUBLIC_SENTRY_DSN) { throw new Error( @@ -61,7 +62,7 @@ const nextConfig = { outputFileTracingExcludes, images: { contentDispositionType: 'inline', // "open image in new tab" instead of downloading - remotePatterns: REMOTE_IMAGE_PATTERNS, + remotePatterns: REMOTE_IMAGE_PATTERNS }, webpack: (config, options) => { config.plugins.push( @@ -69,7 +70,7 @@ const nextConfig = { enableBundleAnalysis: typeof process.env.CODECOV_TOKEN === 'string', bundleName: 'sentry-docs', uploadToken: process.env.CODECOV_TOKEN, - webpack: options.webpack, + webpack: options.webpack }) ); @@ -77,18 +78,18 @@ const nextConfig = { }, env: { // This is used on middleware - DEVELOPER_DOCS_: process.env.NEXT_PUBLIC_DEVELOPER_DOCS, + DEVELOPER_DOCS_: process.env.NEXT_PUBLIC_DEVELOPER_DOCS }, redirects, rewrites: () => [ - { - source: '/:path*.md', - destination: '/md-exports/:path*.md', - }, - ], + { + source: '/:path*.md', + destination: '/md-exports/:path*.md' + }], + sassOptions: { - silenceDeprecations: ['legacy-js-api'], - }, + silenceDeprecations: ['legacy-js-api'] + } }; module.exports = withSentryConfig(nextConfig, { @@ -111,14 +112,14 @@ module.exports = withSentryConfig(nextConfig, { automaticVercelMonitors: true, reactComponentAnnotation: { - enabled: true, + enabled: true }, unstable_sentryWebpackPluginOptions: { - applicationKey: 'sentry-docs', + applicationKey: 'sentry-docs' }, _experimental: { - thirdPartyOriginStackFrames: true, - }, -}); + thirdPartyOriginStackFrames: true + } +}); \ No newline at end of file diff --git a/package.json b/package.json index be2d3acfd3faf7..c9666f183f068b 100644 --- a/package.json +++ b/package.json @@ -64,6 +64,7 @@ "framer-motion": "^10.12.16", "github-slugger": "^2.0.0", "gray-matter": "^4.0.3", + "gt-next": "^6.7.17", "hast-util-select": "^6.0.4", "hast-util-to-jsx-runtime": "^2.3.2", "hastscript": "^8.0.0", diff --git a/public/_gt/es.json b/public/_gt/es.json new file mode 100644 index 00000000000000..315868b4a4264d --- /dev/null +++ b/public/_gt/es.json @@ -0,0 +1,844 @@ +{ + "0088957c716d4b97": { + "c": [ + "Desde ", + { + "i": 2, + "k": "_gt_value_2", + "v": "v" + } + ], + "i": 1, + "t": "h4" + }, + "024ec13c87b2e761": { + "c": [ + "© ", + { + "i": 2, + "k": "_gt_value_2", + "v": "v" + }, + " • Sentry es una marca registrada de Functional Software, Inc." + ], + "i": 1, + "t": "p" + }, + "025268660cde7a9c": { + "c": "Sentry proporciona rastreo distribuido de extremo a extremo, permitiendo a los desarrolladores identificar y depurar problemas de rendimiento y errores en sus sistemas y servicios.", + "i": 1, + "t": "p" + }, + "0336c1c64de40517": "¿Qué te gustó de esta página?", + "033cfb954954d331": "C#", + "034e71bc2b45f822": "Gracias por tu comentario", + "0436342abf417bcc": "Mapas de origen para aplicaciones web que ayudan a traducir código minificado de vuelta al código fuente original para un mejor reporte de errores.", + "05ee89185da3b64a": "SDKs de Sentry más vistos", + "0611f52a410307cb": "Comienza hoy mismo.", + "066dc86ac3842f0a": "Registros", + "08fa6a24189a55c5": "Seguridad, Legal y PII", + "095fe68547cdd437": "Cómo escribimos código frontend.", + "0b5792b85faa1fe9": "Versión", + "0b7416f060d36f45": "No 👎", + "0d0fd7081d435984": "Cómo puedes ejecutar todo Sentry en tu propio servidor, sin pagar nada.", + "0d3edd957f6a8699": "Admitámoslo, todos cometemos errores.", + "0df9ff062f15ce20": { + "c": [ + "Nombre de archivo (v", + { + "i": 2, + "k": "_gt_value_2", + "v": "v" + }, + ")" + ], + "i": 1, + "t": "th" + }, + "0e3e59f7185ccebb": "Texto", + "0ecbde439bf8ca23": { + "c": { + "c": "Ayuda a mejorar este contenido", + "i": 2, + "t": "strong" + }, + "i": 1, + "t": "small" + }, + "0f442932c6435aad": { + "c": { + "i": 2, + "k": "_gt_value_2", + "v": "v" + }, + "i": 1, + "t": "h2" + }, + "11f6d55737a69f98": "¿Te fue útil?", + "12aa61b11f6fdb5a": { + "c": { + "d": { + "b": { + "one": { + "c": [ + { + "i": 4, + "k": "_gt_n_4", + "v": "n" + }, + " archivo modificado" + ], + "i": 3, + "t": "C3" + }, + "other": { + "c": [ + { + "i": 4, + "k": "_gt_n_4", + "v": "n" + }, + " archivos modificados" + ], + "i": 3, + "t": "C3" + } + }, + "t": "p" + }, + "i": 2, + "t": "Plural" + }, + "i": 1, + "t": "span" + }, + "14abd0f98ab67191": "No, esto no fue útil", + "155c351d7fff7655": "Codecov", + "15cb6030dae7a203": { + "c": "o", + "i": 1, + "t": "span" + }, + "15d6b55bc8aabdd9": { + "c": "Preguntar a la IA", + "i": 1, + "t": "span" + }, + "1609fd73c661059c": "Terraform", + "16292b417916d30d": { + "c": [ + "Esta métrica se emite únicamente cuando Relay se ejecuta como servicio interno de Sentry para la ingesta de eventos (función ", + { + "c": "processing", + "i": 2, + "t": "code" + }, + ")." + ], + "i": 1, + "t": "Alert" + }, + "1730ec2deab29c33": "Sentry discord", + "1837f8f35dd37367": "Lua", + "185746ef1496214d": { + "c": "Restablecer pasos", + "i": 1, + "t": "button" + }, + "18858f704bcae140": "Haz clic para generar el token (NO lo subas al repositorio)", + "189644bf689e4c2e": "YAML", + "18d144bcd97f0371": "Ocultar", + "18d9fb1af46e5236": "Software de monitoreo y depuración de aplicaciones considerado \"no está mal\" por 4 millones de desarrolladores.", + "18f209f99ef292fe": "SCHEMA", + "197887a3d0eb6a39": "Disponible desde", + "19c85b1e4e700c05": "Alternar completado del paso {stepNumber}", + "1a848714f55567ed": "Defold", + "1d0a9a96ace983f7": "API de Sentry", + "1dda9f8987324821": "Comentarios de usuarios", + "2028b4e9d54333bd": "Todo sobre nuestra estructura de precios y facturación.", + "20ad15df417f9672": { + "d": { + "b": { + "false": "Objeto", + "true": { + "i": 2, + "k": "_gt_value_2", + "v": "v" + } + }, + "t": "b" + }, + "i": 1, + "t": "Branch" + }, + "217a321934b935db": { + "c": "Página no encontrada", + "i": 1, + "t": "h1" + }, + "21dc428ce8249e22": "Imagen de calculadora", + "224e5b9a8f61a4bf": "{title}: {keyword}. Haz clic para seleccionar un proyecto diferente.", + "23375e8e51bab2b7": { + "c": "Habla con nosotros", + "i": 1, + "t": "h2" + }, + "233c97428f6e8a4e": "https://github.com o https://ghe.example.com", + "2416e6e5fb5efe36": "Servidor", + "252a312fa52dd15c": { + "c": "* No es un campo real, sino que representa datos no estructurados que no forman parte del esquema.", + "i": 1, + "t": "dd" + }, + "2686d27ee5759dea": { + "c": { + "c": "Repositorio en GitHub", + "i": 2, + "t": "SmartLink" + }, + "i": 1, + "t": "li" + }, + "268b029b2df31cb8": "Crear aplicación de GitHub", + "279f1fd40d65766e": "Sentry Discord", + "27bb6e00d62b6fd5": "Código de Conducta", + "28a45948473da7f8": "GitHub", + "29f04e1eb56884ab": "Contribuir", + "2a480610d4c91ee4": "Ver imagen: {alt}", + "2aa7a6d9b80d10e5": "Selecciona una organización:", + "2c948e54b8f55f5a": { + "c": "Solo disponible en el Cliente", + "i": 1, + "t": "div" + }, + "2ecf88ef9e8e4259": "Inicio", + "2f459baf7a2e23ac": { + "c": "Solo disponible en el servidor", + "i": 1, + "t": "div" + }, + "2fc7d2600e8a3e91": "Por favor, ingresa un dominio o URL de GitHub válido", + "312f67067797a503": "Buscar plataformas", + "33bd625c24e47260": { + "c": [ + "Disponible desde: ", + { + "c": { + "i": 3, + "k": "_gt_value_3", + "v": "v" + }, + "i": 2, + "t": "code" + } + ], + "i": 1, + "t": "p" + }, + "34a0b9a8ef44973b": "Buscar SDKs", + "3504966ae0b11c11": "Crystal", + "35d5f128145e1f45": "Copiar página", + "364f6c3e2ebebff7": "Variable ENV", + "36f01fff58d1e604": "Envía información de registro basada en texto desde tus aplicaciones a Sentry para verla junto con los errores relevantes y buscarla por cadena de texto o atributos individuales.", + "3791f3cf45d23ae7": "Solo disponible en", + "396e1d8b8a8a6f3f": "Sentry CLI", + "39fcbb2f5aba6179": "Contribuir a la Documentación", + "3c6984a158a5a8fb": { + "c": { + "i": 2, + "k": "_gt_value_2", + "v": "v" + }, + "d": { + "b": { + "cli": { + "c": "en la línea de comandos", + "i": 2, + "t": "Fragment" + }, + "env": { + "c": "en el Entorno del Sistema", + "i": 2, + "t": "Fragment" + }, + "python": { + "c": [ + "en ", + { + "c": "sentry.conf.py", + "i": 3, + "t": "code" + } + ], + "i": 2, + "t": "Fragment" + }, + "yaml": { + "c": [ + "en ", + { + "c": "config.yaml", + "i": 3, + "t": "code" + } + ], + "i": 2, + "t": "Fragment" + } + }, + "t": "b" + }, + "i": 1, + "t": "Branch" + }, + "3eb8b05f1f4c24df": { + "c": "Eliminado:", + "i": 1, + "t": "span" + }, + "3f138253b1317c72": "Requisito de versión", + "3f79d950c6ead943": "Si lo usas, probablemente lo soportamos.", + "3fb6e7df1104fc1a": "Alojar Sentry por tu cuenta", + "404b8f14eb331d89": "Imagen de papel sellado", + "446fc0e1621b7ae8": "Soporte", + "44c25af421cfbe6f": "Seguridad, Legal y PII", + "44ca2fb46a718d51": "Parámetros de consulta:", + "4628077c7067faa3": "Dominio de GitHub", + "4723d72da1c6e2b1": "Ejecutándose junto al monolito.", + "48de21dffb27aea4": "Registro de cambios", + "48f16abab09f20c1": { + "c": "Slug de la organización de GitHub", + "i": 1, + "t": "label" + }, + "4aa40f5bde5417cf": [ + "Puedes ", + { + "c": "crear manualmente un Auth Token", + "i": 1, + "t": "ExternalLink" + }, + " o crear un token directamente desde esta página. Un token creado solo será visible una vez justo después de su creación - ¡asegúrate de copiarlo y pegarlo inmediatamente y NO lo subas al repositorio! Recomendamos agregarlo como una variable de entorno." + ], + "4b253a5ff9aeed07": "Soporte", + "4bca03b431c858e6": { + "c": [ + { + "c": "No hay entradas de registro de cambios disponibles", + "i": 2, + "t": "p" + }, + { + "c": "Vuelve más tarde para ver actualizaciones.", + "i": 3, + "t": "p" + } + ], + "i": 1, + "t": "div" + }, + "4bea8807020ec301": "Rastreo y detección automática de problemas de rendimiento entre servicios y contexto sobre quién se ve afectado, valores atípicos, regresiones y la causa raíz de tu ralentización.", + "4e183cf10c85fe05": "Documentación para desarrolladores", + "5091397cade97f49": "Dominio inválido", + "5199d5f781e1271d": { + "c": [ + "Sentry ", + { + "c": "url-prefix", + "i": 2, + "t": "code" + } + ], + "i": 1, + "t": "label" + }, + "51f31f38a79f6643": "Ayuda: {name}", + "51fb5099f0705556": "Ícono de {platform}", + "52179353d71e4050": "opciones", + "5262c94c2a67c873": "Imagen de terminal", + "52adbc863aeb5e59": "Error al copiar", + "52ccbf3588ba3024": "JSX", + "5378f3b06a2ba540": "ColdFusion", + "5486691d285bf8f5": "Recibiendo y procesando datos.", + "54a9454d64caeaa4": "Plataforma", + "5555d56db0e2284c": "Alojar Sentry por tu cuenta", + "5581a1e217b26251": { + "c": [ + "Última versión: ", + { + "i": 2, + "k": "_gt_value_2", + "v": "v" + } + ], + "i": 1, + "t": "li" + }, + "56e12032cea891a7": "Pregunta a un bot", + "5709ea3fe53f99c7": "Imagen de burbuja de chat", + "5845560da4531ff8": "Frontend", + "5973d49b78a13b8f": { + "c": "Sandbox", + "i": 1, + "t": "Link" + }, + "59867c5a0a72d1c0": "Clojure (Raven Clj)", + "59cf1fd2cff83af2": "Ver como Markdown", + "5b158b1ab5e338b0": "Parámetros del Body", + "5bdb63979f4de855": "Imagen de concepto y referencias", + "5ebb24b86fa9aac9": "Infraestructura de Desarrollo", + "5fa4b7652d7aeca8": "PowerShell", + "5facaff8479f6a6b": "Conceptos y Referencia", + "60b847b2889fbb4c": "Session Replay", + "611100f34fc43cea": { + "c": "Probemos de nuevo:", + "i": 1, + "t": "p" + }, + "61d6b0baccab242d": "CoffeeScript", + "6201808e78a40607": "Instalación Recomendada:", + "63ec1478086d5484": "Comenzar", + "64abb2144bde1cb3": "Elige tu SDK", + "64c99c6d5805188c": "CTA", + "64dd2ca3ab84c74e": "TSX", + "660e0823e59a2fc8": "Cliente", + "6707421a475dd2d3": { + "c": [ + "Buscar ", + { + "c": { + "i": 3, + "k": "_gt_value_3", + "v": "v" + }, + "i": 2, + "t": "em" + }, + " en todos los sitios de Sentry" + ], + "i": 1, + "t": "button" + }, + "67799c2f5695a1b1": "Discord", + "678d102f69ad9c72": "Grails", + "689ec7c5ae67d59c": "Cloudflare Workers", + "68f3995ee3fa541a": "Procesos de seguridad, cumplimiento y limpieza de datos.", + "693a0a63379e405a": "Precios y Facturación", + "69611e7f5f23f232": [ + "Puedes ", + { + "c": "crear manualmente un Token de Autenticación", + "i": 1, + "t": "ExternalLink" + }, + " o ", + { + "c": "iniciar sesión", + "i": 2, + "t": "ExternalLink" + }, + " para crear un token directamente desde esta página." + ], + "69a6386f7ab88f43": "C++", + "69cc33daebf01c2b": "Cómo poner en marcha tu entorno de desarrollo local.", + "6a7121cf0dbff282": "Hono", + "6a8345e46940f9d1": { + "c": "Detalles del Paquete", + "i": 1, + "t": "h3" + }, + "6be9ba38e1bd6ada": { + "c": "Guías relacionadas", + "i": 1, + "t": "h2" + }, + "6cc608f2f7ed7ca2": "Scrapy", + "6cdc3f32f802d98b": "API", + "6d808fdc22d36d44": "Reproducciones tipo video de sesiones de usuario con contexto de depuración para ayudarte a confirmar el impacto de problemas y solucionarlos más rápido.", + "6dada1e234d5a59f": "Strapi", + "72717733fa3e8861": "Sentry para {title}", + "72917fcd7df46abb": "RESPUESTA", + "73c583cd95c5acf5": "Buscar Documentación", + "74e10e966c378336": "Sandbox", + "75353ce09ec3bfb8": "Menú", + "776f3f4829a64beb": { + "c": "Suma de verificación de integridad", + "i": 1, + "t": "th" + }, + "77cd4adcd4eefe05": "Conectando Sentry a otros productos.", + "77d76a0d22e7f8b7": "Mira cómo podemos ayudarte.", + "78fbd7e6251396a0": "Rastreo", + "79f14a9ad35e8a5d": "Seleccionar región", + "7cffcafcfaae5c33": "Configuración de la organización", + "7e2be5c37e1c72c8": "Prácticas de Ingeniería", + "7e66fe0945220fda": "Comenzar", + "7f8cb8174c6d288f": "Siguiente", + "7fbe41e29206a133": "PHP", + "8042eb18f47511c1": "Copiar página como Markdown para LLMs", + "82f34ce5561d359f": { + "c": [ + "Nuestra documentación es de código abierto y está disponible en GitHub. Tus contribuciones son bienvenidas, ya sea corrigiendo un error tipográfico (¡vaya!) o sugiriendo una actualización (\"sí, esto estaría mejor\").", + { + "c": [ + { + "c": "Cómo contribuir", + "i": 3, + "t": "Link" + }, + " | ", + { + "c": "Editar esta página", + "i": 4, + "t": "Link" + }, + " | ", + { + "c": "Crear un issue de documentación", + "i": 5, + "t": "Link" + }, + " | ", + { + "c": "Obtener soporte", + "i": 6, + "t": "Link" + }, + " " + ], + "i": 2, + "t": "div" + } + ], + "i": 1, + "t": "small" + }, + "831553c2236d6590": { + "c": "Bienvenido a Sentry Docs", + "i": 1, + "t": "h1" + }, + "84b20687683b4a1a": "Mapas de Origen", + "84dfa1e62772f6e8": [ + "Estás en la versión ", + { + "i": 1, + "k": "_gt_value_1", + "v": "v" + }, + " de nuestra documentación del SDK. ¿Quieres ir a la última versión?" + ], + "84f1f772a8f984d7": "Seguridad, Legal y PII", + "86d287aa1993a091": "Cerrar", + "882c45a3c387d0ca": { + "c": "No pudimos encontrar la página que buscabas :(", + "i": 1, + "t": "p" + }, + "8854a34ab59e4832": "Símbolos de depuración para iOS y macOS que proporcionan la información necesaria para convertir direcciones de programa de vuelta a nombres de funciones, nombres de archivos fuente y números de línea.", + "887be83f180b104e": "CLI", + "89c7a83e47e8cfcd": "Último", + "8a3ebfe5eefa1f3a": "Servicios", + "8dcf09dc21a78b5c": "Perfilado", + "8ee1c3cf1d0b5692": "HTML", + "8f77abfed13290fc": "Tutoriales del Producto", + "912a38652c0609f5": "APIs para acceder a Sentry de forma programática.", + "91add63ffc66a2c0": "Todos los SDK compatibles con Sentry", + "91ea5d2b6b8362a7": { + "c": [ + "Pregúntale a Sentry sobre ", + { + "c": { + "i": 3, + "k": "_gt_value_3", + "v": "v" + }, + "i": 2, + "t": "span" + } + ], + "i": 1, + "t": "div" + }, + "9265a59ffa433d01": "Clojure (Sentry Clj)", + "94226dd45d7c2052": { + "c": { + "d": { + "b": { + "Next": "Siguiente", + "Previous": "Anterior" + }, + "t": "b" + }, + "i": 2, + "t": "Branch" + }, + "i": 1, + "t": "div" + }, + "9588289bb956e0d6": "Documentación", + "9630cab36a225e8d": [ + "El siguiente ejemplo de código te permitirá elegir tu configuración personal desde el menú desplegable, una vez que hayas ", + { + "c": "iniciado sesión", + "i": 1, + "t": "Link" + }, + "." + ], + "968072d9af1cc1ba": { + "c": "En esta página", + "i": 1, + "t": "h2" + }, + "96aae8c23c00903e": "Quarkus", + "976e4cbfa6fa14f0": "¿Cómo podemos mejorar esta página?", + "9b463ccb58c7cabd": "Sube tu código fuente para permitir que Sentry muestre fragmentos de tu código junto a los stack traces de eventos.", + "9e8950799011db6e": "GitHub Enterprise", + "9f8189f9fccc84b6": { + "c": "Conócenos", + "i": 1, + "t": "h2" + }, + "a0b1cda8a1216c4c": { + "c": [ + { + "i": 2, + "k": "_gt_value_2", + "v": "v" + }, + " requiere ", + { + "i": 3, + "k": "_gt_value_3", + "v": "v" + }, + " versión ", + { + "c": { + "i": 5, + "k": "_gt_value_5", + "v": "v" + }, + "i": 4, + "t": "code" + }, + " o superior." + ], + "i": 1, + "t": "p" + }, + "a285f1292e8a8574": "palabra clave", + "a6694b6f283723ad": "Conversaciones reales en tiempo real. Únete.", + "a9006bf88e74e9fb": "F#", + "a9b947a784c530e4": "Generando token...", + "a9f2d5fa970770c5": "Contexto de origen", + "a9f7bd5bbaa15f1c": "Imagen de la organización", + "ab47f58386924b4f": "Anterior", + "aca1668281d69d89": "Enviar comentarios", + "ad9c6c6fb79fc7c8": "Configuración de la Organización", + "ae1a122cf663e507": "Recopila comentarios de usuarios desde cualquier lugar de tu aplicación con un widget integrable que permite a los usuarios reportar errores y proporcionar información valiosa.", + "aead6b91dca54308": "¿Qué es Sentry?", + "b373e88e47bd85d8": "JSON", + "b38e18cf71ed346c": { + "c": [ + "Versión del SDK: ", + { + "i": 2, + "k": "_gt_value_2", + "v": "v" + } + ], + "i": 1, + "t": "span" + }, + "b4170381a593d32c": "Arquitectura de la Aplicación", + "b6f33581a13c76c8": "Monitoreo de Errores", + "b7b20228d7d1ccd0": "Session Replay ya está disponible de forma general para móviles.", + "ba853fa1aefa946b": { + "c": "Añadido:", + "i": 1, + "t": "span" + }, + "bb9a903222c1bdcf": "Imagen de cohete", + "bbe080787718432b": "Serverless Framework", + "bc372d1b7722155b": { + "c": "Modificado:", + "i": 1, + "t": "span" + }, + "bc9fca228f29f03f": "El monolito que impulsa Sentry.", + "bdda514910af8c60": "Por favor comparte tu opinión...", + "be386aa4d6a39a70": "OCaml", + "be3e0bf48b6818dd": "Sentry para {platform}", + "bfc9018b5a8f6603": { + "c": "Comenzar", + "i": 1, + "t": "Link" + }, + "c0225c7325ab7fb9": "Buscar Proyecto", + "c0e0ab7b0a89f28d": { + "c": { + "c": [ + "Mostrando las 20 actualizaciones más recientes. Ver el ", + { + "c": "panel de contenido completo", + "i": 3, + "t": "a" + }, + " o suscribirse al ", + { + "c": "feed RSS", + "i": 4, + "t": "a" + }, + "." + ], + "i": 2, + "t": "p" + }, + "i": 1, + "t": "div" + }, + "c25a0a8e3b12a8e2": "Imagen principal de Sentry", + "c2cb6ad98eb15937": "Ir a Sentry", + "c336504f4fe3bd20": "Edita este banner en `/src/components/banner/index.tsx`", + "c37237fc8d425018": "Integraciones", + "c3eeeebc1a198efd": { + "c": "Registro de cambios", + "i": 1, + "t": "Link" + }, + "c5e3992a699ffd7e": { + "c": "Obtén una respuesta impulsada por IA a tu pregunta", + "i": 1, + "t": "div" + }, + "c6099bfabce54674": "Instrumentando código de usuario.", + "c94a6f30ed5b65b8": "Información para configurar la cuenta de Sentry de tu organización.", + "c9b9395a4fa6592a": "Combina Sentry con OpenTelemetry.", + "ca4759898e28459e": "Copiar reglas", + "cab0179a0b032476": "Imagen de enchufe", + "cc8cdd1ece34cd75": "Nota", + "cd8ba56a4fd5b03e": "WordPress", + "ce62397c56fc2d1f": "Requiere que Tracing esté habilitado. Consulta las líneas exactas de código que causan tus cuellos de botella de rendimiento, para una resolución de problemas más rápida y optimización de recursos.", + "cf9e006355e10c19": "Usa la integración estándar de GitHub para github.com", + "d15602f01bb838ee": "No se encontraron SDKs", + "d2d6660d0ff9bd1b": "Nuxt 2", + "d2d9c091ed5f87c0": "Contenido Específico de la Plataforma", + "d3264cfb310b4030": "Escribe", + "d3b106fc0ee472d6": "Haz clic para seleccionar el proyecto", + "d48588f854314c97": "ARN", + "d5abcafdfe033b14": "Sentry Auto-Hospedado", + "d71213149c77df8e": { + "c": "Archivo", + "i": 1, + "t": "th" + }, + "d7c1de156b4170eb": "Kubernetes", + "d857b1d836100e66": "JavaScript (ES6)", + "d91f800c5035b986": "La página que buscas está personalizada para cada plataforma. Selecciona tu plataforma a continuación y te dirigiremos a la documentación más específica sobre ella.", + "d9b5a363281956ec": "OpenTelemetry", + "db89ff88b3f5f808": { + "c": { + "c": "Documentación de la API", + "i": 2, + "t": "SmartLink" + }, + "i": 1, + "t": "li" + }, + "dcdf0779d4f12004": { + "c": "Ir a Sentry", + "i": 1, + "t": "Link" + }, + "dd281e638ef8392f": "Backend", + "dd543f8308228919": "Versiones", + "def85a6fb901d27c": "Ver esta página como texto plano", + "df4cc6fe102d0c5a": "SDKs", + "df6215b61bbae9bc": "Sí 👍", + "e0c8478e1438c7b4": "Parámetros", + "e40e6d4ec89b5365": "Predeterminado", + "e4bdba2b98135c08": "Informar 404 en GitHub", + "e4f2775459c7de91": "Imagen de soporte", + "e7588632064e0364": "Copiado", + "e858582773036a8c": "Parámetros de Ruta", + "e91a06b8df9ae9e2": { + "c": [ + " ", + "(", + { + "i": 2, + "k": "_gt_value_2", + "v": "v" + }, + ")" + ], + "i": 1, + "t": "small" + }, + "e9f89716dfcef12a": "Sí, esto fue útil", + "eaf8192a2c25e4ca": "Ingestion", + "eb06d0b09e455249": "Registro de cambios de la documentación", + "ec2571e23194be1a": "Usa la integración de GitHub Enterprise para tu dominio", + "ed5e16b03e8717b7": "Plataformas", + "edfbe0ccbf302b55": "Logotipo de Sentry", + "ee3e8bd8b7918aec": "Buscar", + "ee70eda414dc4586": { + "c": [ + { + "c": [ + "Necesitas ", + { + "c": "autenticarte mediante token de autenticación bearer.", + "i": 3, + "t": "SmartLink" + } + ], + "i": 2, + "t": "div" + }, + { + "c": "", + "i": 4, + "t": "code" + }, + " requiere uno de los siguientes scopes:" + ], + "i": 1, + "t": "div" + }, + "eee4556d08378cc3": "dSYM", + "efd9775f35548e44": "¡Copiado!", + "efe894c61467a45d": "TypeScript", + "f0308ae2275507c6": "Cómo usar 'sentry-cli' en la línea de comandos.", + "f23922b9d6962b39": "Documentación para Desarrolladores", + "f3a67e68c2900a1d": "Error de red - por favor intenta de nuevo", + "f5d0903337574ed0": "Configuración de la cuenta", + "f7937c8d7882939d": "Conceptos fundamentales que hacen de Sentry, Sentry.", + "f7c05d3a4ef136b8": "JavaScript", + "f7d4c080503e9a83": "Hubo un error al generar tu token.", + "f8c144a0a3070ac7": "Monitoreo de errores de Sentry", + "fbdc38974ff2df72": "Ámbitos", + "fbe11a2e1903cdf9": { + "c": [ + "Declarado ", + { + "i": 2, + "k": "_gt_value_2", + "v": "v" + } + ], + "i": 1, + "t": "small" + }, + "fda5c9f6d1d9da06": "Cambiar tema", + "fe3e030bc6f25d4c": { + "c": "Ver archivos modificados", + "i": 1, + "t": "summary" + }, + "fed968c6ffe41d8c": "OBLIGATORIO", + "ffe068f28fece7f7": "Documentación de Usuario" +} \ No newline at end of file diff --git a/src/components/apiExamples/apiExamples.tsx b/src/components/apiExamples/apiExamples.tsx index ad7226e3e7e864..c0cc55cf4e9a31 100644 --- a/src/components/apiExamples/apiExamples.tsx +++ b/src/components/apiExamples/apiExamples.tsx @@ -11,6 +11,7 @@ import styles from './apiExamples.module.scss'; import {CodeBlock} from '../codeBlock'; import {CodeTabs} from '../codeTabs'; import {codeToJsx} from '../highlightCode'; +import {T, useGT} from 'gt-next'; const strFormat = (str: string) => { const s = str.trim(); @@ -25,6 +26,7 @@ type Props = { }; export function ApiExamples({api}: Props) { + const gt = useGT(); const apiExample = [ `curl ${api.server}${api.apiPath}`, ` -H 'Authorization: Bearer '`, @@ -51,8 +53,8 @@ export function ApiExamples({api}: Props) { const [selectedTabView, selectTabView] = useState(0); const tabViews = api.responses[selectedResponse].content?.schema - ? ['RESPONSE', 'SCHEMA'] - : ['RESPONSE']; + ? [gt('RESPONSE'), gt('SCHEMA')] + : [gt('RESPONSE')]; const [showCopied, setShowCopied] = useState(false); @@ -134,7 +136,7 @@ export function ApiExamples({api}: Props) { className={codeBlockStyles.copied} style={{opacity: showCopied ? 1 : 0}} > - Copied + Copied
{selectedTabView === 0 && (exampleJson ? ( diff --git a/src/components/apiPage/index.tsx b/src/components/apiPage/index.tsx index 1fe9ae31d6f231..c0bce62704c340 100644 --- a/src/components/apiPage/index.tsx +++ b/src/components/apiPage/index.tsx @@ -1,6 +1,7 @@ import {Fragment, ReactElement, useMemo} from 'react'; import {bundleMDX} from 'mdx-bundler'; import {getMDXComponent} from 'mdx-bundler/client'; +import {T, useGT} from 'gt-next'; import {type API} from 'sentry-docs/build/resolveOpenAPI'; import {mdxComponents} from 'sentry-docs/mdxComponents'; @@ -14,6 +15,7 @@ import {DocPage} from '../docPage'; import {SmartLink} from '../smartLink'; function Params({params}) { + const gt = useGT(); return (
{params.map(param => { @@ -30,14 +32,14 @@ function Params({params}) { )} - {!!param.required &&
REQUIRED
} + {!!param.required &&
{gt('REQUIRED')}
} {!!param.description && (
{param.schema?.enum && ( - choices: + {gt('choices')}:
    {param.schema?.enum.map(e => { @@ -49,7 +51,7 @@ function Params({params}) { )} {param.schema?.items?.enum && ( - choices: + {gt('choices')}:
      {param.schema?.items?.enum.map(e => { @@ -122,6 +124,7 @@ type Props = { }; export function ApiPage({api}: Props) { + const gt = useGT(); const frontMatter = { title: api.name, }; @@ -145,38 +148,40 @@ export function ApiPage({api}: Props) { {!!api.pathParameters.length && (
      -

      Path Parameters

      +

      {gt('Path Parameters')}

      )} {!!api.queryParameters.length && (
      -

      Query Parameters:

      +

      {gt('Query Parameters:')}

      )} {!!api.bodyParameters.length && (
      -

      Body Parameters

      +

      {gt('Body Parameters')}

      )} {api.security?.length && (
      -

      Scopes

      +

      {gt('Scopes')}

      -
      +
      - {'You need to '} - - authenticate via bearer auth token. - +
      + You need to{' '} + + authenticate via bearer auth token. + +
      + {''} requires one of the following scopes:
      - {''} requires one of the following scopes: -
      +
        {getScopes(api, 'auth_token').map(scope => ( diff --git a/src/components/banner/index.tsx b/src/components/banner/index.tsx index cd9dbbbba2229b..b97c054248da52 100644 --- a/src/components/banner/index.tsx +++ b/src/components/banner/index.tsx @@ -1,6 +1,7 @@ 'use client'; import {useEffect, useState} from 'react'; +import {msg, useMessages} from 'gt-next'; import styles from './banner.module.scss'; @@ -50,9 +51,9 @@ const BANNERS: BannerType[] = [ // check it out on `/contributing/pages/banners/` { appearsOn: ['^/contributing/pages/banners/'], - text: 'Edit this banner on `/src/components/banner/index.tsx`', + text: msg('Edit this banner on `/src/components/banner/index.tsx`'), linkURL: 'https://docs.sentry.io/contributing/pages/banners/', - linkText: 'CTA', + linkText: msg('CTA'), }, { appearsOn: [ @@ -61,9 +62,9 @@ const BANNERS: BannerType[] = [ '^/platforms/android/', '^/platforms/apple/guides/ios/', ], - text: 'Session Replay is now generally available for mobile.', + text: msg('Session Replay is now generally available for mobile.'), linkURL: 'https://docs.sentry.io/product/explore/session-replay/mobile/', - linkText: 'Get started today.', + linkText: msg('Get started today.'), }, ]; @@ -100,6 +101,7 @@ const readOrResetLocalStorage = () => { export function Banner() { type BannerWithHash = BannerType & {hash: string}; const [banner, setBanner] = useState(null); + const m = useMessages(); useEffect(() => { const matchingBanner = BANNERS.find(b => { @@ -136,9 +138,9 @@ export function Banner() {
        - {banner.text} + {m(banner.text)} - {banner.linkText} + {m(banner.linkText)}
        diff --git a/src/components/changelog/docsChangelog.tsx b/src/components/changelog/docsChangelog.tsx index 6c8f3c6a2a9b0f..281442ba8e2306 100644 --- a/src/components/changelog/docsChangelog.tsx +++ b/src/components/changelog/docsChangelog.tsx @@ -1,3 +1,5 @@ +import {T, Plural, Num, DateTime} from 'gt-next'; + interface ChangelogEntry { author: string; description: string; @@ -36,10 +38,12 @@ export async function DocsChangelog() { if (entries.length === 0) { return ( -
        -

        No changelog entries available

        -

        Check back later for updates.

        -
        + +
        +

        No changelog entries available

        +

        Check back later for updates.

        +
        +
        ); } @@ -70,17 +74,27 @@ export async function DocsChangelog() {
        {totalFiles > 0 && } {totalFiles > 0 && ( - - {totalFiles} file{totalFiles !== 1 ? 's' : ''} changed - + + + + {totalFiles} file changed + + } + other={ + <> + {totalFiles} files changed + + } + /> + + )}
        @@ -91,15 +105,19 @@ export async function DocsChangelog() { {entry.filesChanged && totalFiles > 0 && (
        - - View changed files - + + + View changed files + +
        {entry.filesChanged.added && entry.filesChanged.added.length > 0 && (
        - - Added: - + + + Added: + +
          {entry.filesChanged.added.map(file => (
        • @@ -112,9 +130,11 @@ export async function DocsChangelog() { {entry.filesChanged.modified && entry.filesChanged.modified.length > 0 && (
          - - Modified: - + + + Modified: + +
            {entry.filesChanged.modified.map(file => (
          • @@ -127,9 +147,11 @@ export async function DocsChangelog() { {entry.filesChanged.removed && entry.filesChanged.removed.length > 0 && (
            - - Removed: - + + + Removed: + +
              {entry.filesChanged.removed.map(file => (
            • @@ -146,29 +168,31 @@ export async function DocsChangelog() { ); })} {entries.length > 20 && ( -
              -

              - Showing the 20 most recent updates. View the{' '} - - full content dashboard - {' '} - or subscribe to the{' '} - - RSS feed - - . -

              -
              + +
              +

              + Showing the 20 most recent updates. View the{' '} + + full content dashboard + {' '} + or subscribe to the{' '} + + RSS feed + + . +

              +
              +
              )}
            ); diff --git a/src/components/cliChecksumTable/index.tsx b/src/components/cliChecksumTable/index.tsx index 7283ab2d46e27d..14bec236fe83eb 100644 --- a/src/components/cliChecksumTable/index.tsx +++ b/src/components/cliChecksumTable/index.tsx @@ -1,4 +1,5 @@ import getAppRegistry from 'sentry-docs/build/appRegistry'; +import {T, Var} from 'gt-next'; import styles from './styles.module.scss'; @@ -22,8 +23,8 @@ export async function CliChecksumTable() { - - + + diff --git a/src/components/codeBlock/index.tsx b/src/components/codeBlock/index.tsx index b7cc64c2927e4a..744561ee3aa382 100644 --- a/src/components/codeBlock/index.tsx +++ b/src/components/codeBlock/index.tsx @@ -2,6 +2,7 @@ import {RefObject, useEffect, useRef, useState} from 'react'; import {Clipboard} from 'react-feather'; +import {T} from 'gt-next'; import {usePlausibleEvent} from 'sentry-docs/hooks/usePlausibleEvent'; @@ -117,7 +118,7 @@ export function CodeBlock({filename, language, children}: CodeBlockProps) { className={styles.copied} style={{opacity: showCopied ? 1 : 0}} > - Copied + Copied
            {makeKeywordsClickable(makeHighlightBlocks(children, language))} diff --git a/src/components/codeKeywords/keywordSelector.tsx b/src/components/codeKeywords/keywordSelector.tsx index 820f4307c587a0..31de8a73e0a6c8 100644 --- a/src/components/codeKeywords/keywordSelector.tsx +++ b/src/components/codeKeywords/keywordSelector.tsx @@ -5,6 +5,7 @@ import {createPortal} from 'react-dom'; import {usePopper} from 'react-popper'; import {AnimatePresence} from 'framer-motion'; import {useTheme} from 'next-themes'; +import {useGT} from 'gt-next'; import {useOnClickOutside} from 'sentry-docs/clientUtils'; import {useIsMounted} from 'sentry-docs/hooks/isMounted'; @@ -46,6 +47,7 @@ export function KeywordSelector({ const [orgFilter, setOrgFilter] = useState(''); const [showProjectPreview, setShowProjectPreview] = useState(false); const {resolvedTheme: theme} = useTheme(); + const gt = useGT(); const isDarkMode = theme === 'dark'; const {isMounted} = useIsMounted(); @@ -75,7 +77,7 @@ export function KeywordSelector({ const currentSelection = choices[currentSelectionIdx]; if (!currentSelection) { - return keyword; + return {gt('keyword')}; } const selector = isOpen && ( @@ -89,7 +91,7 @@ export function KeywordSelector({ /> {choices.length > 5 && ( e.stopPropagation()} value={orgFilter} onChange={e => setOrgFilter(e.target.value)} @@ -137,8 +139,11 @@ export function KeywordSelector({ title={currentSelection?.title} aria-label={ currentSelection?.title - ? `${currentSelection?.title}: ${currentSelection[keyword]}. Click to select different project.` - : `Click to select project` + ? gt('{title}: {keyword}. Click to select different project.', { + title: currentSelection.title, + keyword: currentSelection[keyword], + }) + : gt('Click to select project') } aria-expanded={isOpen} onClick={() => setIsOpen(!isOpen)} diff --git a/src/components/codeKeywords/orgAuthTokenCreator.tsx b/src/components/codeKeywords/orgAuthTokenCreator.tsx index ff7ed1a0e764a7..23a25fea862a84 100644 --- a/src/components/codeKeywords/orgAuthTokenCreator.tsx +++ b/src/components/codeKeywords/orgAuthTokenCreator.tsx @@ -5,6 +5,7 @@ import {createPortal} from 'react-dom'; import {usePopper} from 'react-popper'; import {AnimatePresence} from 'framer-motion'; import {useTheme} from 'next-themes'; +import {useGT} from 'gt-next'; import {useOnClickOutside} from 'sentry-docs/clientUtils'; import {useIsMounted} from 'sentry-docs/hooks/isMounted'; @@ -43,6 +44,7 @@ export function OrgAuthTokenCreator() { const [isAnimating, setIsAnimating] = useState(false); const {resolvedTheme: theme} = useTheme(); const isDarkMode = theme === 'dark'; + const gt = useGT(); const {isMounted} = useIsMounted(); @@ -115,16 +117,16 @@ export function OrgAuthTokenCreator() { } if (tokenState.status === 'error') { - return There was an error while generating your token.; + return {gt('There was an error while generating your token.')}; } if (tokenState.status === 'loading') { - return Generating token...; + return {gt('Generating token...')}; } const selector = isOpen && ( - Select an organization: + {gt('Select an organization:')} { handlePress(); @@ -192,7 +194,7 @@ export function OrgAuthTokenCreator() { onAnimationStart={() => setIsAnimating(true)} onAnimationComplete={() => setIsAnimating(false)} > - Click to generate token (DO NOT commit) + {gt('Click to generate token (DO NOT commit)')} diff --git a/src/components/codeTabs.tsx b/src/components/codeTabs.tsx index 64a19962bb5359..e76bc4b9d50750 100644 --- a/src/components/codeTabs.tsx +++ b/src/components/codeTabs.tsx @@ -10,6 +10,7 @@ import { useState, } from 'react'; import styled from '@emotion/styled'; +import {msg, useMessages} from 'gt-next'; import {CodeBlockProps} from './codeBlock'; import {CodeContext} from './codeContext'; @@ -19,23 +20,25 @@ import {SignInNote} from './signInNote'; // human readable versions of names const HUMAN_LANGUAGE_NAMES = { - coffee: 'CoffeeScript', - cpp: 'C++', - csharp: 'C#', - es6: 'JavaScript (ES6)', - fsharp: 'F#', - html: 'HTML', - javascript: 'JavaScript', - json: 'JSON', - jsx: 'JSX', - tsx: 'TSX', - php: 'PHP', - powershell: 'PowerShell', - typescript: 'TypeScript', - yaml: 'YAML', - yml: 'YAML', + coffee: msg('CoffeeScript'), + cpp: msg('C++'), + csharp: msg('C#'), + es6: msg('JavaScript (ES6)'), + fsharp: msg('F#'), + html: msg('HTML'), + javascript: msg('JavaScript'), + json: msg('JSON'), + jsx: msg('JSX'), + tsx: msg('TSX'), + php: msg('PHP'), + powershell: msg('PowerShell'), + typescript: msg('TypeScript'), + yaml: msg('YAML'), + yml: msg('YAML'), }; +const TEXT_FALLBACK = msg('Text'); + interface CodeTabProps { children: React.ReactElement | React.ReactElement[]; } @@ -51,6 +54,7 @@ const showSigninNote = (children: ReactNode) => { export function CodeTabs({children}: CodeTabProps) { const codeBlocks = Array.isArray(children) ? [...children] : [children]; + const m = useMessages(); // The title is what we use for sorting and also for remembering the // selection. If there is no title fall back to the title cased language name @@ -60,10 +64,10 @@ export function CodeTabs({children}: CodeTabProps) { return title; } if (!language) { - return 'Text'; + return m(TEXT_FALLBACK); } if (language in HUMAN_LANGUAGE_NAMES) { - return HUMAN_LANGUAGE_NAMES[language]; + return m(HUMAN_LANGUAGE_NAMES[language]); } return language[0].toUpperCase() + language.substring(1); diff --git a/src/components/communitySupportedPlatforms/index.tsx b/src/components/communitySupportedPlatforms/index.tsx index c5036d931bbb4c..1fd47ddcaac488 100644 --- a/src/components/communitySupportedPlatforms/index.tsx +++ b/src/components/communitySupportedPlatforms/index.tsx @@ -1,4 +1,5 @@ import Image from 'next/image'; +import {msg, useMessages} from 'gt-next'; import {ExternalLink} from '../externalLink'; @@ -22,98 +23,99 @@ import wordpress from './icons/wordpress.png'; const CommunityPlatforms = [ { - name: 'Clojure (Sentry Clj)', + name: msg('Clojure (Sentry Clj)'), url: 'https://github.com/getsentry/sentry-clj', icon: clojure, }, { - name: 'Clojure (Raven Clj)', + name: msg('Clojure (Raven Clj)'), url: 'https://github.com/sethtrain/raven-clj#alternatives', icon: clojure, }, { - name: 'Cloudflare Workers', + name: msg('Cloudflare Workers'), url: 'https://github.com/robertcepa/toucan-js', icon: cloudflare, }, { - name: 'ColdFusion', + name: msg('ColdFusion'), url: 'https://github.com/coldbox-modules/sentry', icon: coldfusion, }, { - name: 'Crystal', + name: msg('Crystal'), url: 'https://github.com/Sija/raven.cr', icon: crystal, }, { - name: 'Defold', + name: msg('Defold'), url: 'https://github.com/indiesoftby/defold-sentinel', icon: defold, }, { - name: 'Grails', + name: msg('Grails'), url: 'https://github.com/agorapulse/grails-sentry', icon: grails, }, { - name: 'Hono', + name: msg('Hono'), url: 'https://github.com/honojs/middleware/tree/main/packages/sentry', icon: hono, }, { - name: 'Kubernetes', + name: msg('Kubernetes'), url: 'https://github.com/alekitto/sentry-kubernetes', icon: kubernetes, }, { - name: 'Lua', + name: msg('Lua'), url: 'https://github.com/cloudflare/raven-lua', icon: lua, }, { - name: 'Nuxt 2', + name: msg('Nuxt 2'), url: 'https://github.com/nuxt-community/sentry-module', icon: nuxt, }, { - name: 'OCaml', + name: msg('OCaml'), url: 'https://github.com/brendanlong/sentry-ocaml', icon: ocaml, }, { - name: 'Quarkus', + name: msg('Quarkus'), url: 'https://github.com/quarkiverse/quarkus-logging-sentry', icon: quarkus, }, { - name: 'Scrapy', + name: msg('Scrapy'), url: 'https://github.com/llonchj/scrapy-sentry', icon: scrapy, }, { - name: 'Serverless Framework', + name: msg('Serverless Framework'), url: 'https://github.com/arabold/serverless-sentry-plugin', icon: serverless, }, { - name: 'Strapi', + name: msg('Strapi'), url: 'https://github.com/strapi/strapi/tree/master/packages/plugins/sentry', icon: strapi, }, { - name: 'Terraform', + name: msg('Terraform'), url: 'https://github.com/jianyuan/terraform-provider-sentry', icon: terraform, }, { - name: 'WordPress', + name: msg('WordPress'), url: 'https://github.com/stayallive/wp-sentry', icon: wordpress, }, ]; export function CommunitySupportedPlatforms() { + const m = useMessages(); return (
              {CommunityPlatforms.map(platform => ( @@ -126,10 +128,10 @@ export function CommunitySupportedPlatforms() { src={platform.icon.src} width={20} height={20} - alt={platform.name} + alt={m(platform.name)} className="!border-none !shadow-none" /> - {platform.name} + {m(platform.name)} ))} diff --git a/src/components/configValue.tsx b/src/components/configValue.tsx index adefb169a49845..e788f412a21e28 100644 --- a/src/components/configValue.tsx +++ b/src/components/configValue.tsx @@ -1,4 +1,5 @@ import {Fragment} from 'react'; +import {T, Branch, Var} from 'gt-next'; type Props = { children: JSX.Element; @@ -7,26 +8,27 @@ type Props = { }; const getDescriptiveLocation = (location: string): JSX.Element => { - switch (location) { - case 'env': - return in System Environment; - case 'yaml': - return ( - - in config.yaml - - ); - case 'python': - return ( - - in sentry.conf.py - - ); - case 'cli': - return on the command line; - default: - throw new Error('Invalid location'); - } + return ( + + in System Environment} + yaml={ + + in config.yaml + + } + python={ + + in sentry.conf.py + + } + cli={on the command line} + > + {(() => { throw new Error('Invalid location'); })()} + + + ); }; export function ConfigValue({name, location, children}: Props): JSX.Element { @@ -36,7 +38,9 @@ export function ConfigValue({name, location, children}: Props): JSX.Element { {name}

              - Declared {getDescriptiveLocation(location)} + + Declared {getDescriptiveLocation(location)} +

              {children}
            diff --git a/src/components/copyMarkdownButton.tsx b/src/components/copyMarkdownButton.tsx index b4a40817847cdd..255d0001e3dcfa 100644 --- a/src/components/copyMarkdownButton.tsx +++ b/src/components/copyMarkdownButton.tsx @@ -4,6 +4,7 @@ import {Fragment, useCallback, useEffect, useRef, useState} from 'react'; import {createPortal} from 'react-dom'; import {Clipboard} from 'react-feather'; import Link from 'next/link'; +import {useGT} from 'gt-next'; import {usePlausibleEvent} from 'sentry-docs/hooks/usePlausibleEvent'; import Chevron from 'sentry-docs/icons/Chevron'; @@ -14,6 +15,7 @@ interface CopyMarkdownButtonProps { } export function CopyMarkdownButton({pathname}: CopyMarkdownButtonProps) { + const gt = useGT(); const [isLoading, setIsLoading] = useState(false); const [copied, setCopied] = useState(false); const [error, setError] = useState(false); @@ -136,7 +138,9 @@ export function CopyMarkdownButton({pathname}: CopyMarkdownButtonProps) { disabled={isLoading} > - {error ? 'Failed to copy' : copied ? 'Copied!' : 'Copy page'} + + {error ? gt('Failed to copy') : copied ? gt('Copied!') : gt('Copy page')} +
            @@ -175,12 +179,12 @@ export function CopyMarkdownButton({pathname}: CopyMarkdownButtonProps) {
            - {error ? 'Failed to copy' : 'Copy page'} + {error ? gt('Failed to copy') : gt('Copy page')}
            {error - ? 'Network error - please try again' - : 'Copy page as Markdown for LLMs'} + ? gt('Network error - please try again') + : gt('Copy page as Markdown for LLMs')}
            @@ -197,10 +201,10 @@ export function CopyMarkdownButton({pathname}: CopyMarkdownButtonProps) {
            - View as Markdown + {gt('View as Markdown')}
            - View this page as plain text + {gt('View this page as plain text')}
            diff --git a/src/components/createGitHubAppForm.tsx b/src/components/createGitHubAppForm.tsx index 834a3fd8299cab..7ebd3ce9baea42 100644 --- a/src/components/createGitHubAppForm.tsx +++ b/src/components/createGitHubAppForm.tsx @@ -2,10 +2,12 @@ import {useState} from 'react'; import {Button} from '@radix-ui/themes'; +import {T, useGT} from 'gt-next'; const MAX_COMPONENTS_ON_PAGE = 100; export function CreateGitHubAppForm({url, defaultOrg, defaultUrlPrefix}) { + const gt = useGT(); const [orgSlug, setOrgSlug] = useState(''); const [urlPrefix, setUrlPrefix] = useState(''); const renderedUrl = url @@ -21,9 +23,11 @@ export function CreateGitHubAppForm({url, defaultOrg, defaultUrlPrefix}) {
            - + + +
            - + + +
            - Create GitHub App + {gt('Create GitHub App')}
            diff --git a/src/components/devDocsCardGrid.tsx b/src/components/devDocsCardGrid.tsx index e999b7f6baa608..8964b612ffc60a 100644 --- a/src/components/devDocsCardGrid.tsx +++ b/src/components/devDocsCardGrid.tsx @@ -1,3 +1,5 @@ +import {useGT} from 'gt-next'; + import BackendImg from 'sentry-docs/imgs/back-end.png'; import InfraImg from 'sentry-docs/imgs/dev-infra.png'; import FrontendImg from 'sentry-docs/imgs/front-end.png'; @@ -10,71 +12,73 @@ import SelfHostedImg from 'sentry-docs/imgs/support.png'; import {Card} from './card'; export function DevDocsCardGrid() { + const gt = useGT(); + return (
            diff --git a/src/components/docFeedback/index.tsx b/src/components/docFeedback/index.tsx index b0dd8704f29af6..a0f03ab36cd954 100644 --- a/src/components/docFeedback/index.tsx +++ b/src/components/docFeedback/index.tsx @@ -3,6 +3,7 @@ import {Fragment, useEffect, useState} from 'react'; import {CheckIcon as Check} from '@radix-ui/react-icons'; import {Button} from '@radix-ui/themes'; import * as Sentry from '@sentry/browser'; +import {useGT} from 'gt-next'; import {usePlausibleEvent} from 'sentry-docs/hooks/usePlausibleEvent'; @@ -11,6 +12,7 @@ type Props = { }; export function DocFeedback({pathname}: Props) { + const gt = useGT(); const {emit} = usePlausibleEvent(); const [showFeedback, setShowFeedback] = useState(false); const [feedbackSubmitted, setFeedbackSubmitted] = useState(false); @@ -60,26 +62,26 @@ export function DocFeedback({pathname}: Props) {
            {feedbackSubmitted ? (
            - Thanks for your feedback + {gt('Thanks for your feedback')}
            ) : (
            - Was this helpful? + {gt('Was this helpful?')}
            @@ -93,8 +95,8 @@ export function DocFeedback({pathname}: Props) {
            Filename (v{version})Integrity ChecksumFilename (v{version})Integrity Checksum