# General Translation Integrations: Конфигурация плагина Sanity URL: https://generaltranslation.com/ru/docs/integrations/sanity/reference/plugin-configuration.mdx --- title: Конфигурация плагина Sanity description: Настройте плагин gt-sanity от General Translation для Sanity Studio. Справочник по API для gtPlugin. --- Настройте General Translation в Sanity Studio с помощью функции `gtPlugin`. Передайте один объект параметров. ```ts title="sanity.config.ts" import { gtPlugin } from 'gt-sanity'; gtPlugin({ sourceLocale: 'en', locales: ['es', 'fr'], translateDocuments: [{ type: 'article' }], }); ``` ## Параметры [#options] | Параметр | Описание | Тип | Необязательно | По умолчанию | | ----------------------------------------------------------------- | ------------------------------------------------------------------------------ | --------------------------------------------------------------------- | ------------- | ------------------------------------------------------- | | [`sourceLocale`](#source-locale) | Код исходного языка, например `en`. | `string` | Да | `defaultLocale`, затем значение библиотеки по умолчанию | | [`defaultLocale`](#default-locale) | Алиас для `sourceLocale` при использовании spread с `gt.config.json`. | `string` | Да | — | | [`locales`](#locales) | Коды целевых локалей. | `string[]` | Нет | — | | [`customMapping`](#custom-mapping) | Пользовательские сопоставления кодов локалей и переопределения свойств. | [`CustomMapping`](/docs/platform/core/reference/types/custom-mapping) | Да | — | | [`apiKey`](#api-key) | API-ключ General Translation. | `string` | Да | Документ Secrets | | [`projectId`](#project-id) | Идентификатор проекта General Translation. | `string` | Да | Документ Secrets | | [`secretsNamespace`](#secrets-namespace) | `_id` документа с закрытыми учетными данными. | `string` | Да | `generaltranslation.secrets` | | [`languageField`](#language-field) | Поле документа, в котором хранится локаль. | `string` | Да | `language` | | [`translateDocuments`](#translate-documents) | Определяет, какие документы можно переводить. | `TranslateDocumentFilter[] \| string[]` | Да | `[]` | | [`singletons`](#singletons) | ID документов, которые считаются синглтонами. | `string[]` | Да | `[]` | | [`singletonMapping`](#singleton-mapping) | Сопоставляет исходный ID и локаль с ID переведённого синглтон-документа. | `(sourceDocumentId: string, locale: string) => string` | Да | `` `${sourceDocumentId}-${locale}` `` | | [`showDocumentInternationalization`](#show-doc-i18n) | Автоматически добавляет `@sanity/document-internationalization`. | `boolean` | Да | `true` | | [`internationalizedArray`](#internationalized-array) | Настраивает локализацию на уровне полей с помощью internationalized arrays. | `GTFieldLevelLocalizationConfig` | Да | — | | [`fieldLevelLocalization`](#field-level-localization) | Алиас для `internationalizedArray`. | `GTFieldLevelLocalizationConfig` | Да | — | | [`translationLevel`](#translation-level) | Выбирает перевод на уровне документа, на уровне полей или смешанный режим. | `'document' \| 'internationalizedArray' \| 'mixed'` | Да | `'document'` | | [`fieldLevelDocuments`](#field-level-documents) | Типы документов, использующие локализацию на уровне полей в смешанном режиме. | `TranslateDocumentFilter[] \| string[]` | Да | `[]` | | [`ignoreFields`](#ignore-fields) | Поля, которые копируются из source без перевода. | `FieldMatcher[]` | Да | `[]` | | [`dedupeFields`](#dedupe-fields) | Поля, которые копируются из source и становятся уникальными для каждой локали. | `FieldMatcher[]` | Да | `[]` | | [`skipFields`](#skip-fields) | Поля, удаляемые из переведённых документов. | `FieldMatcher[]` | Да | `[]` | | [`additionalStopTypes`](#additional-stop-types) | Дополнительные типы схемы, которые сохраняются без перевода. | `string[]` | Да | `[]` | | [`additionalSerializers`](#additional-serializers) | Пользовательские HTML-сериализаторы для `marks` и типов блоков. | `Partial` | Да | `{}` | | [`additionalDeserializers`](#additional-deserializers) | Пользовательские HTML-десериализаторы. | `CustomDeserializers` | Да | `{}` | | [`additionalBlockDeserializers`](#additional-block-deserializers) | Пользовательские правила десериализации блоков Portable Text. | `unknown[]` | Да | `[]` | ## Параметры локали [#locale-options] ### `sourceLocale` [#source-locale] **Тип** `string` · **Необязательно** · **По умолчанию** `defaultLocale`, затем значение по умолчанию библиотеки Код исходного языка, например `en`. Плагин определяет исходную локаль в следующем порядке: `sourceLocale`, затем `defaultLocale`, затем значение по умолчанию библиотеки `generaltranslation`. ### `defaultLocale` [#default-locale] **Тип** `string` · **Необязательно** Алиас для `sourceLocale`; поддерживается, чтобы можно было напрямую передать `gt.config.json` в плагин через spread. Если заданы оба параметра, приоритет у `sourceLocale`. ```ts import gtConfig from './gt.config.json'; gtPlugin({ ...gtConfig }); ``` ### `locales` [#locales] **Type** `string[]` · **Обязательно** Коды целевых локалей, на которые будет выполняться перевод, например `['es', 'fr', 'ja']`. ### `customMapping` [#custom-mapping] **Тип** `CustomMapping` · **Необязательно** Пользовательские сопоставления кодов локалей с названиями или переопределения свойств локали. Передаётся в библиотеку `generaltranslation`. См. [CustomMapping](/docs/platform/core/reference/types/custom-mapping). ## Учетные данные [#credentials] По умолчанию плагин считывает учетные данные из закрытого документа Sanity. См. [Хранение учетных данных](/docs/integrations/sanity/guides/configuring-sanity#store-credentials). ### `apiKey` [#api-key] **Тип** `string` · **Необязательный** · **По умолчанию** считывается из документа secrets Ваш API-ключ General Translation. Если задан, передаётся в библиотеку при запуске. Если есть документ secrets, во время выполнения приоритет имеет его поле `secret`. Рекомендуется использовать документ secrets, чтобы ключи не попадали в систему контроля версий. ### `projectId` [#project-id] **Тип** `string` · **Необязательно** · **По умолчанию** считывается из документа secrets ID вашего проекта General Translation. Если документ secrets присутствует, в Runtime приоритет имеет его поле `project`. ### `secretsNamespace` [#secrets-namespace] **Тип** `string` · **Необязательно** · **По умолчанию** `generaltranslation.secrets` `_id` приватного документа Sanity, в котором хранятся учетные данные. Плагин получает этот документ по `_id` и использует его поле `secret` как API-ключ, а поле `project` — как project ID. Точка `.` в начале `_id` делает документ приватным даже в общедоступном наборе данных. ```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, }); ``` ## Параметры документа [#document-options] ### `languageField` [#language-field] **Тип** `string` · **Необязательно** · **По умолчанию** `language` Поле документа, используемое для хранения локали документа. Добавьте поле с этим именем в каждый тип переводимого документа и используйте его в запросах, чтобы получать конкретную локаль. ### `translateDocuments` [#translate-documents] **Тип** `TranslateDocumentFilter[] | string[]` · **Необязательно** · **По умолчанию** `[]` Определяет, какие документы можно переводить. Принимает объекты фильтра или сокращённые строки типа. Каждая строка `'article'` преобразуется в `{ type: 'article' }`, а элементы без `documentId` или `type` отбрасываются. ```ts gtPlugin({ sourceLocale: 'en', locales: ['es'], translateDocuments: [ { type: 'article' }, { documentId: 'homepage' }, 'page', // сокращённая запись для { type: 'page' } ], }); ``` `TranslateDocumentFilter` выглядит так: ```ts type TranslateDocumentFilter = { documentId?: string; // найти конкретный документ по _id type?: string; // найти все документы заданного типа схемы }; ``` Записи `type` также определяют, для каких типов схем включён [`showDocumentInternationalization`](#show-doc-i18n). ### `singletons` [#singletons] **Тип** `string[]` · **Необязательно** · **По умолчанию** `[]` ID документов, которые считаются синглтонами, например настройки сайта или навигация. ID их переведённых документов определяются с помощью [`singletonMapping`](#singleton-mapping). ### `singletonMapping` [#singleton-mapping] **Тип** `(sourceDocumentId: string, locale: string) => string` · **Необязательно** · **По умолчанию** `` `${sourceDocumentId}-${locale}` `` Сопоставляет ID исходного документа синглтона и локаль с ID документа переведённого синглтона. Значение по умолчанию задаётся детерминированно, поэтому `siteSettings` превращается в `siteSettings-es` для испанской локали. ```ts gtPlugin({ sourceLocale: 'en', locales: ['es'], singletons: ['siteSettings'], singletonMapping: (sourceDocumentId, locale) => `${sourceDocumentId}_${locale}`, }); ``` ### `showDocumentInternationalization` [#show-doc-i18n] **Тип** `boolean` · **Необязательно** · **По умолчанию** `true` Если задано значение `true`, плагин подключает `@sanity/document-internationalization` с языковыми бейджами, меню переводов и шаблонами документов для каждого языка. В качестве типов схемы он использует элементы `type` в [`translateDocuments`](#translate-documents), а в качестве поддерживаемых языков — `[sourceLocale, ...locales]`, поэтому этот параметр действует только тогда, когда `translateDocuments` включает типы документов. Типы документов, локализованные на месте с помощью internationalized arrays, исключаются автоматически. Установите `false`, чтобы управлять интернационализацией самостоятельно. ## Локализация на уровне полей [#field-level] Локализация на уровне полей хранит значения всех локалей в одном документе в виде internationalized array. Данные используют ту же структуру элементов `{ _key, _type, language, value }`, что и `sanity-plugin-internationalized-array`, поэтому существующему контенту internationalized array миграция не требуется. ### `internationalizedArray` [#internationalized-array] **Тип** `GTFieldLevelLocalizationConfig` · **Необязательно** Настраивает типы схем и компоненты ввода Studio, используемые для локализации на уровне полей. Идентификатор локали всегда берётся из `sourceLocale` и `locales`. ```ts type GTFieldLevelLocalizationConfig = { enabled?: boolean; // по умолчанию: false fieldTypes?: FieldLevelFieldType[]; // по умолчанию: ['string', 'text'] languageTitles?: Record; getLanguageTitle?: (locale: string) => string; typePrefix?: string; // по умолчанию: 'internationalizedArray' includeCompatibilityTypes?: boolean; // по умолчанию: true components?: { input?: ComponentType | false; item?: ComponentType | false; field?: ComponentType | false; }; }; type FieldLevelFieldType = | 'string' | 'text' | 'block' | { name: string; type: string; title?: string; of?: unknown[]; fields?: unknown[]; options?: Record; }; ``` Встроенные сокращения `fieldTypes` — `string`, `text` и `block` (Portable Text). Запись объекта определяет пользовательский генерируемый тип. `getLanguageTitle` имеет приоритет над `languageTitles`, если заданы оба. Каждый слот `components` принимает компонент Studio или `false`, чтобы использовать стандартный рендеринг Sanity. ### `fieldLevelLocalization` [#field-level-localization] **Тип** `GTFieldLevelLocalizationConfig` · **Необязательно** Описательный алиас для [`internationalizedArray`](#internationalized-array). ### `translationLevel` [#translation-level] **Тип** `'document' | 'internationalizedArray' | 'mixed'` · **Необязательно** · **По умолчанию** `'document'` Определяет, как переводятся совпадающие документы: * `'document'` создает один документ для каждой локали * `'internationalizedArray'` локализует настроенные поля на месте * `'mixed'` использует локализацию на уровне полей для [`fieldLevelDocuments`](#field-level-documents) и локализацию на уровне документа для всего остального ### `fieldLevelDocuments` [#field-level-documents] **Тип** `TranslateDocumentFilter[] | string[]` · **Необязательно** · **По умолчанию** `[]` Определяет типы документов, в которых используются интернационализированные массивы, если `translationLevel` имеет значение `'mixed'`. Поддерживает те же формы фильтра и сокращённую запись в виде строки, что и [`translateDocuments`](#translate-documents). ```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' }], }); ``` Затем используйте сгенерированные типы в своих схемах: ```ts defineField({ name: 'title', type: 'internationalizedArrayString', }); ``` ## Сопоставители полей [#field-matchers] `ignoreFields`, `dedupeFields` и `skipFields` принимают массив объектов `FieldMatcher`. Сопоставитель указывает поля с помощью выражения JSONPath `property` и при необходимости ограничивается одним исходным документом через `documentId`. ```ts type FieldMatcher = { documentId?: string | null; // ограничить до исходного документа по _id fields?: { property: string; // JSONPath-выражение, например $.slug type?: string; // необязательная подсказка типа схемы, например slug }[]; }; ``` ### `ignoreFields` [#ignore-fields] **Тип** `FieldMatcher[]` · **Необязательно** · **По умолчанию** `[]` Поля копируются из исходного документа в переведённый документ без отправки в API перевода. Используйте это для значений, которые должны оставаться одинаковыми во всех локалях, например для категорий или тегов. ```ts gtPlugin({ sourceLocale: 'en', locales: ['es'], ignoreFields: [ // Копировать категорию без изменений для всех документов { fields: [{ property: '$.category' }] }, // Копировать теги без изменений только для одного документа { documentId: 'homepage', fields: [{ property: '$.tags' }] }, ], }); ``` ### `dedupeFields` [#dedupe-fields] **Тип** `FieldMatcher[]` · **Необязательно** · **По умолчанию** `[]` Поля, скопированные из исходного значения и делающиеся уникальными за счёт добавления локали при первом создании переведённого документа. Обычно используются для slug. ```ts gtPlugin({ sourceLocale: 'en', locales: ['es', 'fr'], // "about" становится "about-es" и "about-fr" dedupeFields: [{ fields: [{ property: '$.slug', type: 'slug' }] }], }); ``` Для поля slug плагин обновляет значение `current` в объекте slug. Если редактор позже изменит переведённый slug, при последующих импортах это изменённое значение сохранится. ### `skipFields` [#skip-fields] **Тип** `FieldMatcher[]` · **Необязательно** · **По умолчанию** `[]` Поля, полностью исключаемые из переведённых документов. ```ts gtPlugin({ sourceLocale: 'en', locales: ['es'], skipFields: [ { fields: [{ property: '$.slug', type: 'slug' }] }, { documentId: 'homepage', fields: [{ property: '$.debugInfo' }] }, ], }); ``` ## Сериализация [#serialization] Плагин сериализует документы в HTML для перевода, а затем десериализует результат обратно в поля Sanity. Большинству проектов эти параметры не нужны. ### `additionalStopTypes` [#additional-stop-types] **Тип** `string[]` · **Необязательно** · **По умолчанию** `[]` Дополнительные типы схем, которые нужно сохранять без перевода в дополнение к [stop types по умолчанию](#stop-types). ```ts gtPlugin({ sourceLocale: 'en', locales: ['es'], additionalStopTypes: ['codeBlock', 'mux.video', 'mux.videoAsset'], }); ``` ### `additionalSerializers` [#additional-serializers] **Тип** `Partial` · **Необязательный** · **По умолчанию** `{}` Пользовательские сериализаторы, объединяемые с сериализаторами по умолчанию в соответствии со структурой компонентов `@portabletext/to-html` (`types`, `marks`, `block`, `list`, `listItem` и другие). Чаще всего используются для сериализации пользовательских `marks`. Для пользовательских `marks` оборачивайте результат в `attachGTData`, чтобы данные `mark` сохранялись при переводе. ```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')` кодирует `data` в формат base64 и записывает его в атрибут `data-gt-internal` первого элемента `html`, а затем возвращает обновлённый HTML. При импорте плагин считывает этот атрибут, чтобы заново создать определение метки. ```ts function attachGTData( html: string, data: Record, type: 'markDef' ): string; ``` ### `additionalDeserializers` [#additional-deserializers] **Тип** `CustomDeserializers` · **Необязательно** · **По умолчанию** `{}` Пользовательские десериализаторы, которые преобразуют переведённые HTML-элементы обратно в объекты Sanity, сопоставляя их по типу. ```ts type CustomDeserializers = { types?: Record< string, (element: HTMLElement) => Record | unknown[] >; } & Record; ``` ### `additionalBlockDeserializers` [#additional-block-deserializers] **Тип** `unknown[]` · **Необязательный** · **По умолчанию** `[]` Дополнительные правила десериализации блоков Portable Text, которые добавляются к встроенным правилам плагина. Каждое правило — это объект с методом `deserialize(node, next)`, соответствующий формату правил `@portabletext/block-tools`. ## Стандартные stop types [#stop-types] Эти типы схем сохраняются и никогда не отправляются на перевод. Чтобы добавить другие, используйте [`additionalStopTypes`](#additional-stop-types). ```ts const defaultStopTypes = [ 'reference', 'date', 'datetime', 'file', 'geopoint', 'image', 'number', 'crop', 'hotspot', 'boolean', 'url', 'color', 'code', ]; ``` Поля slug *по умолчанию не исключаются*, поэтому строковое значение `current` у slug переводится, если только вы не используете [`dedupeFields`](#dedupe-fields) или [`skipFields`](#skip-fields). ## Экспортируемые хелперы [#helpers] `gt-sanity` также экспортирует базовые компоненты для расширенной сериализации и пользовательских узлов документа. Большинству проектов они не нужны. * `TranslationsTab` — компонент вкладки документа для `structureTool`. См. [Настройка Sanity](/docs/integrations/sanity/guides/configuring-sanity#translations-tab). * `attachGTData` / `detachGTData` — прикрепляют и считывают закодированные данные mark, используемые пользовательскими serializers. * `BaseDocumentSerializer`, `BaseDocumentDeserializer`, `BaseDocumentMerger` — стандартные реализации сериализации, десериализации и merge. * `defaultStopTypes`, `customSerializers` — стандартные stop types и набор serializers. * `documentInternationalization` и его типы (`DocumentInternationalizationConfig`, `Language`, `Metadata`, `TranslationReference`) — реэкспортируются из `@sanity/document-internationalization`. ## Полный пример [#complete-example] ```ts title="sanity.config.ts" import { defineConfig } from 'sanity'; import { attachGTData, gtPlugin } from 'gt-sanity'; export default defineConfig({ plugins: [ gtPlugin({ // Обязательно sourceLocale: 'en', locales: ['es', 'fr', 'de', 'ja'], // Документы и поля languageField: 'language', translateDocuments: [{ type: 'article' }, { type: 'page' }], singletons: ['siteSettings', 'navigation'], singletonMapping: (id, locale) => `${id}_${locale}`, // Поведение полей ignoreFields: [{ fields: [{ property: '$.category' }] }], dedupeFields: [{ fields: [{ property: '$.slug', type: 'slug' }] }], skipFields: [{ fields: [{ property: '$.internalNotes' }] }], // Сериализация — только если настройки по умолчанию не подходят для вашей схемы additionalSerializers: { marks: { link: ({ value, children }) => attachGTData(`${children}`, value, 'markDef'), }, }, }), ], }); ```