# General Translation Integrations: Configuración del plugin de Sanity URL: https://generaltranslation.com/es/docs/integrations/sanity/reference/plugin-configuration.mdx --- title: Configuración del plugin de Sanity description: Configura el plugin gt-sanity de General Translation para Sanity Studio. Referencia de la API de gtPlugin. --- Registra General Translation en tu config de Sanity con la función `gtPlugin`. Pasa un único objeto de opciones. ```ts title="sanity.config.ts" import { gtPlugin } from 'gt-sanity'; gtPlugin({ sourceLocale: 'en', locales: ['es', 'fr'], translateDocuments: [{ type: 'article' }], }); ``` ## Opciones [#options] | Opción | Descripción | Tipo | Opcional | Predeterminado | | ----------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- | -------- | --------------------------------------------------------------- | | [`sourceLocale`](#source-locale) | Código del idioma de origen, como `en`. | `string` | Sí | `defaultLocale`, luego el valor predeterminado de la biblioteca | | [`defaultLocale`](#default-locale) | Alias de `sourceLocale`, para expandir `gt.config.json`. | `string` | Sí | — | | [`locales`](#locales) | Códigos de configuración regional de destino. Se eliminan las entradas duplicadas y las correspondientes a la configuración regional de origen. | `string[]` | No | — | | [`customMapping`](#custom-mapping) | Mapeos personalizados de códigos de configuración regional y anulaciones de propiedades. | [`CustomMapping`](/docs/platform/core/reference/types/custom-mapping) | Sí | — | | [`apiKey`](#api-key) | Clave de API de General Translation. | `string` | Sí | Documento de secretos | | [`projectId`](#project-id) | ID del proyecto de General Translation. | `string` | Sí | Documento de secretos | | [`secretsNamespace`](#secrets-namespace) | `_id` del documento privado de credenciales. | `string` | Sí | `generaltranslation.secrets` | | [`languageField`](#language-field) | Campo del documento que almacena la configuración regional. | `string` | Sí | `language` | | [`translateDocuments`](#translate-documents) | Filtra qué documentos se pueden traducir. | `TranslateDocumentFilter[] \| string[]` | Sí | `[]` | | [`singletons`](#singletons) | ID de documentos tratados como singletons. | `string[]` | Sí | `[]` | | [`singletonMapping`](#singleton-mapping) | Asocia un ID de origen y una configuración regional con un ID de singleton traducido. | `(sourceDocumentId: string, locale: string) => string` | Sí | `` `${sourceDocumentId}-${locale}` `` | | [`showDocumentInternationalization`](#show-doc-i18n) | Agrega automáticamente `@sanity/document-internationalization`. | `boolean` | Sí | `true` | | [`internationalizedArray`](#internationalized-array) | Configura `sanity-plugin-internationalized-array` para la localización a nivel de campo. | `GTFieldLevelLocalizationConfig` | Sí | — | | [`fieldLevelLocalization`](#field-level-localization) | Alias de `internationalizedArray`. | `GTFieldLevelLocalizationConfig` | Sí | — | | [`translationLevel`](#translation-level) | Elige la traducción a nivel de documento, a nivel de campo o mixta. | `'document' \| 'internationalizedArray' \| 'mixed'` | Sí | `'document'` | | [`fieldLevelDocuments`](#field-level-documents) | Tipos de documento que usan localización a nivel de campo en modo mixto. | `TranslateDocumentFilter[] \| string[]` | Sí | `[]` | | [`preserveExistingTranslations`](#preserve-existing-translations) | Estado inicial del interruptor **Guardar ediciones locales**. | `boolean` | Sí | `false` | | [`ignoreFields`](#ignore-fields) | Campos copiados del origen sin traducir. | `FieldMatcher[]` | Sí | `[]` | | [`dedupeFields`](#dedupe-fields) | Campos copiados del origen y convertidos en valores únicos por configuración regional. | `FieldMatcher[]` | Sí | `[]` | | [`skipFields`](#skip-fields) | Campos eliminados de los documentos traducidos. | `FieldMatcher[]` | Sí | `[]` | | [`additionalStopTypes`](#additional-stop-types) | Tipos de esquema adicionales que se conservan sin traducir. | `string[]` | Sí | `[]` | | [`additionalSerializers`](#additional-serializers) | serializador HTML personalizados para marcas y tipos de bloque. | `Partial` | Sí | `{}` | | [`additionalDeserializers`](#additional-deserializers) | deserializador HTML personalizados. | `CustomDeserializers` | Sí | `{}` | | [`additionalBlockDeserializers`](#additional-block-deserializers) | Reglas personalizadas de deserialización de bloques de Portable Text. | `unknown[]` | Sí | `[]` | ## Opciones de configuración regional [#locale-options] ### `sourceLocale` [#source-locale] **Tipo** `string` · **Opcional** · **Predeterminado** `defaultLocale`, y luego el valor predeterminado de la biblioteca El código del idioma de origen, como `en`. El plugin determina la configuración regional de origen en este orden: `sourceLocale`, luego `defaultLocale` y, por último, el valor predeterminado de la biblioteca `generaltranslation`. ### `defaultLocale` [#default-locale] **Tipo** `string` · **Opcional** Alias de `sourceLocale`, que se acepta para que puedas pasar un `gt.config.json` directamente al plugin mediante spread. Si se establecen ambos, `sourceLocale` tiene prioridad. ```ts import gtConfig from './gt.config.json'; gtPlugin({ ...gtConfig }); ``` ### `locales` [#locales] **Tipo** `string[]` · **Obligatorio** Los códigos de configuración regional de destino para traducir, como `['es', 'fr', 'ja']`. El plugin elimina las entradas duplicadas y cualquier entrada igual a la configuración regional de origen resuelta antes de configurar los plugins de traducción o de localización de Sanity. | Versión | Cambios | | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `3.1.1` | Elimina las configuraciones regionales de destino duplicadas y la configuración regional de origen resuelta antes de configurar los plugins de traducción y de localización de Sanity. | ### `customMapping` [#custom-mapping] **Tipo** [`CustomMapping`](/docs/platform/core/reference/types/custom-mapping) · **Opcional** Mapeos personalizados de códigos de configuración regional a nombres, o anulaciones de propiedades de la configuración regional. Se pasa a la biblioteca `generaltranslation`. Consulta [CustomMapping](/docs/platform/core/reference/types/custom-mapping). ## Credenciales [#credentials] De forma predeterminada, el plugin obtiene las credenciales de un documento privado de Sanity. Consulta [Guardar credenciales](/docs/integrations/sanity/guides/configuring-sanity#store-credentials). ### `apiKey` [#api-key] **Tipo** `string` · **Opcional** · **Predeterminado** tomado del documento de secretos Tu clave de API de General Translation. Si se configura, se pasa a la biblioteca al iniciarse. Si hay un documento de secretos, su campo `secret` tiene prioridad en tiempo de ejecución. Se recomienda usar el documento de secretos para que las claves no queden en el control de versiones. ### `projectId` [#project-id] **Tipo** `string` · **Opcional** · **Predeterminado** se lee del documento de secretos El ID del proyecto de tu proyecto de General Translation. Cuando hay un documento de secretos, su campo `project` tiene prioridad en tiempo de ejecución. ### `secretsNamespace` [#secrets-namespace] **Tipo** `string` · **Opcional** · **Valor predeterminado** `generaltranslation.secrets` El `_id` del documento privado de Sanity que contiene las credenciales. El plugin recupera este documento por `_id` y usa su campo `secret` como clave de API y su campo `project` como ID del proyecto. Un `.` al inicio del `_id` hace que el documento siga siendo privado, incluso en un conjunto de datos público. ```js title="populateSecrets.js" import { getCliClient } from 'sanity/cli'; const client = getCliClient({ apiVersion: '2026-04-06' }); client.createOrReplace({ _id: 'generaltranslation.secrets', _type: 'generaltranslation.secrets', secret: process.env.GT_API_KEY, project: process.env.GT_PROJECT_ID, }); ``` ## Opciones del documento [#document-options] ### `languageField` [#language-field] **Tipo** `string` · **Opcional** · **Predeterminado** `language` El campo del documento que se usa para almacenar la configuración regional de la traducción a nivel de documento de cada documento. Agrega un campo con este nombre a los tipos de documento traducidos con localización a nivel de documento y consúltalo para recuperar una configuración regional específica. La localización a nivel de campo no usa este campo. ### `translateDocuments` [#translate-documents] **Tipo** `TranslateDocumentFilter[] | string[]` · **Opcional** · **Predeterminado** `[]` Filtra qué documentos se pueden traducir. Acepta objetos de filtro o cadenas abreviadas con tipos. Cada entrada de cadena `'article'` se normaliza a `{ type: 'article' }`, y se descartan las entradas que no tengan `documentId` o `type`. ```ts gtPlugin({ sourceLocale: 'en', locales: ['es'], translateDocuments: [ { type: 'article' }, { documentId: 'homepage' }, 'page', // forma abreviada de { type: 'page' } ], }); ``` `TranslateDocumentFilter` tiene esta estructura: ```ts type TranslateDocumentFilter = { documentId?: string; // coincide con un documento específico por _id type?: string; // coincide con todos los documentos de un tipo de esquema }; ``` Las entradas de `type` también determinan qué tipos de esquema habilita [`showDocumentInternationalization`](#show-doc-i18n). ### `singletons` [#singletons] **Tipo** `string[]` · **Opcional** · **Predeterminado** `[]` IDs de documentos que se tratan como singletons, como la configuración del sitio o la navegación. Los IDs de sus documentos traducidos se derivan de [`singletonMapping`](#singleton-mapping). ### `singletonMapping` [#singleton-mapping] **Tipo** `(sourceDocumentId: string, locale: string) => string` · **Opcional** · **Predeterminado** `` `${sourceDocumentId}-${locale}` `` Asigna el ID del documento de origen de un singleton y una configuración regional al ID del documento del singleton traducido. El valor predeterminado es determinista, por lo que `siteSettings` pasa a ser `siteSettings-es` en español. ```ts gtPlugin({ sourceLocale: 'en', locales: ['es'], singletons: ['siteSettings'], singletonMapping: (sourceDocumentId, locale) => `${sourceDocumentId}_${locale}`, }); ``` ### `showDocumentInternationalization` [#show-doc-i18n] **Tipo** `boolean` · **Opcional** · **Predeterminado** `true` Cuando es `true`, el plugin añade `@sanity/document-internationalization` con insignias de idioma, un menú de traducción y plantillas de documentos para cada idioma. Usa las entradas `type` de [`translateDocuments`](#translate-documents) como tipos de esquema y la configuración regional de origen seguida de las configuraciones regionales de destino normalizadas como idiomas admitidos, por lo que solo surte efecto cuando `translateDocuments` incluye tipos de documento. Los tipos de documento localizados en el mismo documento con listas internacionalizadas se excluyen automáticamente. Establécelo en `false` para gestionar la internacionalización por tu cuenta. Si ya registraste `@sanity/document-internationalization` en tu Studio, mantén tu configuración y establece esta opción en `false` para que el plugin (y su tipo de documento `translation.metadata`) solo se registre una vez: registrarlo dos veces produce un error de tipo de esquema duplicado. La traducción funciona con tu instancia sin cambios: el plugin lee y escribe documentos mediante el [`languageField`](#language-field) y los documentos `translation.metadata`, independientemente de cuál de los registros los haya añadido. Usa los mismos ID de idioma y el mismo campo de idioma en ambas configuraciones. ## Localización a nivel de campo [#field-level] La localización a nivel de campo almacena el valor de cada configuración regional en un único documento como una lista internacionalizada. Se implementa mediante [`sanity-plugin-internationalized-array`](https://github.com/sanity-io/sanity-plugin-internationalized-array): `gtPlugin` configura el plugin nativo, que registra los tipos de esquema `internationalizedArray*` y la interfaz de usuario de edición de Studio. Los datos almacenados usan la estructura de elementos `{ _key, _type, language, value }`, por lo que el contenido existente de internationalized-array no necesita migración, y la traducción funciona igual tanto si los tipos los registró `gtPlugin` como si los registró tu propia implementación de `internationalizedArray()`. **Cambió en v3:** la localización a nivel de campo la proporciona `sanity-plugin-internationalized-array` en lugar de los tipos y componentes generados por GT. Se eliminaron `createInternationalizedArrayTypes`, `FieldLevelUIComponents` y las opciones `typePrefix`, `includeCompatibilityTypes` y `components`; si se pasa una opción eliminada, se registra una advertencia y se ignora. ### `internationalizedArray` [#internationalized-array] **Tipo** `GTFieldLevelLocalizationConfig` · **Opcional** Configura `sanity-plugin-internationalized-array` para la localización a nivel de campo. La identidad de la configuración regional siempre se toma de `sourceLocale` y `locales`; deja esta opción sin configurar si registras el plugin nativo por tu cuenta, para que los tipos de esquema solo se registren una vez. ```ts type GTFieldLevelLocalizationConfig = { enabled?: boolean; // predeterminado: false fieldTypes?: FieldLevelFieldType[]; // predeterminado: ['string', 'text'] languageTitles?: Record; getLanguageTitle?: (locale: string) => string; defaultLanguages?: string[]; // predeterminado: [sourceLocale] // Se transfiere directamente a sanity-plugin-internationalized-array apiVersion?: string; buttonLocations?: ('field' | 'unstable__fieldAction' | 'document')[]; buttonAddAll?: boolean; languageDisplay?: 'titleOnly' | 'codeOnly' | 'titleAndCode'; }; type FieldLevelFieldType = | string | { name: string; type: string; title?: string; of?: unknown[]; fields?: unknown[]; options?: Record; }; ``` Las entradas de `fieldTypes` aceptan un nombre de tipo de Sanity (`'string'`, `'text'`), el atajo `'block'` (una lista de Portable Text) o una entrada de objeto que define un campo encapsulado personalizado; una entrada de objeto llamada `seo` registra `internationalizedArraySeo`. `getLanguageTitle` reemplaza a `languageTitles` cuando ambos están configurados. `defaultLanguages` controla qué configuraciones regionales se rellenan de antemano en los campos localizados vacíos y, de forma predeterminada, usa la configuración regional de origen. `apiVersion`, `buttonLocations`, `buttonAddAll` y `languageDisplay` se pasan al plugin nativo sin cambios. ### `fieldLevelLocalization` [#field-level-localization] **Tipo** `GTFieldLevelLocalizationConfig` · **Opcional** Un alias descriptivo de [`internationalizedArray`](#internationalized-array). ### `translationLevel` [#translation-level] **Tipo** `'document' | 'internationalizedArray' | 'mixed'` · **Opcional** · **Por defecto** `'document'` Controla cómo se traducen los documentos que coinciden: * `'document'` crea un documento por configuración regional * `'internationalizedArray'` localiza los campos configurados en el mismo documento * `'mixed'` usa localización a nivel de campo para [`fieldLevelDocuments`](#field-level-documents) y localización a nivel de documento para todo lo demás ### `fieldLevelDocuments` [#field-level-documents] **Tipo** `TranslateDocumentFilter[] | string[]` · **Opcional** · **Predeterminado** `[]` Selecciona los tipos de documentos que usan listas internacionalizadas cuando `translationLevel` es `'mixed'`. Cada entrada es un filtro de tipo, como `{ type: 'siteSettings' }`, o la cadena abreviada `'siteSettings'`. Aquí no se admiten filtros por ID de documento. ```ts gtPlugin({ sourceLocale: 'en', locales: ['es', 'fr'], translateDocuments: [{ type: 'post' }, { type: 'siteSettings' }], internationalizedArray: { enabled: true, fieldTypes: ['string', 'text', 'block'], languageTitles: { es: 'Español', fr: 'Français' }, }, translationLevel: 'mixed', fieldLevelDocuments: [{ type: 'siteSettings' }], }); ``` Luego, usa los tipos generados en tus schemas: ```ts defineField({ name: 'title', type: 'internationalizedArrayString', }); ``` ## Opciones del flujo de trabajo de Traducción [#workflow-options] ### `preserveExistingTranslations` [#preserve-existing-translations] **Tipo** `boolean` · **Opcional** · **Predeterminado** `false` Establece el estado inicial del interruptor **Guardar ediciones locales**. Cuando está activado, las traducciones existentes en Sanity se envían a General Translation antes de ejecutar una traducción, de modo que el contenido cuyo texto de origen no haya cambiado conserve su redacción existente en lugar de volver a traducirse. ```ts title="sanity.config.ts" gtPlugin({ sourceLocale: 'en', locales: ['es', 'fr'], translateDocuments: [{ type: 'post' }], preserveExistingTranslations: true, }); ``` Esta opción establece el estado inicial del interruptor al cargar Studio. Los editores pueden activarlo o desactivarlo durante su sesión desde la herramienta **Translations** o la pestaña del documento, y esa elección prevalece durante el resto de la sesión. Con el interruptor activado, el contenido de Sanity reemplaza cualquier contenido que General Translation tenga para esa versión del documento, incluida una traducción finalizada que aún no se haya importado. Importe las traducciones pendientes antes de activarlo. Consulte [Conservar las ediciones de las traducciones](/docs/integrations/sanity/guides/translating-content#preserve-edits). ## Selectores de campos [#field-matchers] Cada uno de `ignoreFields`, `dedupeFields` y `skipFields` acepta una lista de objetos `FieldMatcher`. Un selector se aplica a campos mediante una expresión JSONPath en `property` y, opcionalmente, puede limitarse a un único documento de origen mediante `documentId`. Para excluir un campo en cualquier lugar donde aparezca, es preferible marcarlo en el esquema con las [opciones de exclusión del esquema](#schema-exclusion). ```ts type FieldMatcher = { documentId?: string | null; // restringir a un documento de origen por _id fields?: { property: string; // expresión JSONPath, como $.slug type?: string; // sugerencia de tipo de esquema opcional, como slug }[]; }; ``` ### `ignoreFields` [#ignore-fields] **Tipo** `FieldMatcher[]` · **Opcional** · **Predeterminado** `[]` Campos copiados del documento de origen al documento traducido sin enviarlos a la API de traducción. Úselo para valores que deben permanecer idénticos en todas las configuraciones regionales, como categorías o etiquetas. ```ts gtPlugin({ sourceLocale: 'en', locales: ['es'], ignoreFields: [ // Copiar categoría sin cambios para todos los documentos { fields: [{ property: '$.category' }] }, // Copiar etiquetas sin cambios solo para un documento { documentId: 'homepage', fields: [{ property: '$.tags' }] }, ], }); ``` ### `dedupeFields` [#dedupe-fields] **Tipo** `FieldMatcher[]` · **Opcional** · **Predeterminado** `[]` Campos copiados del valor de origen y convertidos en valores únicos al añadir la configuración regional cuando el documento traducido se crea por primera vez. Suele usarse para slugs. ```ts gtPlugin({ sourceLocale: 'en', locales: ['es', 'fr'], // "about" se convierte en "about-es" y "about-fr" dedupeFields: [{ fields: [{ property: '$.slug', type: 'slug' }] }], }); ``` En un campo slug, el plugin actualiza el valor `current` del objeto slug. Si más adelante un editor cambia el slug traducido, las importaciones futuras conservan ese valor editado. ### `skipFields` [#skip-fields] **Tipo** `FieldMatcher[]` · **Opcional** · **Predeterminado** `[]` Campos que se eliminan por completo de los documentos traducidos. ```ts gtPlugin({ sourceLocale: 'en', locales: ['es'], skipFields: [ { fields: [{ property: '$.slug', type: 'slug' }] }, { documentId: 'homepage', fields: [{ property: '$.debugInfo' }] }, ], }); ``` ## Opciones de exclusión del esquema [#schema-exclusion] Los campos y tipos pueden excluirse de la traducción directamente en el esquema, sin una entrada en la configuración del plugin. Durante la serialización, el plugin comprueba los `options` de cada definición del esquema en busca de estos espacios de nombres y omite las coincidencias del contenido enviado para traducción: | Opción | Plugin de origen | | ---------------------------------------------- | --------------------------------------- | | `options.gt.exclude` | `gt-sanity` | | `options.documentInternationalization.exclude` | `@sanity/document-internationalization` | | `options.aiAssist.exclude` | `@sanity/assist` | Cada uno acepta `boolean`; solo se excluye con un `true` explícito. La exclusión se aplica a cualquier nivel de anidamiento. El contenido excluido nunca se envía para traducción, por lo que los documentos traducidos conservan sin cambios el valor de origen. ```ts defineField({ name: 'internalNotes', type: 'string', options: { gt: { exclude: true } }, }); ``` Establecer una opción de exclusión en las `options` de una definición de tipo personalizada excluye todas las apariciones de ese tipo, siguiendo la semántica de "campo o tipo" de los plugins nativos. La propiedad de campo legacy `localize: false` también se sigue respetando. `gt-sanity` amplía los tipos de opciones del esquema de Sanity (la interfaz `GTSchemaFieldOptions`) para que `options.gt` tenga verificación de tipos en cualquier definición de campo. *Nota: la exclusión en el esquema marca un campo por nombre y tipo; para reglas dirigidas a un documento específico por ID o que transforman valores según la configuración regional, usa [`ignoreFields`, `skipFields` y `dedupeFields`](#field-matchers).* ## Serialización [#serialization] El plugin serializa los documentos a HTML para traducirlos y luego deserializa el resultado de nuevo en campos de Sanity. La mayoría de los proyectos no necesitan estas opciones. ### `additionalStopTypes` [#additional-stop-types] **Tipo** `string[]` · **Opcional** · **Predeterminado** `[]` Tipos de esquema adicionales que se conservarán sin traducir, añadidos a los [tipos de exclusión predeterminados](#stop-types). ```ts gtPlugin({ sourceLocale: 'en', locales: ['es'], additionalStopTypes: ['codeBlock', 'mux.video', 'mux.videoAsset'], }); ``` ### `additionalSerializers` [#additional-serializers] **Tipo** `Partial` · **Opcional** · **Predeterminado** `{}` Serializadores personalizados combinados con los predeterminados, siguiendo la estructura de componentes de `@portabletext/to-html` (`types`, `marks`, `block`, `list`, `listItem`, entre otros). Se usan principalmente para serializar `marks` personalizados. Para `marks` personalizados, envuelve la salida con `attachGTData` para que los datos de la marca se conserven durante la traducción. ```ts title="sanity.config.ts" import { attachGTData, gtPlugin } from 'gt-sanity'; gtPlugin({ sourceLocale: 'en', locales: ['es'], additionalSerializers: { marks: { link: ({ value, children }) => attachGTData(`${children}`, value, 'markDef'), inlineMath: ({ value, children }) => attachGTData(`${children}`, value, 'markDef'), }, }, }); ``` `attachGTData(html, data, 'markDef')` codifica `data` en base64 en un atributo `data-gt-internal` del primer elemento de `html` y devuelve el HTML actualizado. Al importarlo, el plugin lee ese atributo para reconstruir la definición de la marca. ```ts function attachGTData( html: string, data: Record, type: 'markDef' ): string; ``` ### `additionalDeserializers` [#additional-deserializers] **Tipo** `CustomDeserializers` · **Opcional** · **Predeterminado** `{}` Deserializadores personalizados que convierten elementos HTML traducidos nuevamente en objetos de Sanity, organizados por tipo. ```ts type CustomDeserializers = { types?: Record< string, (element: HTMLElement) => Record | unknown[] >; } & Record; ``` ### `additionalBlockDeserializers` [#additional-block-deserializers] **Tipo** `unknown[]` · **Opcional** · **Predeterminado** `[]` Reglas adicionales para deserializar bloques de Portable Text, que se añaden a las reglas integradas del plugin. Cada regla es un objeto con un método `deserialize(node, next)`, que sigue la estructura de regla de `@portabletext/block-tools`. ## Tipos de exclusión predeterminados [#stop-types] Estos tipos de esquema se conservan y nunca se envían a traducción. Añade más con [`additionalStopTypes`](#additional-stop-types). ```ts const defaultStopTypes = [ 'reference', 'date', 'datetime', 'file', 'geopoint', 'image', 'number', 'crop', 'hotspot', 'boolean', 'url', 'color', 'code', ]; ``` Los campos slug *no* se omiten de forma predeterminada, por lo que la cadena `current` de un slug se traduce a menos que uses [`dedupeFields`](#dedupe-fields) o [`skipFields`](#skip-fields). ## Funciones auxiliares exportadas [#helpers] `gt-sanity` también exporta bloques base para la serialización avanzada y nodos de documento personalizados. La mayoría de los proyectos no los necesitan. * `TranslationsTab` — el componente de pestaña del documento para `structureTool`. Consulta [Configurar Sanity](/docs/integrations/sanity/guides/configuring-sanity#translations-tab). * `attachGTData` / `detachGTData` — adjuntan y leen los datos de marca codificados que usan los serializadores personalizados. * `BaseDocumentSerializer`, `BaseDocumentDeserializer`, `BaseDocumentMerger` — las implementaciones predeterminadas para serializar, deserializar y fusionar. * `defaultStopTypes`, `customSerializers` — los tipos de exclusión predeterminados y el conjunto de serializadores. * `documentInternationalization` y sus tipos (`DocumentInternationalizationConfig`, `Language`, `Metadata`, `TranslationReference`) — se reexportan desde `@sanity/document-internationalization`. * `internationalizedArray`, `internationalizedArrayLanguageFilter` e `isInternationalizedArrayItemType`, además de los tipos `InternationalizedArrayPluginConfig` e `InternationalizedArrayLanguage` — se reexportan desde `sanity-plugin-internationalized-array`. * `GTSchemaFieldOptions` — la interfaz de opciones de esquema detrás de `options.gt`. Consulta [opción de exclusión del esquema](#schema-exclusion). ## Ejemplo completo [#complete-example] ```ts title="sanity.config.ts" import { defineConfig } from 'sanity'; import { attachGTData, gtPlugin } from 'gt-sanity'; export default defineConfig({ plugins: [ gtPlugin({ // Obligatorio sourceLocale: 'en', locales: ['es', 'fr', 'de', 'ja'], // Documentos y campos languageField: 'language', translateDocuments: [{ type: 'article' }, { type: 'page' }], singletons: ['siteSettings', 'navigation'], singletonMapping: (id, locale) => `${id}_${locale}`, // Comportamiento de campos ignoreFields: [{ fields: [{ property: '$.category' }] }], dedupeFields: [{ fields: [{ property: '$.slug', type: 'slug' }] }], skipFields: [{ fields: [{ property: '$.internalNotes' }] }], // Serialización — solo si los valores predeterminados no cubren tu esquema additionalSerializers: { marks: { link: ({ value, children }) => attachGTData(`${children}`, value, 'markDef'), }, }, }), ], }); ```