# sanity: Configuration
URL: https://generaltranslation.com/en-GB/docs/sanity/guides/configuration.mdx
---
title: Configuration
description: Configure the gt-sanity plugin for your Sanity project
---
## Overview
The `gtPlugin` function accepts a configuration object to customise translation behaviour, locale settings, and document handling.
```typescript title="sanity.config.ts"
import { gtPlugin } from 'gt-sanity';
export default defineConfig({
plugins: [
gtPlugin({
sourceLocale: 'en',
locales: ['es', 'zh', 'ja'], // Replace with your target locales
languageField: 'language',
singletons: ['siteSettings', 'navigation'],
}),
],
});
```
## Basic configuration
### Source and target locales
Define your source language and target locales:
```typescript
gtPlugin({
sourceLocale: 'en', // Source language for content
locales: ['es', 'zh', 'ja'], // Target languages for translation
});
```
### Using `defaultLocale` from `gt.config.json`
If you already have a `gt.config.json` (for example, from using `gt-next` or `gt-react`), you can spread it directly into the plugin configuration. The `defaultLocale` field is accepted as an alias for `sourceLocale`:
```typescript
import gtConfig from './gt.config.json';
gtPlugin({
...gtConfig, // { defaultLocale: 'en', locales: ['es', 'zh', 'ja'] }
});
```
If both `sourceLocale` and `defaultLocale` are provided, `sourceLocale` takes precedence.
### Language field
Specify which field stores the document's locale. Defaults to `'language'`:
```typescript
gtPlugin({
sourceLocale: 'en',
locales: ['es', 'zh', 'ja'],
languageField: 'locale', // By default, documents use the 'language' field. Here we use 'locale' instead.
});
```
## Document filtering
### Translate specific document types
Limit translation to specific document types:
```typescript
gtPlugin({
sourceLocale: 'en',
locales: ['es', 'zh', 'ja'],
translateDocuments: [{ type: 'page' }, { type: 'post' }],
});
```
### Translate specific documents
Target specific document IDs:
```typescript
gtPlugin({
sourceLocale: 'en',
locales: ['es', 'zh', 'ja'],
translateDocuments: [
{ documentId: 'homepage' },
{ documentId: 'about-page' },
],
});
```
## Singleton documents
Singletons are Sanity documents that exist as a single instance with translated variants. Configure how translated versions are named:
```typescript
gtPlugin({
sourceLocale: 'en',
locales: ['es', 'zh', 'ja'],
singletons: ['siteSettings', 'navigation', 'footer'], // List of singleton document IDs
singletonMapping: (docId, locale) => `${docId}-${locale}`, // Optional function to customise the ids of the translated singleton documents
});
```
By default, translations for singletons will have randomly generated ids unless `singletonMapping` is provided.
## Ignoring fields
Fields you don't want translated or sent to the GT API, but that should still be copied across from the source document to the translation. Ignored fields are stripped before serialisation (so the content is never sent to the API), then restored from the source document after the translated document is created.
Use `ignoreFields` for fields like categories, tags, or internal metadata that should have the same value on both the source and translated documents but don't need translation:
```typescript
gtPlugin({
sourceLocale: 'en',
locales: ['es', 'zh', 'ja'],
ignoreFields: [
{ fields: [{ property: '$.category' }] }, // same category across all languages
{ fields: [{ property: '$..linkType' }] }, // internal link metadata
{ fields: [{ property: '$..frequencies.default' }] },
],
});
```
`property` is a [JSONPath](https://goessner.net/articles/JsonPath/) expression that matches one or more fields in documents.
`type` is an optional parameter to further filter the fields to ignore to specific types.
## Deduplicating fields
Fields you don't want translated or sent to the GT API, but that should still be copied from the source document and made unique when a translated document is first created. Dedupe fields are stripped before serialisation, then restored from the source document with the target locale appended.
Use `dedupeFields` for Sanity slugs or other string-like identifiers that should remain based on the source value but must be unique for each language:
```typescript
gtPlugin({
sourceLocale: 'en',
locales: ['es', 'zh', 'ja'],
dedupeFields: [
{ fields: [{ property: '$.slug', type: 'slug' }] }, // "about" becomes "about-es"
],
});
```
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.
## Skipping fields
Fields that shouldn't be copied automatically to translated documents at all. Unlike `ignoreFields` (which preserves the source value in the translation), `skipFields` removes the matched fields entirely from the translated document.
Use `skipFields` for fields such as SEO canonical URLs, source-only metadata, or slugs that editors should set manually for each language:
```typescript
gtPlugin({
sourceLocale: 'en',
locales: ['es', 'zh', 'ja'],
skipFields: [
{ fields: [{ property: '$.slug', type: 'slug' }] }, // editors set slugs manually per language
{ fields: [{ property: '$.canonicalUrl' }] }, // only relevant on source
{
documentId: 'homepage',
fields: [{ property: '$.debugInfo' }], // source-only debug data
},
],
});
```
## Serialisation options
Extend the default serialisation behaviour:
```typescript
import { attachGTData, gtPlugin } from 'gt-sanity';
gtPlugin({
sourceLocale: 'en',
locales: ['es', 'zh', 'ja'],
additionalSerializers: {
// Additional serialisers for marks (custom annotations)
marks: {
link: ({ value, children }) =>
attachGTData(`${children}`, value, 'markDef'),
inlineMath: ({ value, children }) =>
attachGTData(`${children}`, value, 'markDef'),
},
},
});
```
See the [Serialisation Guide](/docs/sanity/guides/serialization) for details.
## Complete example
```typescript title="sanity.config.ts"
import { defineConfig } from 'sanity';
import { gtPlugin } from 'gt-sanity';
export default defineConfig({
name: 'default',
title: 'My Project',
projectId: 'your-project-id',
dataset: 'production',
plugins: [
gtPlugin({
sourceLocale: 'en',
locales: ['es', 'fr', 'de', 'ja', 'zh'],
languageField: 'language',
singletons: ['siteSettings', 'navigation'],
translateDocuments: [{ type: 'article' }, { type: 'page' }],
ignoreFields: [
{
fields: [{ property: '$.publishedAt' }],
},
],
dedupeFields: [
{
fields: [{ property: '$.slug', type: 'slug' }],
},
],
skipFields: [
{
fields: [{ property: '$.internalNotes' }],
},
],
}),
],
schema: {
types: schemaTypes,
},
});
```
## Next steps
* [Serialisation Guide](/docs/sanity/guides/serialization) - Custom serialisation rules
* [API Reference](/docs/sanity/api/plugin-config) - Full configuration options