# General Translation Integrations: Vender en varios mercados
URL: https://generaltranslation.com/es/docs/integrations/shopify/guides/selling-in-markets.mdx
Docs index: https://generaltranslation.com/llms.txt
Description: Cómo asociar cada idioma con su propio mercado de Shopify y trasladar el carrito cuando los compradores cambian de idioma.

Shopify devuelve los precios, la moneda y la disponibilidad del mercado que selecciona el `country` indicado en `@inContext`. Las guías de localización usan un único mercado para todos los idiomas, así que al cambiar de idioma solo cambia el texto. Esta guía asocia cada idioma con su propio mercado, como hace la [tienda de ejemplo](https://gt-shopify-vercel.vercel.app), de modo que cada idioma muestre también los precios y la moneda de su mercado.

*Nota: El código amplía los módulos `proxy.ts` y `lib/i18n` de [Localizar una tienda de Shopify con Next.js](/docs/integrations/shopify/guides/localizing-nextjs).*

## Antes de empezar [#before-start]

* Completa [Localizar una tienda de Shopify con Next.js](/docs/integrations/shopify/guides/localizing-nextjs).
* Añade un mercado de Shopify para cada país que asocies a un idioma. Si almacenas las traducciones del catálogo en Shopify, publica cada idioma en su mercado.

Asociar idiomas con mercados es opcional. Para que los compradores puedan elegir un país independientemente del idioma, añade en su lugar un selector de país aparte y actualiza la identidad del comprador del carrito cada vez que cambie el país. (Consulta [Idioma y mercado](/docs/integrations/shopify/reference/locale-handling#language-market)).

## Asigna cada configuración regional a un mercado [#market-map]

Sustituye la función `getCommerceLocale`, pensada para un único mercado, por un mapa que asocie cada configuración regional a un país y un idioma de Shopify:

```ts title="lib/i18n/index.ts"
import type { CommerceLocale } from "@/lib/config/types";

// Cada idioma vende en un único mercado de Shopify, así que Shopify devuelve los precios y la moneda de ese mercado.
// La moneda siempre se obtiene de la respuesta de Shopify, nunca de esta tabla.
const markets: Record<string, CommerceLocale> = {
  en: { country: "US", language: "EN" },
  fr: { country: "FR", language: "FR" },
  ja: { country: "JP", language: "JA" },
  ko: { country: "KR", language: "KO" },
  id: { country: "ID", language: "ID" },
};

export function getCommerceLocale(locale: string): CommerceLocale {
  const market = markets[locale];
  if (!market) throw new Error(`No Shopify market for locale: ${locale}`);
  return market;
}
```

Cada país del mapa debe pertenecer a uno de los mercados de Shopify de la tienda, y cada idioma debe ser un `LanguageCode` de la Storefront API. (Consulta [Códigos de configuración regional](/docs/integrations/shopify/reference/locale-handling#locale-codes)).

No cambia nada más en las lecturas del catálogo, los manejadores de solicitud de Hydrogen ni en [`getRegion`](/docs/react/nextjs/reference/functions/get-region): ya leen `getCommerceLocale`, así que ahora cada configuración regional consulta su propio mercado y los getters con `"use cache"` guardan una entrada de caché por mercado. Al crear carritos nuevos, usa el país del mercado como `countryCode` del comprador.

## Mover el carrito entre mercados [#move-cart]

Un carrito conserva la moneda del país de su comprador. Los manejadores de solicitud del carrito de Hydrogen no incluyen ninguna acción para cambiar el país del comprador, así que, cuando la navegación a otra página puede cambiar el mercado, el proxy lee el país real del carrito y lo actualiza antes de que se renderice la página:

```ts title="lib/cart/request.ts"
const CART_COUNTRY_QUERY = gql(`#graphql
  query cartCountry($cartId: ID!) {
    cart(id: $cartId) {
      buyerIdentity { countryCode }
    }
  }
`);

const CART_COUNTRY_UPDATE_MUTATION = gql(`#graphql
  mutation cartCountryUpdate($cartId: ID!, $countryCode: CountryCode!) {
    cartBuyerIdentityUpdate(cartId: $cartId, buyerIdentity: { countryCode: $countryCode }) {
      cart { buyerIdentity { countryCode } }
      userErrors {
        message
      }
    }
  }
`);

export async function moveCartToMarket(
  request: Request,
  requestContext: ShopifyRequestContext,
): Promise<void> {
  const cartId = getCartId({ cookie: request.headers.get("cookie") ?? undefined });
  if (!cartId) return;
  const client = createRequestStorefrontClient(requestContext);
  const countryCode = requestContext.i18n.country;
  // Lee el carrito sin caché; puede que otra pestaña o sesión lo haya movido.
  const current = await client.graphql(CART_COUNTRY_QUERY, { variables: { cartId } });
  if (current.errors) throw new Error("Unable to read the cart's country");
  const cart = current.data?.cart;
  // Si el carrito ha caducado, lo gestiona el flujo de creación de carritos que ya incluye la plantilla.
  if (!cart || cart.buyerIdentity.countryCode === countryCode) return;

  const result = await client.graphql(CART_COUNTRY_UPDATE_MUTATION, {
    variables: { cartId, countryCode },
  });
  if (result.errors) throw new Error("Unable to update the cart's country");
  const updated = result.data.cartBuyerIdentityUpdate;
  if (
    !updated ||
    updated.userErrors.length > 0 ||
    updated.cart?.buyerIdentity.countryCode !== countryCode
  ) {
    throw new Error("The cart's country was not updated");
  }
}
```

En `proxy.ts`, ejecuta el traslado solo cuando el mercado pueda cambiar y establece la cookie de configuración regional únicamente cuando el traslado se haya completado correctamente. Esto sustituye la actualización de la cookie de la guía de Next.js:

```ts title="proxy.ts"
// Un cambio de idioma, o una vista de página sin la cookie de configuración regional, puede mover el carrito a otro mercado.
const marketMayChange = isPageNavigation && rememberedLocale !== locale;

// Después de que handleShopifyRoutes rechace la solicitud, antes de la respuesta de la página o de la cookie de configuración regional.
if (marketMayChange) {
  try {
    await moveCartToMarket(request, requestContext);
  } catch {
    // No renderices precios del nuevo mercado junto a un carrito de otro mercado.
    const failure = new NextResponse("Unable to switch the cart's market. Please reload to retry.", {
      status: 503,
      headers: { "Cache-Control": "no-store" },
    });
    // Es posible que la actualización haya llegado a Shopify aunque aquí haya fallado, así que se descarta la
    // configuración regional recordada; así, la siguiente navegación de página vuelve a leer el carrito.
    failure.cookies.delete(LOCALE_COOKIE_NAME);
    return failure;
  }
}

// En la respuesta. Solo se llega aquí si moveCartToMarket se completa correctamente.
if (marketMayChange) {
  response.cookies.set(LOCALE_COOKIE_NAME, locale, { path: "/", sameSite: "lax" });
}
```

Cómo se comporta la comprobación:

* **Coste.** La navegación dentro de un mismo idioma omite la comprobación. Un cambio de idioma, o una visita sin la cookie, añade una lectura del carrito sin caché, y una mutación solo cuando los países no coinciden. No almacenes en caché la consulta del país del carrito.
* **Fallos.** Los fallos de red, los errores de GraphQL y los `userErrors` de la mutación devuelven un 503 en lugar de renderizar precios del nuevo mercado junto a un carrito del mercado anterior. Como la comprobación solo se ejecuta al cambiar de mercado, una caída del carrito de Shopify impide cambiar de idioma, pero no navegar.
* **Recuperación.** La cookie de configuración regional solo se establece tras un traslado correcto. Un traslado fallido, incluso uno que llegó a Shopify pero cuya respuesta se perdió, elimina la cookie, de modo que la siguiente navegación de página, en cualquier idioma, vuelve a leer el carrito. La cookie sigue siendo un indicio, no una prueba, del país del carrito: si el país se cambia fuera de este proxy, se corrige en el siguiente cambio de idioma o en la siguiente visita sin la cookie.

Shopify recalcula los precios de las líneas del carrito tras actualizar correctamente el país. El [selector de idioma](/docs/integrations/shopify/guides/localizing-nextjs#routing) navega con una carga de página completa, por lo que el proxy detecta cada cambio.

## Next steps

- /docs/integrations/shopify/guides/localizing-nextjs
- /docs/integrations/shopify/guides/translating-products
- /docs/integrations/shopify/guides/localizing-react-router

## Sitemap

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