Aller au contenu

Translations

The translation system allows you to store and retrieve content in multiple languages. This is essential for building internationalized applications.

Translations work by:

  1. Marking fields as localizable: true in your DTO
  2. Automatically adding a locale parameter to queries and mutations
  3. Exposing a translations field in queries to retrieve all translations
  4. Accepting a translations array in mutations to create/update translations

To enable translations on a field, use the localizable option in @EnhancedField:

import { EnhancedField, IDField } from '@lib/type-graphql-query';
import { ObjectType, ID, Field } from '@lib/type-graphql';
@ObjectType('Product')
export class Product {
@IDField(() => ID)
id!: string;
@EnhancedField({ localizable: true })
name!: string;
@EnhancedField({ localizable: true })
description!: string;
@EnhancedField()
price!: number;
}

When you query a record, you can specify a locale parameter to get the translated values:

GraphQL:

{
products(locale: "fr") {
edges {
node {
id
name # Returns French translation
description # Returns French translation
price
}
}
}
}

Response:

{
"data": {
"products": {
"edges": [
{
"node": {
"id": "1",
"name": "Œufs Premium",
"description": "Œufs de haute qualité",
"price": 15.99
}
}
]
}
}
}

You can retrieve all translations for a record using the translations field:

GraphQL:

{
product(id: "1") {
id
name
description
translations {
locale
name
description
}
}
}

Response:

{
"data": {
"product": {
"id": "1",
"name": "Premium Eggs",
"description": "High quality eggs",
"translations": [
{
"locale": "fr",
"name": "Œufs Premium",
"description": "Œufs de haute qualité"
},
{
"locale": "en",
"name": "Premium Eggs",
"description": "High quality eggs"
},
{
"locale": "mg",
"name": "Atody Premium",
"description": "Atody kalitao avo lenta"
}
]
}
}
}

When creating a record, you can provide translations using the translations field:

GraphQL:

mutation {
createOneProduct(
input: {
product: {
price: 15.99
translations: [
{ locale: "fr", name: "Œufs Premium", description: "Œufs de haute qualité" }
{ locale: "en", name: "Premium Eggs", description: "High quality eggs" }
{ locale: "mg", name: "Atody Premium", description: "Atody kalitao avo lenta" }
]
}
}
) {
id
name
description
price
}
}

You can update translations using the updateOne mutation:

GraphQL:

mutation {
updateOneProduct(
input: {
id: "1"
update: {
translations: [
{ locale: "fr", name: "Œufs Premium Mis à Jour", description: "Description mise à jour" }
]
}
}
) {
id
name
description
}
}

All mutations accept an optional locale parameter that serves as the default locale:

GraphQL:

mutation {
createOneProduct(input: { product: { name: "Premium Eggs", price: 15.99 } }, locale: "fr") {
id
name
price
}
}

When locale is provided, it will be used as the default locale for any localizable fields that don’t have explicit translations in the translations array.

The translation input type is automatically generated based on your DTO’s localizable fields. You must use TranslationInputType to get the type for your input DTOs:

import { TranslationInputType, Translation } from '@lib/type-graphql-query';
import { Product } from './product.type';
import { InputType, Field } from '@lib/type-graphql';
// Get the automatically generated translation input type
const ProductTranslationInput = TranslationInputType(Product);
@InputType()
export class ProductInput {
@Field()
price!: number;
@Field(() => [ProductTranslationInput], { nullable: true, defaultValue: [] })
translations?: Translation<Product, 'name' | 'description'>[];
}

The translation input type includes:

  • All fields marked with localizable: true from your DTO
  • A locale field (required)

For better TypeScript type safety, you can use the Translation<DTO, Fields> type:

import { Translation } from '@lib/type-graphql-query';
// Specify which fields are localizable for better type checking
type ProductTranslation = Translation<Product, 'name' | 'description'>;
@InputType()
export class ProductInput {
@Field(() => [ProductTranslationInput], { nullable: true })
translations?: ProductTranslation[];
}

Supported locales are configured when building your schema:

import { buildTypeDefsAndResolvers } from '@lib/type-graphql-query';
const { resolvers, typeDefs } = await buildTypeDefsAndResolvers({
supportedLocales: ['fr', 'en', 'mg'],
defaultLocale: 'mg',
// ... other options
});
  1. Mark appropriate fields as localizable - Only mark user-facing text fields, not IDs or technical fields
  2. Provide translations for all locales - Ensure all required locales have translations
  3. Use locale parameter as fallback - The locale parameter provides a default when translations are missing
  4. Query translations when needed - Use the translations field when you need all language versions
  5. Update translations atomically - Update all translations in a single mutation when possible
  • DTOs - Configure localizable fields
  • Queries - Query operations with locale
  • Mutations - Mutations with translations