# sanity: Configuration
URL: https://generaltranslation.com/en-US/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 customize translation behavior, 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` (e.g. from using `gt-next` or `gt-react`), you can spread it directly into the plugin config. 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 '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 customize 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 over from the source document to the translation. Ignored fields are stripped before serialization (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.
## Skipping fields
Fields that shouldn't be automatically copied over to translated documents at all. Unlike `ignoreFields` (which preserves the source value on the translation), `skipFields` removes the matched fields entirely from the translated document.
Use `skipFields` for fields like unique document slugs, SEO canonical URLs, or source-only metadata that should not exist on translations — either because they need to be set independently per language or because they only apply to the source:
```typescript
gtPlugin({
sourceLocale: 'en',
locales: ['es', 'zh', 'ja'],
skipFields: [
{ fields: [{ property: '$.slug', type: 'slug' }] }, // slugs should be unique per language
{ fields: [{ property: '$.canonicalUrl' }] }, // only relevant on source
{
documentId: 'homepage',
fields: [{ property: '$.debugInfo' }], // source-only debug data
},
],
});
```
## Serialization options
Extend the default serialization behavior:
```typescript
import { attachGTData, gtPlugin } from 'gt-sanity';
gtPlugin({
sourceLocale: 'en',
locales: ['es', 'zh', 'ja'],
additionalSerializers: {
// Additional serializers for marks (custom annotations)
marks: {
link: ({ value, children }) =>
attachGTData(`${children}`, value, 'markDef'),
inlineMath: ({ value, children }) =>
attachGTData(`${children}`, value, 'markDef'),
},
},
});
```
See the [Serialization 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: 'slug' }, { property: 'publishedAt' }],
},
],
skipFields: [
{
fields: [{ property: '$.internalNotes' }],
},
],
}),
],
schema: {
types: schemaTypes,
},
});
```
## Next steps
- [Serialization Guide](/docs/sanity/guides/serialization) - Custom serialization rules
- [API Reference](/docs/sanity/api/plugin-config) - Full configuration options