# General Translation Integrations: Tradurre i prodotti Shopify
URL: https://generaltranslation.com/it/docs/integrations/shopify/guides/translating-products.mdx
Docs index: https://generaltranslation.com/llms.txt
Description: Come tradurre i contenuti dei prodotti Shopify con General Translation e archiviarli in Shopify oppure includerli nel bundle del tuo storefront.

I titoli, le descrizioni e le opzioni dei prodotti provengono da Shopify, non dal tuo codice, quindi `gt-react` e `gt-next` non li traducono. Traducili una sola volta e servili da una delle due posizioni disponibili.

## Cosa usare e quando [#choosing]

* **Archivia le traduzioni in Shopify** se i merchant modificano spesso il catalogo. Uno script registra le traduzioni tramite l&#39;Admin API, gli storefront le leggono con `@inContext(language:)` e le modifiche al catalogo non richiedono una nuova build dello storefront.
* **Includi le traduzioni nel bundle dello storefront** se non hai accesso a Shopify Admin oppure vuoi che le traduzioni del catalogo vengano revisionate e distribuite insieme al codice. La CLI traduce un file JSON esportato nella stessa esecuzione dei tuoi testi. Lo storefront di esempio usa questo approccio.

*Nota: nella Dashboard non è disponibile una connessione Shopify ospitata. In entrambi i casi, l&#39;esportazione la esegui tu, con le tue credenziali Shopify e General Translation.*

## a) Archiviare le traduzioni in Shopify [#store-in-shopify]

Shopify archivia una traduzione per ciascun campo di una risorsa, per ogni impostazione regionale. Uno script esporta il testo di origine tramite l&#39;Admin API, lo traduce con [`translateMany`](/docs/platform/core/reference/gt-class-methods/translation/translate-many) e registra nuovamente i risultati in Shopify.

### Prima di iniziare

Ti servono:

* Le lingue di destinazione aggiunte e pubblicate nel pannello di amministrazione di Shopify, in **Settings &gt; Languages**.
* Un token di accesso alla Shopify Admin API generato da un&#39;app installata nello store, con gli ambiti `read_translations`, `write_translations` e `read_locales`. Un token della Storefront API non può scrivere traduzioni.
* `generaltranslation` installato e una chiave API di progetto con il permesso **Runtime translation** (`project:translations:generate`). (Consulta l&#39;[Avvio rapido](/docs/platform/core/quickstart) della libreria principale).

Conserva il token Admin e la chiave API nell&#39;ambiente del tuo script. Non aggiungerli mai all&#39;ambiente dello storefront né ai bundle del browser.

### Esportare il contenuto di origine

Esegui una query su `translatableResources` per ogni tipo di risorsa da tradurre. Ogni campo restituisce la propria `key`, il `value` di origine e un `digest` che identifica in modo univoco quel preciso testo di origine.

```graphql title="Admin API"
query CatalogExport($type: TranslatableResourceType!, $after: String) {
  translatableResources(first: 50, after: $after, resourceType: $type) {
    nodes {
      resourceId
      translatableContent { key value digest locale }
      translations(locale: "fr") { key value outdated }
    }
    pageInfo { hasNextPage endCursor }
  }
}
```

Usa tipi di risorsa come `PRODUCT`, `PRODUCT_OPTION` e `PRODUCT_OPTION_VALUE` e scorri i risultati pagina per pagina con `endCursor`. Conserva i digest: ti serviranno per registrare le traduzioni.

### Tradurre con General Translation

Invia a [`translateMany`](/docs/platform/core/reference/gt-class-methods/translation/translate-many) i campi in testo semplice, come titoli e tipi di prodotto, titoli e descrizioni SEO, nomi e valori delle opzioni. Aggiungi [`metadata.context`](/docs/platform/core/reference/types/entry-metadata#context) per far sì che anche le etichette brevi vengano tradotte correttamente.

```ts title="scripts/translate-catalog.ts"
import { GT } from 'generaltranslation';

const gt = new GT({
  apiKey: process.env.GT_API_KEY,
  projectId: process.env.GT_PROJECT_ID,
  sourceLocale: 'en',
});

const results = await gt.translateMany(
  fields.map((field) => ({
    source: field.value,
    metadata: {
      context: `Shopify ${field.resourceType} ${field.key}. Preserve product brand names, measurements, and model numbers.`,
    },
  })),
  { sourceLocale: 'en', targetLocale: 'fr' }
);
```

I risultati vengono restituiti nello stesso ordine dell&#39;input e per ciascuno viene indicato separatamente l&#39;esito positivo o negativo. Riprova a inviare le voci non riuscite invece di registrarle.

I campi in testo ricco, come il `body_html` di un prodotto, contengono HTML. La traduzione basata sul formato tramite [`metadata.fileFormat`](/docs/platform/core/reference/types/entry-metadata#file-format) supporta solo documenti Markdown e MDX, quindi non inviare HTML grezzo a [`translateMany`](/docs/platform/core/reference/gt-class-methods/translation/translate-many) senza prima prevedere un passaggio che ne preservi il markup.

### Registrare le traduzioni in Shopify

Salva ogni traduzione con la mutation [`translationsRegister`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/translationsRegister) dell&#39;Admin API. Passa il digest del contenuto sorgente come `translatableContentDigest`: in questo modo Shopify rifiuterà qualsiasi traduzione il cui contenuto sorgente sia cambiato dopo l&#39;esportazione.

```graphql title="Admin API"
mutation CatalogRegister($resourceId: ID!, $translations: [TranslationInput!]!) {
  translationsRegister(resourceId: $resourceId, translations: $translations) {
    translations { key locale value outdated }
    userErrors { field code }
  }
}
```

```json title="Variables"
{
  "resourceId": "gid://shopify/Product/123",
  "translations": [
    {
      "locale": "fr",
      "key": "title",
      "value": "Sweat à capuche en coton",
      "translatableContentDigest": "<digest from export>"
    }
  ]
}
```

Per `locale` usa il codice locale di Shopify, che può differire da quello di General Translation. (Vedi [Codici locale](/docs/integrations/shopify/reference/locale-handling#locale-codes)).

<Callout type="warn">
  `translationsRegister` sostituisce la traduzione esistente per quella chiave e impostazione regionale, comprese le traduzioni inserite da un merchant nel pannello di amministrazione o scritte da un&#39;altra app. Prima di scrivere, confronta la traduzione attuale con il valore registrato dal tuo script l&#39;ultima volta e salta i campi che non hai scritto tu.
</Callout>

### Leggere le traduzioni nello storefront

Aggiungi `@inContext(language: $language)` alle query del catalogo e passa il `LanguageCode` di Shopify corrispondente all&#39;impostazione regionale. Shopify restituisce il valore tradotto, se disponibile, altrimenti il valore di origine. Il client Storefront di Hydrogen ricava `$language` dal proprio contesto della richiesta. (Consulta [Localizzare Shopify Hydrogen con React Router](/docs/integrations/shopify/guides/localizing-react-router#storefront-language)).

I contenuti tradotti del catalogo compaiono non appena le cache di Shopify e dello storefront vengono aggiornate, senza bisogno di un&#39;ulteriore distribuzione.

### Mantenere aggiornate le traduzioni

Quando un merchant modifica un prodotto, il digest dei suoi campi cambia e Shopify contrassegna le traduzioni esistenti come `outdated`. Riesegui l&#39;esportazione, traduci solo i campi con un digest modificato o privi di traduzione, quindi registra i risultati.

## b) Includere le traduzioni nel bundle dello storefront [#bundle]

*Nota: questi esempi sono tratti dallo storefront di esempio di Next.js, che usa la configurazione delle impostazioni regionali descritta nella [guida di Next.js](/docs/integrations/shopify/guides/localizing-nextjs).*

Esporta il testo del catalogo tramite la Storefront API, usando come chiave il testo di origine stesso. Salva le etichette brevi (titoli, nomi e valori delle opzioni, testo alternativo) e il testo ricco (descrizioni, contenuto delle pagine) in file separati, così che al browser arrivino solo le etichette. Sanifica il testo ricco nello stesso modo in cui lo storefront lo renderizza, in modo che le chiavi corrispondano:

```ts title="scripts/export-catalog.ts"
const labels = new Set<string>();
const content = new Set<string>();
for (const product of catalog.products.nodes) {
  labels.add(product.title).add(product.productType);
  content.add(product.description).add(sanitizeShopifyHtml(product.descriptionHtml));
  for (const image of product.images.nodes) if (image.altText) labels.add(image.altText);
  for (const option of product.options) {
    labels.add(option.name);
    for (const value of option.optionValues) labels.add(value.name);
  }
}

async function writeCatalog(file: string, texts: Set<string>): Promise<number> {
  const entries = [...texts].filter((text) => text.trim()).sort((a, b) => a.localeCompare(b, "en"));
  await writeFile(
    new URL(`../catalog/en/${file}`, import.meta.url),
    `${JSON.stringify(Object.fromEntries(entries.map((text) => [text, text])), null, 2)}\n`,
  );
  return entries.length;
}
```

Aggiungi i file esportati sotto `files.json` in `gt.config.json`, accanto alla voce `files.gt` già presente, così che [`npx gt translate`](/docs/cli/reference/commands/translate) generi `catalog/<locale>/labels.json` e `catalog/<locale>/content.json` nella stessa esecuzione in cui traduce i tuoi testi:

```json title="gt.config.json"
{
  "files": {
    "json": { "include": ["catalog/[locale]/labels.json", "catalog/[locale]/content.json"] }
  }
}
```

Cerca le traduzioni in base al testo di origine attuale e usa quest&#39;ultimo come fallback, così qualsiasi contenuto modificato in Shopify dopo l&#39;ultima esportazione mostrerà il testo aggiornato:

```ts title="lib/catalog/index.ts"
/** Cerca il testo del commerciante in base alla sorgente inglese attuale e, se non esiste una traduzione, ripiega sulla sorgente stessa. */
export function translateCatalogText(catalog: Catalog, text: string): string;
export function translateCatalogText(catalog: Catalog, text: string | undefined): string | undefined;
export function translateCatalogText(catalog: Catalog, text: string | undefined) {
  return (text && catalog[text]) || text;
}
```

```ts title="lib/catalog/server.ts"
/** Etichette brevi (titoli, nomi e valori delle opzioni, testo alternativo) per i componenti client come il carrello. */
export function getCatalogLabels(locale: string): Catalog {
  return catalogs[locale]?.labels ?? {};
}

/** Restituisce una funzione di traduzione per i testi del merchant Shopify nell'impostazione regionale della richiesta. */
export async function getCatalogText() {
  const catalog = catalogs[await getLocale()];
  const merged: Catalog = catalog ? { ...catalog.content, ...catalog.labels } : {};
  function ct(text: string): string;
  function ct(text: string | undefined): string | undefined;
  function ct(text: string | undefined) {
    return translateCatalogText(merged, text);
  }
  return ct;
}
```

* Passa il testo tradotto a [`<T>`](/docs/react/reference/components/t) tramite [`<Var>`](/docs/react/reference/components/var), non come testo sorgente.
* Per i componenti client come il carrello e la ricerca predittiva, passa `getCatalogLabels(locale)` a un provider di contesto nel layout. Non inviare al browser testo ricco né i cataloghi delle altre impostazioni regionali.
* Mantieni i valori delle opzioni nella lingua sorgente ovunque servano a selezionare una variante, costruire un URL o comunicare con Shopify. Traduci solo l&#39;etichetta visualizzata.
* Per orientare la traduzione dei nomi dei prodotti, ad esempio per mantenere invariati i termini del brand o tradurre il nome di un capo d&#39;abbigliamento, aggiungi termini del Glossario e Prompt Personalizzati al gruppo di contesto del progetto nella dashboard.

## Next steps

- /docs/integrations/shopify/guides/localizing-react-router
- /docs/integrations/shopify/guides/localizing-nextjs
- /docs/integrations/shopify/guides/selling-in-markets

## Sitemap

See the full [sitemap](https://generaltranslation.com/sitemap.md) for all pages.
