Cómo ubicar lugares de Webflow CMS en Google Maps dentro de Webflow Cloud

Cómo mostrar cada ubicación del CMS como un marcador de Google Maps con una aplicación de Webflow Cloud

Aprende a crear una aplicación de Webflow Cloud que lea una colección de CMS desde el servidor y ubique cada lugar como un marcador de Google Maps bajo la ruta de montaje correcta.

Cómo mostrar cada ubicación del CMS como un marcador de Google Maps con una aplicación de Webflow Cloud

Ismail Ajagbe
Redactor técnico
Ver perfil del autor
Ismail Ajagbe
Redactor técnico
Ver perfil del autor
Índice de contenidos

Los marcadores leídos desde el CMS se mueven con el contenido, y una pequeña aplicación de Webflow Cloud en el mismo sitio se encarga de la lectura; un pin estático queda obsoleto en cuanto el equipo de marketing abre una segunda oficina.

Las listas de tiendas y oficinas regionales suelen vivir en una colección de CMS con un elemento por cada lugar. Cuando el mapa lee esa colección, un editor que publica una nueva ubicación obtiene un nuevo pin sin necesidad de cambiar el código.

El mapa aquí es una aplicación de Webflow Cloud montada en el mismo sitio. Un gestor de rutas (Route Handler) lee los elementos publicados de la colección a través de la Content Delivery API de Webflow, y un componente cliente dibuja un marcador por elemento y ajusta la vista para que todos quepan.

La compilación almacena la latitud y longitud de cada ubicación en el CMS como números, ingresados una sola vez cuando un editor crea el elemento, y el gestor de rutas omite cualquier elemento al que le falte alguno de estos datos.

¿Qué necesitas para añadir marcadores de Google Maps desde una colección de CMS en Webflow?

Necesitas seis requisitos previos:

  • Un sitio de Webflow con acceso a CMS: Necesitas permisos para gestionar una colección y sus campos en el CMS de Webflow, así como para publicar el contenido que añadan los editores.
  • Un token de API del sitio de Webflow conCMS:read: El mapa solo necesita acceso de lectura; Webflow recomienda un token dedicado de solo lectura para cada canal de entrega de contenido. Guárdalo como un secreto del lado del servidor.
  • Un proyecto de Google Cloud con una cuenta de facturación: Google requiere facturación para la API de JavaScript de Maps y los marcadores avanzados; sin ella, el mapa se renderiza oscurecido y con marca de agua. También necesitas una clave de API y un ID de mapa para los marcadores avanzados que dibuja el componente.
  • Node.js 22 o superior y npm: Las versiones mínimas requieren Node.js 22 o superior y Next.js 15 o superior; Webflow Cloud solo admite npm.
  • Un proyecto de Next.js compatible: La aplicación aquí se ha creado desde cero con create-next-app y utiliza el App Router y TypeScript.
  • Control de versiones para la aplicación: Mantén el código de la aplicación y su archivo de bloqueo de npm juntos para que la compilación desplegada sea reproducible.

Con estos requisitos previos listos, puedes modelar el contenido, conectar ambas API, crear la aplicación y desplegarla bajo la ruta de montaje de Webflow Cloud.

7 pasos para añadir marcadores de Google Maps desde una colección de CMS en Webflow Cloud

Un gestor de rutas de Next.js lee la colección de ubicaciones a través de la Content Delivery API de Webflow, mientras que un componente cliente coloca un marcador por elemento. El manejo explícito de la ruta base permite que la solicitud del cliente funcione bajo la ruta de montaje de Webflow Cloud.

Primero crea el modelo de datos y las credenciales, luego añade la ruta del servidor, el componente del mapa y el entorno desplegado, en ese orden.

1. Modela la colección de ubicaciones en el CMS de Webflow

Crea una colección llamada Ubicaciones y guarda las coordenadas en campos de tipo Número, que admiten decimales. Las coordenadas numéricas evitan tener que analizar direcciones en la ruta de la solicitud.

Añade estos campos a la colección de Ubicaciones:

  • Nombre: El gestor de rutas lo devuelve y el componente lo utiliza como título al pasar el cursor sobre el marcador.
  • Dirección: Se almacena para mostrarla, por ejemplo, en una futura ventana de información; el componente actual no la renderiza.
  • Latitud: Grados decimales, negativos para el hemisferio sur. Webflow genera el slug del campo latitude, que es lo que lee el gestor de rutas.
  • Longitud: Grados decimales, negativos para el hemisferio occidental. Su slug es longitude; si a un elemento le falta cualquiera de los dos valores, se omite y no genera ningún pin.
  • Slug: Devuélvelo desde el gestor de rutas si es posible que un marcador enlace más adelante a la página de colección de ese elemento.

La colección ahora tiene todos los valores que devuelve el gestor de rutas y todas las coordenadas que el mapa necesita para colocar un marcador.

Añade al menos dos elementos con coordenadas reales y publícalos. Pega las coordenadas con su precisión decimal completa; redondearlas moverá el pin. La colección debería mostrar dos o más elementos publicados, cada uno con ambos valores de coordenadas completados.

2. Prepara el acceso a la API e identifica la colección

En Configuración del sitio > Aplicaciones e integraciones > Acceso a la API, crea un token de API del sitio con acceso de solo lectura al CMS. Ponle al token el nombre de la aplicación (por ejemplo, locations-map) para que quien herede el sitio sepa para qué sirve, y cópialo directamente en un gestor de contraseñas o .env.local.

Copia el ID de la colección de ubicaciones desde el panel de configuración de la colección. El gestor de rutas lo necesita para solicitar los elementos correctos.

Mantén ambos valores fuera del repositorio. El token va en .env.local para el desarrollo local y en el entorno de Webflow Cloud para el despliegue, y nunca aparece en un archivo enviado o en una variable NEXT_PUBLIC_.

Si una agencia entrega el sitio a un cliente, anota en la entrega quién gestiona el token y dónde reside, porque si se reemplaza, el entorno de Webflow Cloud necesita el nuevo valor antes de que el mapa vuelva a cargarse.

Ahora deberías tener un token de solo lectura y el ID de la colección listos para añadir a .env.local.

3. Crea una clave de API de Google Maps restringida y un ID de mapa

Crea una clave de API de Google Maps y aplica sus restricciones antes de usarla, ya que la clave se envía al navegador en el paquete de la página, donde cualquiera puede leerla. En la consola de Google Cloud, añade soporte para la API de JavaScript de Maps a tu proyecto y crea una clave de API.

Restrígela a sitios web (referentes HTTP) y añade http://localhost:3000/* para comprobaciones locales, además de cada origen completo donde se servirá la aplicación desplegada, incluido el esquema y seguido de /*, como https://www.example.com/* y tu dominio de webflow.io pruebas. En las restricciones de API, limita la clave a la API de JavaScript de Maps.

Crea un ID de mapa para JavaScript en la consola de Google Cloud y copia su valor. El componente cliente dibuja marcadores con AdvancedMarkerElement, que requiere un mapa creado con un ID de mapa.

Siempre reviso primero la lista de referentes, porque una clave que funciona en un dominio y falla en otro produce un mapa oscurecido con marca de agua sin causa aparente hasta que abres la consola. La clave de API debería tener ahora las entradas de referente necesarias, y el ID de mapa debería estar listo para añadir a .env.local junto con la clave como los dos valores NEXT_PUBLIC_ de Google.

4. Prepara la estructura de la aplicación Next.js

Prepara la estructura de la aplicación con el App Router y TypeScript, y deja next.config.ts intacto. Webflow Cloud inyecta la ruta base en el momento de la compilación, y la página de "bring-your-own-app" de Webflow la establece como "No adapter, no base path, no wrangler.json".

Ejecuta el andamiaje y añade las definiciones de tipo de Google Maps:

npx create-next-app@latest locations-map --typescript --app --eslint --no-tailwind --no-src-dir --import-alias "@/*" --use-npm --yes
cd locations-map
npm install -D @types/google.maps

El paquete de tipos es una dependencia de desarrollo que proporciona a TypeScript los tipos que utiliza el componente.google.maps

Ejecuta estos comandos para recopilar los cuatro valores de configuración sin colocar marcadores de posición instructivos en el archivo:

read -rsp "Webflow API token: " WEBFLOW_API_TOKEN && printf '\n'
read -rp "Webflow Collection ID: " WEBFLOW_COLLECTION_ID
read -rsp "Google Maps API key: " NEXT_PUBLIC_GOOGLE_MAPS_API_KEY && printf '\n'
read -rp "Google Maps Map ID: " NEXT_PUBLIC_GOOGLE_MAPS_MAP_ID
cat > .env.local <<EOF
WEBFLOW_API_TOKEN=$WEBFLOW_API_TOKEN
WEBFLOW_COLLECTION_ID=$WEBFLOW_COLLECTION_ID
NEXT_PUBLIC_GOOGLE_MAPS_API_KEY=$NEXT_PUBLIC_GOOGLE_MAPS_API_KEY
NEXT_PUBLIC_GOOGLE_MAPS_MAP_ID=$NEXT_PUBLIC_GOOGLE_MAPS_MAP_ID
NEXT_PUBLIC_BASE_PATH=
EOF

WEBFLOW_API_TOKENy contienen el token de solo lectura y el ID de la colección del paso 2. está deliberadamente vacío a nivel local, porque sirve la aplicación en la raíz. En Webflow Cloud, contendrá la ruta de montaje.WEBFLOW_COLLECTION_IDNEXT_PUBLIC_BASE_PATHnext dev

Los dos valores de Google son configuración pública del cliente; el valor de Webflow del lado del servidor no tiene ese prefijo y permanece en el servidor. Añade a si el andamiaje aún no lo ha hecho. inicia ahora una aplicación Next.js en blanco en localhost con todas las variables que leen el controlador de rutas y el componente de mapa.NEXT_PUBLIC_.env.local.gitignorenpm run dev

5. Escribe el controlador de rutas que lee la colección

Coloca la llamada a la API REST en un controlador de rutas y mantén los valores confidenciales del lado del servidor en el servidor, ya que los paquetes del navegador exponen cualquier valor que contengan. No le añadas .export const runtime = 'edge'

Esa línea es un defecto frecuente en las aplicaciones Next.js de Webflow Cloud y proviene de una colisión de nombres. Webflow Cloud ejecuta tu aplicación en Cloudflare Workers, una plataforma perimetral, y puedes describirla como el uso de un entorno de ejecución Edge.

La directiva de Next.js es algo distinto: un destino de tiempo de ejecución por ruta que el adaptador de Cloudflare de OpenNext no admite. Un controlador con esa exportación genera una compilación defectuosa. Un controlador que utiliza el estándar no necesita ninguna exportación de tiempo de ejecución.edgefetch

Obtención de ubicaciones desde la API de entrega de contenido de Webflow

Crea . Lee los elementos publicados desde la API de entrega de contenido de Webflow, , que es el punto final de elementos en vivo de la API de datos en un host con caché. Tiene que ver con la página: ese punto final devuelve 25 elementos cuando no pasas ningún y 100 como máximo, por lo que una sola solicitud contra una colección de 60 oficinas omitiría silenciosamente 35 marcadores.app/api/locations/route.tsGET https://api-cdn.webflow.com/v2/collections/{collection_id}/items/livelimit

Los slugs de los campos de Webflow se generan a partir de los nombres de los campos en el paso 1, por lo que se convierte en ; compruébalos en la configuración de la colección si nombraste los campos de forma diferente.Latitudelatitude

// app/api/locations/route.ts
type MapLocation = {
  id: string;
  name: string;
  slug: string;
  address: string;
  lat: number;
  lng: number;
};

type CmsItem = { id: string; fieldData: Record<string, unknown> };
type ItemsPage = { items?: CmsItem[]; pagination?: { total: number } };

const PAGE_SIZE = 100; // the endpoint's documented maximum
const CACHE_MS = 5 * 60 * 1000;

// Per-Worker-instance cache, a second layer on top of the CDN host. It is not global:
// each instance keeps its own copy, and a cold instance fetches again.
let cached: { at: number; locations: MapLocation[] } | null = null;

function coordinate(value: unknown, limit: number): number | null {
  if (value === null || value === undefined || value === '') return null;
  const n = typeof value === 'number' ? value : Number(value);
  return Number.isFinite(n) && Math.abs(n) <= limit ? n : null;
}

export async function GET() {
  if (cached && Date.now() - cached.at < CACHE_MS) {
    return Response.json(cached.locations);
  }

  const token = process.env.WEBFLOW_API_TOKEN;
  const collectionId = process.env.WEBFLOW_COLLECTION_ID;
  if (!token || !collectionId) {
    return Response.json({ error: 'Locations are not configured' }, { status: 500 });
  }

  const locations: MapLocation[] = [];
  let offset = 0;
  let total = Infinity;

  while (offset < total) {
    // /items/live returns published items only, so drafts never become pins.
    // The Content Delivery API host serves cached published items with effectively no rate limit.
    const url = new URL(`https://api-cdn.webflow.com/v2/collections/${collectionId}/items/live`);
    url.searchParams.set('offset', String(offset));
    url.searchParams.set('limit', String(PAGE_SIZE));

    const res = await fetch(url, {
      headers: { Authorization: `Bearer ${token}`, Accept: 'application/json' },
    });
    if (!res.ok) {
      console.error('Webflow CMS request failed', res.status);
      // Serve the last good copy rather than an empty map, if there is one.
      if (cached) return Response.json(cached.locations);
      return Response.json({ error: 'Locations are unavailable' }, { status: 502 });
    }

    const page = (await res.json()) as ItemsPage;
    const items = page.items ?? [];
    for (const item of items) {
      const f = item.fieldData;
      const lat = coordinate(f.latitude, 90);
      const lng = coordinate(f.longitude, 180);
      if (lat === null || lng === null) continue; // skip an incomplete item, keep the rest
      locations.push({
        id: item.id,
        name: String(f.name ?? ''),
        slug: String(f.slug ?? ''),
        address: String(f.address ?? ''),
        lat,
        lng,
      });
    }

    total = page.pagination?.total ?? offset + items.length;
    if (items.length === 0) break;
    offset += items.length;
  }

  cached = { at: Date.now(), locations };
  return Response.json(locations);
}

El controlador lee y , devuelve un error 500 si falta alguno y devuelve una matriz JSON de objetos . Mapear a , , , y en este límite significa que el componente del cliente nunca depende de la estructura de respuesta del CMS.WEBFLOW_API_TOKENWEBFLOW_COLLECTION_IDMapLocationfieldDatanameslugaddresslatlng

La comprobación rechaza cualquier valor que no sea un número utilizable dentro del rango, por lo que un elemento al que le falte su latitud se omite en lugar de descartarse en 0, 0 frente a la costa de África, y los elementos restantes se devuelven. Devuelve los fallos ascendentes como una respuesta de error y mantén el token y los detalles de autorización sin procesar fuera del navegador.coordinate

La ruta de esta ubicación es intencionadamente pública para que cada visitante pueda recuperar los datos del marcador. El ejemplo no tiene autenticación de visitantes ni autorización por usuario, y no tiene limitación de tasa. La elección del host importa más de lo que parece.

Límites de tasa y almacenamiento en caché para solicitudes de CMS

En el host estándar , cada vista de mapa sería una llamada a la API de datos, y los sitios Starter y Basic obtienen 60 de esas por minuto, por lo que una página con mucho tráfico empezaría a fallar. Los documentos de límites de tasa de Webflow dicen que "para las solicitudes almacenadas en caché a la API de entrega de contenido, prácticamente no hay límites de tasa", que es la razón por la que el controlador utiliza ; la caché en memoria es una segunda capa que también sirve la última copia válida si una solicitud falla.api.webflow.comapi-cdn.webflow.com

Un encabezado no puede realizar ninguna de las dos funciones, porque Webflow Cloud lo reemplaza por . No devuelvas campos de ubicación privados a través de esta ruta. Si los datos no deben ser públicos, añade autenticación y autorización, y luego limita las solicitudes antes de la implementación.Cache-Controlprivate, no-cache

Ejecuta y abre . Deberías ver una matriz JSON con un objeto por ubicación devuelto por el controlador, cada uno con , , , y .npm run devhttp://localhost:3000/api/locationsnameslugaddresslatlng

6. Crea el componente de mapa que dibuja los marcadores

Crea el componente de cliente incluyendo la ruta de montaje de Webflow Cloud en su solicitud de ubicaciones. Una petición a /api/locations funciona en next dev y devuelve un error 404 una vez que la aplicación se monta en /map, ya que el controlador real ahora reside en /map/api/locations.

Leer process.env.NEXT_PUBLIC_BASE_PATH en el componente soluciona esto en ambos entornos, ya que Webflow Cloud no reescribe las solicitudes del lado del cliente.

Guarda esto como app/components/LocationsMap.tsx; carga la API de Google Maps para JavaScript una vez y coloca un marcador avanzado por cada elemento:

"use client";

import { useEffect, useRef, useState } from "react";

type MapLocation = {
  id: string;
  name: string;
  slug: string;
  address: string;
  lat: number;
  lng: number;
};

declare global {
  interface Window {
    __onGoogleMapsReady?: () => void;
  }
}

let mapsPromise: Promise<void> | null = null;

function loadGoogleMaps(key: string): Promise<void> {
  if (mapsPromise) return mapsPromise;
  mapsPromise = new Promise((resolve, reject) => {
    window.__onGoogleMapsReady = () => resolve();
    const script = document.createElement("script");
    script.src =
      `https://maps.googleapis.com/maps/api/js?key=${encodeURIComponent(key)}` +
      `&libraries=marker&loading=async&callback=__onGoogleMapsReady`;
    script.async = true;
    script.onerror = () => reject(new Error("Google Maps failed to load"));
    document.head.appendChild(script);
  });
  return mapsPromise;
}

export default function LocationsMap() {
  const mapRef = useRef<HTMLDivElement>(null);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    const basePath = process.env.NEXT_PUBLIC_BASE_PATH ?? "";
    const key = process.env.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY;
    const mapId = process.env.NEXT_PUBLIC_GOOGLE_MAPS_MAP_ID;

    if (!key || !mapId) {
      setError("Google Maps is not configured");
      return;
    }

    let cancelled = false;

    async function render() {
      const [locations] = await Promise.all([
        fetch(`${basePath}/api/locations`).then((res) => {
          if (!res.ok) {
            throw new Error(`Locations request failed: ${res.status}`);
          }
          return res.json() as Promise<MapLocation[]>;
        }),
        loadGoogleMaps(key as string),
      ]);

      if (cancelled || !mapRef.current) return;

      const map = new google.maps.Map(mapRef.current, {
        center: { lat: 0, lng: 0 },
        zoom: 2,
        mapId,
      });

      const bounds = new google.maps.LatLngBounds();

      for (const location of locations) {
        const position = { lat: location.lat, lng: location.lng };
        new google.maps.marker.AdvancedMarkerElement({
          map,
          position,
          title: location.name,
        });
        bounds.extend(position);
      }

      if (locations.length === 1) {
        map.setCenter(bounds.getCenter());
        map.setZoom(14);
      } else if (locations.length > 1) {
        map.fitBounds(bounds);
      }
    }

    render().catch((err) => {
      setError(err instanceof Error ? err.message : "Map failed to load");
    });

    return () => {
      cancelled = true;
    };
  }, []);

  if (error) {
    return <p role="alert">{error}</p>;
  }

  return <div ref={mapRef} style={{ width: "100%", height: "70vh" }} />;
}

El mapsPromise a nivel de módulo evita una segunda etiqueta de script si el efecto se ejecuta más de una vez, y la devolución de llamada con nombre en la URL del script resuelve esa promesa, por lo que el componente espera al cargador antes de crear el mapa.

El ajuste de límites maneja el caso que le interesa a los editores: añade una ubicación en un país nuevo y el mapa se aleja para incluirla sin que nadie tenga que cambiar un centro predeterminado en el código.

Renderízalo desde la página raíz de la aplicación reemplazando app/page.tsx:

import LocationsMap from "@/app/components/LocationsMap";

export default function Page() {
  return (
    <main>
      <h1>Our locations</h1>
      <LocationsMap />
    </main>
  );
}

Recarga localhost y deberías ver un mapa con un pin por cada ubicación devuelta por el controlador de rutas y el visor encuadrado alrededor de todas ellas.

7. Despliega en Webflow Cloud con las variables de entorno

Configura el entorno de Webflow Cloud y establece su ruta de montaje en /map.

Establece las cinco variables de entorno en ese entorno antes del primer despliegue. Next.js integra los valores de NEXT_PUBLIC_ en el paquete del cliente cuando compila, por lo que un despliegue que se ejecute sin ellos produce una página que informa "Google Maps no está configurado" hasta que los añades y vuelves a desplegar.

Webflow Cloud hace que tanto las variables secretas como las no secretas estén disponibles en tiempo de compilación y de ejecución, por lo que un único conjunto cubre tanto el controlador como el componente.

Configuración de variables de entorno en Webflow Cloud

Añade WEBFLOW_API_TOKEN, WEBFLOW_COLLECTION_ID, NEXT_PUBLIC_GOOGLE_MAPS_API_KEY, NEXT_PUBLIC_GOOGLE_MAPS_MAP_ID, y NEXT_PUBLIC_BASE_PATH al entorno desplegado. Marca WEBFLOW_API_TOKEN como secreto para que Webflow Cloud oculte su valor en los registros de compilación.

Establece NEXT_PUBLIC_BASE_PATH en /map, haciendo coincidir la ruta de montaje exactamente con la barra diagonal inicial y sin barra diagonal final. Los dos valores de Google y la ruta base son públicos por diseño.

En la pantalla de variables, comprueba dos cosas: que el token esté marcado como secreto y que la ruta de montaje sea /map.

Despliega la aplicación. Una vez completado, abre la URL /map desplegada (o la ruta del dominio personalizado en Premium o superior), y el mismo mapa que viste en localhost debería renderizarse en el dominio del sitio, con pines y todo. Abre el panel de red del navegador y confirma que la solicitud de ubicaciones se dirigió a /map/api/locations y devolvió la matriz JSON.

¿Qué hace que los marcadores de Google Maps del CMS de Webflow fallen?

Los marcadores de Google Maps suelen fallar porque la ruta montada devuelve un 404, la compilación contiene una exportación de tiempo de ejecución no compatible, faltan valores de API desplegados o la clave de Google rechaza el dominio de servicio.

Relaciona el síntoma visible del navegador o de la compilación con la causa, inspecciona la configuración nombrada y verifica la corrección con la respuesta esperada.

La página muestra 'Locations request failed: 404' en Webflow Cloud, pero el mapa se carga en localhost

Causa: El componente cliente omitió la ruta de montaje de Webflow Cloud en la solicitud de ubicaciones. En next dev, no hay una ruta base, por lo que /api/locations se resuelve correctamente y oculta el defecto hasta la implementación.

Una vez que la aplicación se monta en /map, el controlador de rutas (Route Handler) reside en /map/api/locations. Webflow Cloud no reescribe automáticamente esa solicitud del lado del navegador, lo que provoca que el componente solicite una ruta que no existe.

Solución: Establece NEXT_PUBLIC_BASE_PATH en /map en el entorno implementado, mantenlo vacío en .env.local, y construye la solicitud como fetch(${basePath}/api/locations). Vuelve a implementar, ya que Next.js integra el valor público durante la compilación.

En el panel de red del navegador, inspecciona la URL y el estado de la solicitud. Debería incluir el prefijo /map , devolver una respuesta 200 y contener la matriz JSON de ubicaciones.

La compilación de Webflow Cloud falla aunque next dev ejecute el controlador de rutas sin errores

Causa: El controlador de rutas contiene export const runtime = 'edge'. Esta línea suele aparecer al interpretar "Edge runtime" en la guía de la plataforma como una instrucción para el archivo de ruta. Webflow Cloud ejecuta la aplicación en Cloudflare Workers, pero la exportación edge de Next.js es un destino específico por ruta que el adaptador OpenNext de Cloudflare no admite.

El desarrollo local puede ejecutar el controlador sin revelar la incompatibilidad de implementación, por lo que el primer síntoma claro aparece en el registro de compilación de Webflow Cloud.

Solución: Elimina la exportación de tiempo de ejecución de app/api/locations/route.ts y de cualquier otra ruta o página donde se haya añadido, luego confirma y vuelve a implementar. Un controlador que utiliza el fetch estándar no necesita una exportación de tiempo de ejecución.

Si un compañero también renombró middleware.ts a proxy.ts, revierte ese cambio; el middleware de tiempo de ejecución de Node.js no es compatible con Webflow Cloud, y proxy no puede optar por el middleware de borde que sí lo es. La implementación corregida debería completarse sin el error de destino de tiempo de ejecución.

La página muestra 'Locations request failed: 500' o '502' mientras que localhost devuelve datos

Causa: Al controlador de rutas implementado le falta un valor necesario o su solicitud de API ascendente ha fallado. .env.local es leído por next dev y no forma parte del entorno implementado. Con el manejo de errores del controlador, la falta de WEBFLOW_API_TOKEN o WEBFLOW_COLLECTION_ID devuelve una respuesta 500, mientras que un fallo en la API ascendente puede devolver un 502.

Abre /map/api/locations directamente, o inspecciona la respuesta en el panel de red, para leer el cuerpo del error del controlador y distinguir una configuración faltante de un fallo ascendente.

Solución: Abre las variables de entorno en Webflow Cloud y comprueba que WEBFLOW_API_TOKEN y WEBFLOW_COLLECTION_ID existan, que los nombres estén escritos exactamente como los lee el controlador y que estén configurados en el entorno que realmente implementaste.

Si el token ha sido reemplazado o ha perdido su acceso de lectura al CMS, pega uno nuevo en el entorno y vuelve a implementar. Un 200 de /map/api/locations con la matriz JSON confirma la corrección.

El mapa se muestra oscurecido y con marca de agua, y la consola informa RefererNotAllowedMapError

Causa: La restricción de referente HTTP de la clave de Google no incluye el dominio que sirve la aplicación. El navegador recibe la clave y carga la API de JavaScript de Maps, pero Google rechaza la solicitud porque el referente no coincide con una entrada de sitio web permitida. Esto suele aparecer solo después de la implementación porque la entrada de localhost y el dominio implementado son referentes distintos.

Por lo tanto, una clave puede funcionar en http://localhost:3000 mientras produce un mapa oscurecido y con marca de agua en el dominio alojado en Webflow o en un dominio personalizado.

Solución: Añade el dominio de servicio que falta a las restricciones de sitio web de la clave en la consola de Google Cloud. Incluye /* después del dominio para que la entrada cubra todas las rutas, incluyendo /map. Añade cada dominio que pueda servir la aplicación implementada en lugar de asumir que una entrada cubre otro nombre de host.

Una entrada de dominio personalizado solo importa una vez que el sitio está en Premium o superior y el dominio está conectado. Recarga la página y confirma que el error de la consola ha desaparecido y que los marcadores se renderizan.

Qué puedes construir a continuación con Google Maps y Webflow

Explora la integración con Google Maps para tu próximo proyecto. Si necesitas que esas mismas ubicaciones lleguen a otro sistema, la lectura paginada del paso 5 es la clave del patrón de sincronización de CMS. Para una personalización más profunda, la documentación para desarrolladores de Webflow cubre la plataforma de desarrollo y la guía de Cloud.

Preguntas frecuentes

¿Puedo mostrar marcadores de CMS en un mapa sin una aplicación de Webflow Cloud?

Sí, y para una lista pequeña es más sencillo. Vincula los campos numéricos a atributos personalizados en una lista de colección y léelos con un script de página que inicialice el mapa. La página de integración de Google Maps de Webflow también sugiere una aplicación del Marketplace para la versión sin código. Ten en cuenta dos límites: una lista de colección muestra 100 elementos por defecto y publicar el script requiere un plan de sitio de pago o un Workspace Core, Growth, Agency o Freelancer. La aplicación de Webflow Cloud vale la pena cuando superas unos cientos de ubicaciones o necesitas filtrado del lado del servidor.

¿Tienen los editores que escribir la latitud y longitud a mano?

No, pero revisa los términos del servicio que utilices para rellenarlos. La API de Geocoding de Google es un servicio de pago independiente; sus términos permiten almacenar en caché las coordenadas devueltas durante un máximo de 30 días y prohíben compartirlas entre usuarios finales, por lo que guardar los resultados permanentemente en el CMS para cada visitante no cumple con sus normas. Pide a los editores que copien coordenadas de una fuente que puedan almacenar o usa un geocodificador cuyos términos permitan el almacenamiento permanente.

¿Cómo puedo verificar que una ubicación recién publicada llegó al mapa?

Puedes verificar la publicación antes de revisar el mapa: abre /map/api/locations y busca el slug y las coordenadas del elemento en el JSON devuelto. Si el elemento no aparece, comprueba su estado de publicación y los campos de coordenadas. Si está presente, la lectura del CMS fue exitosa y puedes centrarte en el componente del navegador.


Última actualización
October 2, 2026
Categoría

Artículos relacionados


verifone logomonday.com logospotify logoted logogreenhouse logoclear logocheckout.com logoreddit logothe new york times logoideo logoupwork logodiscord logo
verifone logomonday.com logospotify logoted logogreenhouse logoclear logocheckout.com logoreddit logothe new york times logoideo logoupwork logodiscord logo

Empieza gratis

Prueba Webflow todo el tiempo que quieras con nuestro plan Starter gratuito. Compra un plan de sitio de pago para publicar, alojar y desbloquear funciones adicionales.

Empieza, es gratis
Ver demostración

Prueba Webflow todo el tiempo que quieras con nuestro plan Starter gratuito. Compra un plan de sitio de pago para publicar, alojar y desbloquear funciones adicionales.