# sanity: Plugin Configuration URL: https://generaltranslation.com/en-GB/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 serialisation and restored from the source document after translation.', optional: true, }, dedupeFields: { type: 'DedupeFields[]', description: 'Fields to exclude from translation, then initialise 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 determining 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 serialisation', optional: true, }, additionalSerializers: { type: 'Record', description: 'Custom HTML serialisers for block types', optional: true, }, additionalDeserializers: { type: 'Record', description: 'Custom HTML deserialisers', optional: true, }, additionalBlockDeserializers: { type: 'BlockDeserializer[]', description: 'Custom block-level deserialisers', 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, a 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 such as 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 in translations at all. Use this for fields such as SEO canonical URLs, source-only metadata, or slugs that editors should set manually for each 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 Filters 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' }, ], }); ``` ## Serialiser 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' }] }], // Serialisation - Do not use this unless you know what you are doing! additionalSerializers: { // Additional serialisers 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 * [Serialisation Guide](/docs/sanity/guides/serialization) - Custom serialisation