Cómo resolver: Error de CORS al consumir APIs externas desde plantillas de Shopify
Cuando realizas una petición fetch() o axios desde el archivo JavaScript de un tema de Shopify (theme.liquid o secciones storefront) hacia tu API externa, el navegador bloquea la respuesta con el error: Access to fetch at 'https://mi-api.com' from origin 'https://mi-tienda.myshopify.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
El Diagnóstico Rápido
Cuando realizas una petición fetch() o axios desde el archivo JavaScript de un tema de Shopify (theme.liquid o secciones storefront) hacia tu API externa, el navegador bloquea la respuesta con el error: Access to fetch at 'https://mi-api.com' from origin 'https://mi-tienda.myshopify.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
La Solución Paso a Paso
Paso 1: Configurar las cabeceras CORS en tu servidor Backend
La solución directa consiste en permitir que el dominio de tu tienda Shopify consulte tu servidor. Si usas Node.js con Express:
import cors from 'cors';
import express from 'express';
const app = express();
// Configurar orígenes permitidos (tu dominio myshopify y dominio personalizado)
const allowedOrigins = [
'https://mi-tienda.myshopify.com',
'https://www.mi-tienda.com'
];
app.use(cors({
origin: function(origin, callback) {
if (!origin || allowedOrigins.indexOf(origin) !== -1) {
callback(null, true);
} else {
callback(new Error('Bloqueado por CORS'));
}
},
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
allowedHeaders: ['Content-Type', 'Authorization'],
credentials: true
}));
Paso 2: Utilizar Shopify App Proxies (Solución recomendada para apps)
Si estás desarrollando una aplicación o deseas evitar problemas de CORS y proteger tus credenciales de backend, utiliza los Application Proxies de Shopify:
-
1
Paso 1
En tu Shopify Partner Dashboard > App Setup > App Proxy, configura una ruta proxy comoapps/mi-proxy. -
2
Paso 2
Redirige esa ruta hacia la URL pública de tu backend:https://mi-api.com/api/. -
3
Paso 3
En el código Liquid/JS de tu tienda, realiza la petición directamente a la misma URL de la tienda:
// La petición se hace al mismo origen, eliminando el bloqueo CORS por completo
fetch('/apps/mi-proxy/obtener-datos', {
method: 'GET',
headers: { 'Content-Type': 'application/json' }
})
.then(res => res.json())
.then(data => console.log('Datos recibidos:', data));
Paso 3: Validar la respuesta preflight (OPTIONS)
Asegúrate de que tu servidor responda con código HTTP 200 OK o 204 No Content a las peticiones con método OPTIONS que los navegadores envían antes de enviar datos en formato JSON (application/json).
❓ Preguntas Frecuentes (FAQ)
¿Se pueden configurar cabeceras CORS directamente dentro del código Liquid?
No. Liquid es un lenguaje de plantillas que se renderiza en los servidores de Shopify para generar HTML estático. Las peticiones CORS ocurren del lado del navegador del cliente hacia tu servidor externo.
¿Por qué App Proxy es más seguro que CORS abierto?
Porque Shopify firma criptográficamente cada petición del App Proxy con un parámetro signature (HMAC SHA-256), permitiendo a tu backend verificar con certeza que la petición proviene legítimamente de tu tienda.
Consejo de Prevención
Prácticas de seguridad recomendadas:
- No uses Access-Control-Allow-Origin: * si manejas datos privados: Permitir todos los orígenes con asterisco (
*) inhabilita el envío de cookies/tokens de autenticación (credentials: true) y expone tus endpoints a abusos desde cualquier sitio web. - Comprueba el protocolo HTTPS: Shopify fuerza HTTPS. Cualquier intento de conectar con
http://fallará por políticas de seguridad de contenido mixto del navegador.