Saltar al contenido principal
8 min de lectura

Seguimiento de primera parte con Astro

Configura un proxy de primera parte en tu proyecto Astro usando rutas API. Funciona con modos estático y SSR.

Dificultad: Fácil - Agrega un archivo de ruta API a tu proyecto.

Por qué funciona (mismo origen)

Este enfoque utiliza /api/_z/script.js que está en el mismo origen que tu sitio web. Firefox ETP y otras protecciones de rastreo solo bloquean solicitudes entre orígenes.

  • El navegador ve: tudominio.com/api/_z/script.js — mismo origen, sin bloqueo entre orígenes
  • La ruta API de Astro proxifica la solicitud al servidor de Zenovay en el servidor (el navegador nunca ve esto)
  • Toda la protección de rastreo se evita porque la solicitud es de primera parte

Antes de empezar

Asegúrate de tener:

  • Un proyecto de Astro (v2.0+ recomendado)
  • Tu código de rastreo de Zenovay (encontrado en Dominios → tu dominio → General)
  • Adaptador SSR instalado (para Vercel, Netlify, Cloudflare, Node, etc.)

Formato de tu código de rastreo

Tu código de rastreo se ve así: ZV_XXXXXXXXXX

  • Comienza con ZV_
  • Seguido por 10 caracteres (letras y números)
  • SENSIBLE A MAYÚSCULAS - cópialo exactamente

Ejemplo: ZV_Q8U0GYD70WR

La tarjeta del script de rastreo que muestra el fragmento del script con pestañas HTML, React, Next.js y Primera parte
Encuentra tu código de rastreo en la pestaña de Primera parte en Dominios → tu dominio → General.

Sitios estáticos: Si estás usando output: 'static', las rutas API de Astro no funcionarán. Usa el proxy de tu plataforma de alojamiento en su lugar (reescrituras de Vercel, redirecciones de Netlify, etc.).


Paso 1: Habilitar SSR (si no lo está ya)

Primero, asegúrate de que tu proyecto Astro tenga SSR habilitado con un adaptador.

Para Vercel

TerminalBash
npm install @astrojs/vercel
astro.config.mjsJavaScript
import { defineConfig } from 'astro/config';
import vercel from '@astrojs/vercel/serverless';

export default defineConfig({
output: 'server', // o 'hybrid' para SSR parcial
adapter: vercel(),
});

Para Netlify

TerminalBash
npm install @astrojs/netlify
astro.config.mjsJavaScript
import { defineConfig } from 'astro/config';
import netlify from '@astrojs/netlify';

export default defineConfig({
output: 'server',
adapter: netlify(),
});

Para Cloudflare

TerminalBash
npm install @astrojs/cloudflare
astro.config.mjsJavaScript
import { defineConfig } from 'astro/config';
import cloudflare from '@astrojs/cloudflare';

export default defineConfig({
output: 'server',
adapter: cloudflare(),
});

Para Node.js

TerminalBash
npm install @astrojs/node
astro.config.mjsJavaScript
import { defineConfig } from 'astro/config';
import node from '@astrojs/node';

export default defineConfig({
output: 'server',
adapter: node({
  mode: 'standalone'
}),
});

Paso 2: Crear la ruta API del proxy

Crea una ruta API de captura que proxifique solicitudes a Zenovay:

src/pages/api/_z/[...path].tsTypeScript
import type { APIRoute } from 'astro'

export const ALL: APIRoute = async ({ params, request }) => {
// Construir la ruta desde el parámetro de captura
const path = params.path || ''
const url = new URL(request.url)
const targetUrl = `https://api.zenovay.com/fp/${path}${url.search}`

// Manejar solicitudes preflight CORS
if (request.method === 'OPTIONS') {
  return new Response(null, {
    status: 204,
    headers: {
      'Access-Control-Allow-Origin': '*',
      'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
      'Access-Control-Allow-Headers': 'Content-Type',
    },
  })
}

try {
  // Obtener la IP real del cliente para geolocalización exacta
  const clientIP = request.headers.get('x-forwarded-for')?.split(',')[0]
                || request.headers.get('cf-connecting-ip')
                || request.headers.get('x-real-ip')
                || ''

  // Construir encabezados del proxy
  const headers = new Headers()
  headers.set('Content-Type', request.headers.get('Content-Type') || 'application/json')
  headers.set('X-Zenovay-Real-IP', clientIP)

  // Reenviar la solicitud
  const response = await fetch(targetUrl, {
    method: request.method,
    headers: headers,
    body: request.method !== 'GET' ? await request.text() : undefined,
  })

  // Construir respuesta con encabezados CORS
  const responseHeaders = new Headers(response.headers)
  responseHeaders.set('Access-Control-Allow-Origin', '*')

  return new Response(response.body, {
    status: response.status,
    headers: responseHeaders,
  })
} catch (error) {
  console.error('Error del proxy:', error)
  return new Response(JSON.stringify({ error: 'Error del proxy' }), {
    status: 502,
    headers: { 'Content-Type': 'application/json' },
  })
}
}

¿Por qué [...path].ts? La sintaxis de expansión crea una ruta de captura que captura múltiples segmentos de ruta. Esto significa que /api/_z/script.js, /api/_z/e/CODE, y /api/_z/settings/CODE todas se enrutan a este único archivo.


Paso 3: Agregar el script de rastreo

Agrega el script de rastreo a tu maquetación:

src/layouts/Layout.astroASTRO
---
interface Props {
title: string;
}

const { title } = Astro.props;
---

<!doctype html>
<html lang="es">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>{title}</title>

  <!-- Análisis de Zenovay (Proxy de primera parte) -->
  <script defer data-tracking-code="TU_CÓDIGO_DE_RASTREO" src="/api/_z/script.js"></script>
</head>
<body>
  <slot />
</body>
</html>

Importante: Reemplaza TU_CÓDIGO_DE_RASTREO con tu código de rastreo real del panel de control de Zenovay.


Paso 4: Desplegar

Despliega tu proyecto Astro en tu plataforma elegida:

TerminalBash
# Construir el proyecto
npm run build

# Desplegar (depende de tu adaptador)
# Vercel: vercel deploy
# Netlify: netlify deploy --prod
# Cloudflare: wrangler pages deploy dist

Modo híbrido (recomendado)

Si la mayoría de tu sitio es estático pero necesitas el proxy, usa el modo híbrido:

astro.config.mjsJavaScript
import { defineConfig } from 'astro/config';
import vercel from '@astrojs/vercel/serverless';

export default defineConfig({
output: 'hybrid', // Estático por defecto, SSR para rutas específicas
adapter: vercel(),
});

Luego marca la ruta API para renderizado en el servidor:

src/pages/api/_z/[...path].tsTypeScript
// Forzar renderizado en el servidor para esta ruta
export const prerender = false;

import type { APIRoute } from 'astro'

export const ALL: APIRoute = async ({ params, request }) => {
// ... resto del código del proxy
}

Verificar que funciona

Revisar la pestaña de red

  1. Visita tu sitio desplegado
  2. Abre las herramientas de desarrollo (F12)
  3. Ve a la pestaña Red
  4. Recarga la página
  5. Busca /api/_z/script.js

Deberías ver:

  • Estado: 200
  • Dominio: Tu dominio
  • Respuesta: Código JavaScript

Probar en Firefox

  1. Abre Firefox
  2. Configuración → Privacidad y seguridad → Protección mejorada de rastreo: Estricta
  3. Visita tu sitio
  4. Verifica que el script cargue correctamente

Solución de problemas

Error 404 en la ruta API

Causa: SSR no habilitado o adaptador no configurado.

Solución:

  1. Asegúrate de tener output: 'server' o output: 'hybrid' en astro.config.mjs
  2. Verifica que tengas un adaptador instalado y configurado
  3. Para modo híbrido, agrega export const prerender = false; a la ruta API

Error 500

Causa: Error de sintaxis o problema en tiempo de ejecución en la ruta API.

Solución:

  1. Revisa los registros del servidor para mensajes de error detallados
  2. Asegúrate de que los tipos de TypeScript sean correctos
  3. Verifica que todas las importaciones estén disponibles

El script carga pero no hay datos

Causa: Falta de concordancia en el código de rastreo.

Solución:

  1. Verifica que data-tracking-code coincida con tu código en el panel de control de Zenovay
  2. Revisa la consola del navegador para errores de JavaScript
  3. Asegúrate de que el dominio esté registrado en Zenovay

Geolocalización incorrecta

Causa: La IP del cliente no se reenvía correctamente.

Solución: La ruta API intenta múltiples encabezados. Asegúrate de que tu plataforma reenvíe uno de estos:

  • x-forwarded-for (más común)
  • cf-connecting-ip (Cloudflare)
  • x-real-ip (nginx)

Alternativa para sitios estáticos

Si estás usando output: 'static', no puedes usar rutas API. En su lugar, usa el proxy de tu plataforma de alojamiento:

Vercel

vercel.jsonJSON
{
"rewrites": [
  { "source": "/api/_z/:path*", "destination": "https://api.zenovay.com/fp/:path*" }
]
}

Netlify

public/_redirectsTEXT
/api/_z/*  https://api.zenovay.com/fp/:splat  200

Cloudflare Pages

Usa las funciones de Cloudflare Pages en su lugar - consulta la guía de Cloudflare Pages.


Ejemplo completo

Estructura del proyectoTEXT
mi-sitio-astro/
├── astro.config.mjs
├── src/
│   ├── layouts/
│   │   └── Layout.astro
│   └── pages/
│       ├── index.astro
│       └── api/
│           └── _z/
│               └── [...path].ts
└── package.json
astro.config.mjsJavaScript
import { defineConfig } from 'astro/config';
import vercel from '@astrojs/vercel/serverless';

export default defineConfig({
output: 'hybrid',
adapter: vercel(),
});
src/layouts/Layout.astroASTRO
---
const { title } = Astro.props;
---
<!doctype html>
<html lang="es">
<head>
  <meta charset="UTF-8" />
  <title>{title}</title>
  <script defer data-tracking-code="TU_CÓDIGO_DE_RASTREO" src="/api/_z/script.js"></script>
</head>
<body>
  <slot />
</body>
</html>

Lista de verificación final

Antes de terminar, verifica todos estos puntos:

  • SSR de Astro está habilitado (o usando reescrituras de la plataforma de sitios estáticos)
  • El archivo de ruta API existe en src/pages/api/_z/[...path].ts
  • export const prerender = false está configurado (para modo híbrido)
  • La etiqueta de script usa /api/_z/script.js (no la URL directa de Zenovay)
  • El atributo data-tracking-code contiene tu código de rastreo correcto
  • El proyecto está desplegado (no solo ejecutándose localmente)
  • Probado en Firefox con Protección mejorada de rastreo configurada en Estricta
  • Las visitas aparecen en el panel de control de Zenovay

Próximos pasos

¿Fue útil esta página?