# sanity: Plugin Configuration URL: https://generaltranslation.com/en-US/docs/sanity/api/plugin-config.mdx --- title: Plugin Configuration description: API reference for gtPlugin configuration options --- ## Overview The `gtPlugin` function configures General Translation for your Sanity Studio. ```typescript import { gtPlugin } from 'gt-sanity' gtPlugin(config: GTPluginConfig) ``` ## GTPluginConfig string', description: 'Function to generate translated singleton IDs. Default: "${docId}-${locale}"', optional: true, }, ignoreFields: { type: 'IgnoreFields[]', description: 'Fields to exclude from translation. Matched fields are stripped before serialization and restored from the source document after translation.', optional: true, }, dedupeFields: { type: 'DedupeFields[]', description: 'Fields to exclude from translation, then initialize from the source document with the target locale appended when creating a translated document.', optional: true, }, skipFields: { type: 'SkipFields[]', description: 'Fields to remove entirely from translated documents. Unlike ignoreFields, these fields will not appear on the translated document at all.', optional: true, }, translateDocuments: { type: "TranslateDocumentFilter[] | string[]", description: 'Filter which documents can be translated. Accepts an array of filter objects or a shorthand array of document type strings.', optional: true, }, secretsNamespace: { type: 'string', description: 'Namespace for credentials document. Default: "generaltranslation"', optional: true, }, additionalStopTypes: { type: 'string[]', description: 'Additional types to skip during serialization', optional: true, }, additionalSerializers: { type: 'Record', description: 'Custom HTML serializers for block types', optional: true, }, additionalDeserializers: { type: 'Record', description: 'Custom HTML deserializers', optional: true, }, additionalBlockDeserializers: { type: 'BlockDeserializer[]', description: 'Custom block-level deserializers', optional: true, }, customMapping: { type: "Record>", description: 'Custom locale mapping for non-standard locale codes', optional: true, }, showDocumentInternationalization: { type: 'boolean', description: 'When true (default), automatically adds the @sanity/document-internationalization plugin with language badges, translation menu, and per-language templates. Requires translateDocuments.', optional: true, }, }} /> ## IgnoreFields Fields that are not translated or sent to the API, but are copied over from the source document to the translation. Use this for fields like categories, tags, or internal metadata that should have the same value across all languages. ```typescript type IgnoreFields = { documentId?: string; fields?: Array<{ property: string; type?: string; }>; }; ``` ### Example ```typescript gtPlugin({ sourceLocale: 'en', locales: ['es'], ignoreFields: [ // Copy category as-is to all translated documents { fields: [{ property: '$.category' }], }, // Copy these fields as-is only for articles { documentId: 'article', fields: [{ property: '$.tags' }, { property: '$.author' }], }, ], }); ``` ## DedupeFields Fields that are not translated or sent to the API, but are copied from the source document with the target locale appended when a translated document is first created. Use this for fields that should start source-derived but unique per translated document, such as Sanity slugs. ```typescript type DedupeFields = { documentId?: string; fields?: Array<{ property: string; type?: string; }>; }; ``` ### Example ```typescript gtPlugin({ sourceLocale: 'en', locales: ['es', 'fr'], dedupeFields: [ // "about" becomes "about-es" and "about-fr" { fields: [{ property: '$.slug', type: 'slug' }], }, ], }); ``` For Sanity slug fields, the plugin updates the slug object's `current` value. For example, `{ _type: 'slug', current: 'about' }` becomes `{ _type: 'slug', current: 'about-es' }` when the Spanish document is created. If an editor later changes the translated slug, future translation imports preserve that edited value. ## SkipFields Fields that are removed entirely from translated documents. Unlike `ignoreFields`, these fields will not appear on translations at all. Use this for fields like SEO canonical URLs, source-only metadata, or slugs that editors should set manually per language. ```typescript type SkipFields = { documentId?: string; fields?: Array<{ property: string; type?: string; }>; }; ``` ### Example ```typescript gtPlugin({ sourceLocale: 'en', locales: ['es'], skipFields: [ // Editors will set slugs manually per language { fields: [{ property: '$.slug', type: 'slug' }], }, // Remove source-only debug data from homepage translations { documentId: 'homepage', fields: [{ property: '$.debugInfo' }], }, ], }); ``` ## TranslateDocumentFilter Filter which documents are available for translation: ```typescript type TranslateDocumentFilter = { documentId?: string; // Specific document ID type?: string; // Document type }; ``` ### Example ```typescript gtPlugin({ sourceLocale: 'en', locales: ['es'], translateDocuments: [ { type: 'article' }, { type: 'page' }, { documentId: 'homepage' }, ], }); ``` ## Serializer Custom function to convert a Sanity block to HTML: ```typescript type Serializer = (props: { value: any; isInline?: boolean; children?: string; }) => string; ``` ### Example ```typescript import { attachGTData, gtPlugin } from 'gt-sanity'; gtPlugin({ sourceLocale: 'en', locales: ['es'], additionalSerializers: { link: ({ value, children }) => attachGTData(`${children}`, value, 'markDef'), }, }); ``` ## Default stop types These types are preserved but not sent for translation: ```typescript const defaultStopTypes = [ 'reference', 'crossDatasetReference', 'date', 'datetime', 'file', 'geopoint', 'image', 'number', 'slug', 'url', ]; ``` Add more with `additionalStopTypes`: ```typescript gtPlugin({ sourceLocale: 'en', locales: ['es'], additionalStopTypes: ['codeBlock', 'mathFormula'], }); ``` ## Complete example ```typescript title="sanity.config.ts" import { defineConfig } from 'sanity'; import { attachGTData, gtPlugin } from 'gt-sanity'; export default defineConfig({ plugins: [ gtPlugin({ // Required sourceLocale: 'en', locales: ['es', 'fr', 'de', 'ja'], // Document handling languageField: 'language', singletons: ['siteSettings', 'navigation'], singletonMapping: (id, locale) => `${id}_${locale}`, // Filtering translateDocuments: [{ type: 'article' }, { type: 'page' }], ignoreFields: [{ fields: [{ property: '$.publishedAt' }] }], dedupeFields: [{ fields: [{ property: '$.slug', type: 'slug' }] }], skipFields: [{ fields: [{ property: '$.internalNotes' }] }], // Serialization - Do not use this unless you know what you are doing! additionalSerializers: { // Additional serializers for marks (custom annotations) marks: { link: ({ value, children }) => attachGTData(`${children}`, value, 'markDef'), inlineMath: ({ value, children }) => attachGTData(`${children}`, value, 'markDef'), }, }, }), ], }); ``` ## Next steps - [Configuration Guide](/docs/sanity/guides/configuration) - Configuration patterns - [Serialization Guide](/docs/sanity/guides/serialization) - Custom serialization