# General Translation Integrations: Configurar Sanity
URL: https://generaltranslation.com/es/docs/integrations/sanity/guides/configuring-sanity.mdx
Docs index: https://generaltranslation.com/llms.txt
Description: Cómo configurar el plugin gt-sanity de General Translation para locales, filtros de documentos, localización a nivel de campo, credenciales y documentos singleton.

Configura cómo funciona General Translation dentro de Sanity Studio con la función `gtPlugin`.

Esta guía abarca las opciones más comunes. Para ver la lista completa, consulta la [referencia de configuración del plugin](/docs/integrations/sanity/reference/plugin-configuration).

## Agrega el plugin [#add-plugin]

Agrega `gtPlugin` a la configuración de Studio. Este paso también se trata en el [Quickstart](/docs/integrations/sanity/quickstart).

```ts title="sanity.config.ts"
import { defineConfig } from 'sanity';
import { gtPlugin } from 'gt-sanity';

export default defineConfig({
  plugins: [
    gtPlugin({
      sourceLocale: 'en',
      locales: ['es', 'zh', 'ja'],
      translateDocuments: [{ type: 'article' }, { type: 'page' }],
    }),
  ],
});
```

## Explorar traducciones por configuración regional [#browse-locales]

Normalmente, Sanity muestra los documentos traducidos junto a los documentos de origen. Usa `gtStructureItems` para agrupar cada tipo de documento traducible en un panel por configuración regional, conservando los demás elementos de la estructura.

```ts title="sanity.config.ts"
import { defineConfig } from 'sanity';
import { structureTool } from 'sanity/structure';
import { gtPlugin, gtStructureItems } from 'gt-sanity';

export default defineConfig({
  plugins: [
    gtPlugin({
      sourceLocale: 'en',
      locales: ['es', 'zh', 'ja'],
      translateDocuments: [{ type: 'article' }, { type: 'page' }],
    }),
    structureTool({
      structure: (S, context) =>
        S.list()
          .title('Content')
          .items([
            ...gtStructureItems(S, context),
            S.divider(),
            ...S.documentTypeListItems(),
          ]),
    }),
  ],
});
```

El panel de la configuración regional de origen incluye documentos sin un campo de idioma, por lo que el contenido creado antes del plugin sigue apareciendo. Los tipos localizados en el mismo documento mediante listas internacionalizadas se omiten porque sus traducciones permanecen en el documento de origen.

Si Studio solo necesita los tipos agrupados por configuración regional, pasa el resolvedor `gtStructure()` completo a `structureTool`:

```ts
import { gtStructure } from 'gt-sanity';

structureTool({ structure: gtStructure() });
```

Pasa `types` a cualquiera de los helpers para reemplazar los tipos de documentos que se agrupan. Usa `sourceTitle` para cambiar el nombre del panel de origen o `localeTitle` para crear títulos personalizados para los paneles de destino. (Consulta la [referencia de helpers de estructura](/docs/integrations/sanity/reference/plugin-configuration#structure-helpers)).

## Define la configuración regional de origen y las de destino [#set-locales]

Usa `sourceLocale` para el idioma de origen y `locales` para las configuraciones regionales de destino.

```ts
gtPlugin({
  sourceLocale: 'en',
  locales: ['es', 'zh', 'ja'],
});
```

Si ya tienes un `gt.config.json`, puedes incluirlo en la configuración del plugin con el operador spread. `defaultLocale` también se acepta como alias de `sourceLocale`.

```ts title="sanity.config.ts"
import gtConfig from './gt.config.json';

gtPlugin({
  ...gtConfig,
});
```

La configuración regional de origen se determina en este orden: `sourceLocale`, luego `defaultLocale` y, después, el valor predeterminado de la biblioteca. Si se configuran tanto `sourceLocale` como `defaultLocale`, prevalece `sourceLocale`. El plugin elimina la configuración regional de origen y las entradas duplicadas de `locales`, por lo que un `gt.config.json` compartido puede incluir de forma segura la configuración regional predeterminada.

## Añade un campo de idioma [#language-field]

Las traducciones a nivel de documento se almacenan como documentos separados. El plugin usa un campo de idioma para registrar la configuración regional de cada documento. De forma predeterminada, el campo se llama `language`. La localización a nivel de campo no usa este campo.

```ts title="schema/article.ts"
import { defineField, defineType } from 'sanity';

export const articleType = defineType({
  name: 'article',
  title: 'Article',
  type: 'document',
  fields: [
    defineField({
      name: 'language',
      type: 'string',
      readOnly: true,
      hidden: true,
    }),
  ],
});
```

Para usar un nombre de campo distinto, configura `languageField` y usa el mismo nombre en tu schema.

```ts
gtPlugin({
  sourceLocale: 'en',
  locales: ['es', 'zh', 'ja'],
  languageField: 'locale',
});
```

## Elige qué documentos traducir [#choose-documents]

Usa `translateDocuments` para filtrar qué documentos se pueden traducir. Acepta filtros por tipo de documento, por ID de documento o cadenas abreviadas de tipo.

```ts
// Por tipo de documento
gtPlugin({
  sourceLocale: 'en',
  locales: ['es', 'zh', 'ja'],
  translateDocuments: [{ type: 'page' }, { type: 'post' }],
});
```

```ts
// Por ID de documento específico
gtPlugin({
  sourceLocale: 'en',
  locales: ['es', 'zh', 'ja'],
  translateDocuments: [{ documentId: 'homepage' }, { documentId: 'about-page' }],
});
```

```ts
// Cadenas de tipo en forma abreviada
gtPlugin({
  sourceLocale: 'en',
  locales: ['es'],
  translateDocuments: ['article', 'page'],
});
```

Las entradas de tipo `string` se tratan como `{ type: '<string>' }`. `showDocumentInternationalization` usa las entradas de `type` para decidir qué tipos de schema reciben insignias de idioma y plantillas, por lo que se requieren filtros por tipo de documento para habilitar esas funciones.

## Configurar la localización a nivel de campo [#field-level]

De forma predeterminada, `gt-sanity` traduce a nivel de documento y crea un documento por configuración regional. La localización a nivel de campo almacena el valor de cada configuración regional dentro del mismo documento como una lista internacionalizada (`[{ _key, _type, language, value }]` — con la misma estructura que [`sanity-plugin-internationalized-array`](https://github.com/sanity-io/sanity-plugin-internationalized-array), por lo que los datos existentes no requieren migración).

Habilita la generación del schema con `internationalizedArray` (o su alias, `fieldLevelLocalization`) y luego establece `translationLevel` en `'internationalizedArray'`.

```ts
gtPlugin({
  sourceLocale: 'en',
  locales: ['es', 'zh', 'ja'],
  translateDocuments: [{ type: 'post' }],
  internationalizedArray: { enabled: true },
  translationLevel: 'internationalizedArray',
});
```

La localización a nivel de campo se basa en [`sanity-plugin-internationalized-array`](https://github.com/sanity-io/sanity-plugin-internationalized-array), el plugin de referencia de Sanity. `gtPlugin` lo configura a partir de `sourceLocale` y `locales`, y el plugin nativo registra los tipos de schema `internationalizedArray*` y la interfaz de edición de Studio — los botones de añadir para cada idioma, las etiquetas de idioma y las acciones de campo se comportan exactamente igual que con el plugin independiente. Usa los tipos registrados en tus esquemas.

```ts
defineField({
  name: 'title',
  type: 'internationalizedArrayString',
});
```

De forma predeterminada, el plugin registra tipos `string` y `text`. Usa `fieldTypes` para añadir `block` (Portable Text) o definiciones de objetos personalizadas.

```ts
internationalizedArray: {
  enabled: true,
  fieldTypes: ['string', 'text', 'block', { name: 'seo', type: 'seoFields' }],
},
```

Si ya registras `sanity-plugin-internationalized-array` en tu Studio por tu cuenta, mantén tu configuración y deja `internationalizedArray` sin configurar para que los tipos de schema solo se registren una vez. Traducción lee y escribe los datos almacenados `{ _key, _type, language, value }` independientemente de qué instancia del plugin haya registrado los tipos, así que establecer `translationLevel` (y `translateDocuments`) es todo lo que GT necesita.

```ts
import { internationalizedArray } from 'gt-sanity';

plugins: [
  internationalizedArray({
    languages: [
      { id: 'en', title: 'English' },
      { id: 'es', title: 'Spanish' },
    ],
    fieldTypes: ['string'],
  }),
  gtPlugin({
    sourceLocale: 'en',
    locales: ['es'],
    translateDocuments: [{ type: 'post' }],
    translationLevel: 'internationalizedArray',
  }),
],
```

Para combinar ambas estrategias, establece `translationLevel` en `'mixed'` y enumera en `fieldLevelDocuments` los tipos de documento a nivel de campo.

```ts
gtPlugin({
  sourceLocale: 'en',
  locales: ['es', 'zh', 'ja'],
  translateDocuments: [{ type: 'post' }, { type: 'siteSettings' }],
  internationalizedArray: { enabled: true },
  translationLevel: 'mixed',
  fieldLevelDocuments: [{ type: 'siteSettings' }],
});
```

Los tipos de documento localizados en el mismo documento se excluyen automáticamente de `@sanity/document-internationalization`, por lo que no reciben insignias de idioma ni plantillas de documento para cada configuración regional. Durante la importación, el plugin actualiza solo la configuración regional de destino en el documento de origen y conserva todos los demás idiomas.

(Consulta la [referencia de configuración del plugin](/docs/integrations/sanity/reference/plugin-configuration#field-level) para ver todas las opciones a nivel de campo).

## Excluir campos de la traducción [#exclude-fields]

Marca un campo en tu schema para que su contenido no se traduzca. Establece `options.gt.exclude` en la definición del campo.

```ts title="schema/article.ts"
defineField({
  name: 'internalNotes',
  type: 'string',
  options: { gt: { exclude: true } },
});
```

Los campos excluidos nunca se envían a traducción, por lo que los documentos traducidos conservan intacto el valor de origen. La exclusión se aplica a cualquier nivel de anidación.

El plugin también respeta las opciones de exclusión de los plugins estándar de localización de Sanity, así que, si tu schema ya las usa, no necesitas añadir una segunda marca:

* `options.documentInternationalization.exclude` de `@sanity/document-internationalization`
* `options.aiAssist.exclude` de `@sanity/assist`
* la propiedad de campo heredada `localize: false`

Para excluir todas las instancias de un tipo personalizado, establece la opción en la propia definición del tipo.

```ts title="schema/objects/legalDisclaimer.ts"
export const legalDisclaimer = defineType({
  name: 'legalDisclaimer',
  type: 'object',
  // Excluye este tipo en todos los lugares donde se utiliza
  options: { gt: { exclude: true } },
  fields: [
    defineField({ name: 'jurisdiction', type: 'string' }),
    defineField({ name: 'text', type: 'text' }),
  ],
});
```

Para las reglas que se aplican a documentos por ID o transforman valores según la configuración regional —como la deduplicación de `slug`— usa en su lugar las opciones [`ignoreFields`, `skipFields` y `dedupeFields`](/docs/integrations/sanity/reference/plugin-configuration#field-matchers) a nivel del plugin.

## Configurar documentos singleton [#singletons]

Usa `singletons` para documentos que existen una sola vez por sitio, como la configuración del sitio o la navegación. `singletonMapping` controla cómo se obtiene el ID del documento del singleton traducido a partir del ID y la configuración regional del documento fuente.

```ts
gtPlugin({
  sourceLocale: 'en',
  locales: ['es', 'zh', 'ja'],
  singletons: ['siteSettings', 'navigation', 'footer'],
  singletonMapping: (sourceDocumentId, locale) => `${sourceDocumentId}-${locale}`,
});
```

Si omites `singletonMapping`, de forma predeterminada se asignan `sourceDocumentId` y `locale` a `` `${sourceDocumentId}-${locale}` `` (por ejemplo, `siteSettings-es`).

## Guardar credenciales [#store-credentials]

El plugin lee tu clave de API y el ID del proyecto de un documento privado de Sanity cuyo `_id` coincide con `secretsNamespace` (por defecto, `generaltranslation.secrets`). Créalo con un script puntual.

```js title="populateSecrets.js"
import { getCliClient } from 'sanity/cli';

const client = getCliClient({ apiVersion: '2025-09-15' });

client.createOrReplace({
  _id: 'generaltranslation.secrets',
  _type: 'generaltranslationSettings',
  secret: process.env.GT_API_KEY,
  project: process.env.GT_PROJECT_ID,
});
```

```bash
GT_API_KEY=your-api-key GT_PROJECT_ID=your-project-id npx sanity exec populateSecrets.js --with-user-token
```

El campo `secret` se usa como la clave de API y el campo `project` como el ID del proyecto. Para leer credenciales desde otro documento, establece `secretsNamespace` con el `_id` de ese documento.

También puedes pasar `apiKey` y `projectId` directamente a `gtPlugin`, pero se recomienda usar el documento de secretos para que las credenciales no queden en el control de versiones. Cuando ambos están presentes, el documento de secretos tiene prioridad en Runtime.

La convención de documentos privados evita las consultas públicas no autenticadas; no sustituye los permisos de Sanity para los usuarios autenticados de Studio. Restringe el acceso al conjunto de datos con el [control de acceso basado en roles de Sanity](https://www.sanity.io/docs/access-control) y elimina el script puntual después de crear el documento.

## Añade la pestaña opcional Traducciones [#translations-tab]

La acción de documento **Traducir** se añade automáticamente. Para mostrar también la pestaña Traducciones dentro del editor de documentos, añade `TranslationsTab` con `structureTool`.

```ts title="sanity.config.ts"
import { defineConfig } from 'sanity';
import { structureTool } from 'sanity/structure';
import { gtPlugin, TranslationsTab } from 'gt-sanity';

export default defineConfig({
  plugins: [
    structureTool({
      defaultDocumentNode: (S) =>
        S.document().views([
          S.view.form(),
          S.view.component(TranslationsTab).title('General Translation'),
        ]),
    }),
    gtPlugin({
      sourceLocale: 'en',
      locales: ['es', 'zh', 'ja'],
    }),
  ],
});
```

## Next steps

- /docs/integrations/sanity/guides/translating-content
- /docs/integrations/sanity/guides/managing-translations
- /docs/integrations/sanity/guides/querying-translations

## Sitemap

See the full [sitemap](https://generaltranslation.com/sitemap.md) for all pages.
