Cómo integrar Google Maps en WordPress paso a paso
Conoce más sobre la optimización de velocidad WordPress en WPPoland.
Integrar Google Maps en WordPress correctamente en 2026 va mucho más allá de pegar un iframe. Los desarrolladores profesionales deben considerar rendimiento, privacidad (GDPR), seguridad de la API key y la experiencia del usuario. Esta guía cubre cada aspecto en detalle.
Por qué no deberías usar iframes para Google Maps
La forma más común de agregar Google Maps a WordPress es copiar un iframe desde maps.google.com. Aunque funciona, tiene graves desventajas:
Problemas de rendimiento:
- Un iframe de Google Maps carga JavaScript y recursos desde servidores de Google
- Bloquea el renderizado de la página si no se carga de forma diferida
- Impacta negativamente en LCP (Largest Contentful Paint) e INP (Interaction to Next Paint)
- Puede causar Layout Shift (CLS) si no tiene dimensiones fijas
Problemas de privacidad:
- El iframe se carga sin esperar al consentimiento del usuario
- Cada carga envía a Google la dirección IP del visitante, y sin consentimiento previo eso choca con las normas europeas que se explican más abajo
Limitaciones funcionales:
- Sin personalización de estilos del mapa
- Sin marcadores personalizados
- Sin interactividad avanzada
- Sin control sobre el comportamiento del zoom o la navegación
Cómo se diferencia la Maps Embed API de un iframe copiado
Hay dos tipos de iframe. El fragmento que se copia desde el diálogo “Compartir” de google.com/maps no lleva API key ni contrato, así que detrás no tienes proyecto, ni cuota, ni informe de uso. La Maps Embed API es la versión documentada de la misma idea: un iframe cuyo src apunta a https://www.google.com/maps/embed/v1/MAP_MODE?key=YOUR_API_KEY&PARAMETERS, donde el modo es place, view, directions, streetview o search.
La página de uso y facturación de Google indica que la Maps Embed API “es de uso gratuito con solicitudes ilimitadas” (traducción propia) y que no hay límites por segundo ni por día. Aun así, cada solicitud necesita una API key, de modo que las restricciones de clave descritas más abajo también se aplican aquí. Los mapas incrustados no son compatibles por debajo de 200 px en ninguna de las dos dimensiones, y Google pide un atributo referrerpolicy en el iframe para que el navegador envíe tu dominio en la cabecera Referer. Sin él, una clave restringida a tu sitio web rechazará la solicitud.
<iframe
width="600" height="450" style="border:0" loading="lazy"
referrerpolicy="no-referrer-when-downgrade"
src="https://www.google.com/maps/embed/v1/place?key=YOUR_API_KEY&q=YOUR_ADDRESS">
</iframe>La Embed API encaja en una página de contacto con una sola ubicación. No hay riesgo de facturación ni JavaScript que escribir, y el atributo nativo loading="lazy" del iframe lo deja fuera de la carga inicial de la página. Lo que no resuelve es la cuestión de la privacidad. El iframe sigue cargando contenido de servidores de Google en el navegador del visitante, así que las reglas de consentimiento de las secciones sobre el RGPD de esta guía se le aplican igual que a la API de JavaScript. Cuando necesitas marcadores personalizados, agrupación de marcadores (clustering), estilos propios o interacción con el resto de la página, la herramienta adecuada es la Maps JavaScript API.
Paso 1: configurar la API de Google Maps
Crear proyecto en Google Cloud Console
- Ve a console.cloud.google.com
- Crea un nuevo proyecto o selecciona uno existente
- Habilita la “Maps JavaScript API”
- Ve a “Credenciales” y crea una API Key
Restringir la API key
Esto es crítico para la seguridad. Sin restricciones, cualquiera puede usar tu API Key y generar costos en tu cuenta.
Restricciones de aplicación: HTTP referrers
Referrers permitidos:
https://tusitio.com/*
https://www.tusitio.com/*
https://staging.tusitio.com/*Qué hacer si se filtra una API key de Google Maps
Una clave de navegador siempre está visible en el código fuente de la página, así que una “filtración” suele significar que faltaban restricciones o que eran demasiado amplias. Las buenas prácticas de seguridad de la API de Google marcan el orden de trabajo:
- Restringe primero. Añade una restricción de aplicación (sitios web, direcciones IP, apps de Android o iOS) y limita la clave a las APIs que realmente llama. Una restricción de sitio web acepta comodines como
https://*.example.com, que cubre todos los subdominios. - Usa claves distintas para aplicaciones y entornos distintos. Si una clave queda comprometida, puedes eliminarla o rotarla sin tocar las demás.
- Rota solo cuando restringir no baste. Google aconseja regenerar las claves “con cautela y solo como último recurso” (traducción propia). La rotación crea una clave nueva con las restricciones de la anterior, y ambas funcionan durante la transición, así que puedes desplegar la clave nueva en WordPress antes de retirar la antigua.
- Antes de eliminar una clave, comprueba en la vista de métricas que ya no recibe solicitudes correctas desde producción.
En WordPress, guarda la clave en una opción o en wp-config.php e imprímela desde un único sitio. Así una rotación es un solo cambio y no una búsqueda por las plantillas del tema y los widgets del maquetador visual.
Cómo funciona la facturación de Google Maps Platform desde marzo de 2025
Los tutoriales antiguos, incluidas versiones anteriores de este, mencionan un crédito mensual de 200 USD. Ese modelo ya no existe. Según la página de cambios de facturación de marzo de 2025 (consultada el 2026-10-14), Google “ha sustituido el crédito mensual recurrente de 200 USD por un umbral mensual de uso gratuito para cada SKU de Core Services” (traducción propia). Cada SKU pertenece a una categoría (Essentials, Pro o Enterprise), y el umbral gratuito varía según la categoría.
En la página de precios actual, los SKU que usa un sitio WordPress típico están en Essentials. Dynamic Maps (una carga de mapa en la Maps JavaScript API), Static Maps y Geocoding tienen cada uno un límite gratuito de 10.000 eventos facturables al mes, y el SKU de Embed figura como ilimitado. La mayoría de los SKU Pro tienen un límite de 5.000, y la mayoría de los Enterprise, de 1.000. Los umbrales se cuentan por SKU, de modo que un sitio que carga un mapa dinámico y además geocodifica direcciones consume dos cupos distintos. Los precios por encima del límite cambian con el tiempo, así que consúltalos en la página de precios y no en un artículo de blog.
La Maps JavaScript API sigue exigiendo una cuenta de facturación, aunque nunca superes el umbral gratuito. Hay dos controles que te protegen de una factura inesperada. Un presupuesto en Cloud Billing envía alertas cuando el gasto alcanza los umbrales que definas, pero no detiene la API. Una cuota en “APIs y servicios” (APIs & Services) limita el número de solicitudes por minuto o por día, y las solicitudes que la superan fallan. Las buenas prácticas de seguridad de Google recomiendan límites de cuota por minuto y por usuario en los proyectos del lado del cliente. Fija la cuota por encima de tu pico real de tráfico, porque cuando se alcanza también los visitantes legítimos reciben errores.
Esa misma página de marzo de 2025 pasó a estado Legacy tres servicios: Places API, Directions API y Distance Matrix API. Los servicios Legacy no reciben funciones nuevas, y la página de productos heredados indica que “no están disponibles en proyectos de Cloud nuevos” (traducción propia). Un proyecto creado hoy tiene que usar Places API (New) y Routes API, por lo que los ejemplos de código que llaman a google.maps.places.Autocomplete o DirectionsService pueden fallar en un proyecto nuevo aunque sigan funcionando en los antiguos.
Paso 2: implementar la fachada del mapa (map facade)
La técnica de “fachada” es clave para el rendimiento. En lugar de cargar Google Maps inmediatamente, muestras una imagen estática o un placeholder que se reemplaza por el mapa real solo cuando el usuario interactúa.
// Shortcode para mapa con fachada
function wppoland_mapa_google($atts) {
$atts = shortcode_atts(array(
'lat' => '48.2082',
'lng' => '16.3738',
'zoom' => '15',
'ancho' => '100%',
'alto' => '400px',
'marcador_titulo' => 'Nuestra ubicación',
), $atts);
$mapa_id = 'mapa-' . wp_unique_id();
ob_start();
?>
<div
id="<?php echo esc_attr($mapa_id); ?>"
class="wppoland-mapa-fachada"
data-lat="<?php echo esc_attr($atts['lat']); ?>"
data-lng="<?php echo esc_attr($atts['lng']); ?>"
data-zoom="<?php echo esc_attr($atts['zoom']); ?>"
data-título="<?php echo esc_attr($atts['marcador_titulo']); ?>"
style="width: <?php echo esc_attr($atts['ancho']); ?>; height: <?php echo esc_attr($atts['alto']); ?>; background: #e0e0e0; display: flex; align-items: center; justify-content: center; cursor: pointer; border-radius: 8px;"
>
<div class="mapa-placeholder" style="text-align: center;">
<svg width="48" height="48" viewBox="0 0 24 24" fill="#666">
<path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z"/>
</svg>
<p style="margin: 8px 0 0; color: #666; font-size: 14px;">Haz clic para cargar el mapa</p>
</div>
</div>
<?php
return ob_get_clean();
}
add_shortcode('google_mapa', 'wppoland_mapa_google');Paso 3: gestionar el consentimiento RGPD
Antes de cargar cualquier script de Google, debes obtener el consentimiento del usuario para cookies de marketing/terceros.
// Cargar mapa solo despues del consentimiento
document.addEventListener('DOMContentLoaded', function() {
const mapas = document.querySelectorAll('.wppoland-mapa-fachada');
mapas.forEach(function(contenedorMapa) {
contenedorMapa.addEventListener('click', function() {
// Verificar consentimiento de cookies
if (!tieneConsentimiento('marketing')) {
mostrarBannerConsentimiento();
return;
}
cargarMapa(contenedorMapa);
});
});
});
function cargarMapa(contenedor) {
const lat = parseFloat(contenedor.dataset.lat);
const lng = parseFloat(contenedor.dataset.lng);
const zoom = parseInt(contenedor.dataset.zoom);
const título = contenedor.dataset.título;
// Cargar script de Google Maps dinamicamente
if (!window.google || !window.google.maps) {
const script = document.createElement('script');
script.src = `https://maps.googleapis.com/maps/api/js?key=${GOOGLE_MAPS_API_KEY}&callback=initMap`;
script.async = true;
script.defer = true;
document.head.appendChild(script);
window.initMap = function() {
renderizarMapa(contenedor, lat, lng, zoom, título);
};
} else {
renderizarMapa(contenedor, lat, lng, zoom, título);
}
}
function renderizarMapa(contenedor, lat, lng, zoom, título) {
contenedor.innerHTML = '';
const mapa = new google.maps.Map(contenedor, {
center: { lat: lat, lng: lng },
zoom: zoom,
mapId: 'TU_MAP_ID_AQUI', // Estilos en la nube
});
new google.maps.Marker({
position: { lat: lat, lng: lng },
map: mapa,
title: título,
});
}Este ejemplo crea el marcador con google.maps.Marker, una clase que Google marca como obsoleta. Más abajo, en la sección sobre cómo sustituirla, está la versión actual con AdvancedMarkerElement y la carga mediante importLibrary().
Qué base jurídica cubre Google Maps según el RGPD
En una página con un mapa de Google confluyen dos normas distintas. La Directiva ePrivacy (2002/58/CE, artículo 5, apartado 3) exige consentimiento antes de almacenar información en el dispositivo del visitante o de leerla de él, salvo que sea estrictamente necesario para un servicio que el visitante haya solicitado expresamente. Después, el RGPD (GDPR) regula los propios datos personales, empezando por la dirección IP que queda expuesta en cada solicitud a los servidores de Google.
El papel del propietario del sitio lo aclaró el Tribunal de Justicia de la UE en el asunto Fashion ID (C-40/17), con sentencia del 29 de julio de 2019. El caso trataba de un botón “Me gusta” de Facebook, pero el razonamiento abarca cualquier contenido de terceros incrustado. El operador del sitio web puede ser corresponsable del tratamiento en la recogida y la transmisión de los datos de los visitantes al tercero, aunque no de lo que ese tercero haga después con ellos. Cuando la base jurídica es el consentimiento, el operador tiene que obtenerlo para esas operaciones y debe informar a los visitantes en el momento de la recogida.
El propio contrato de Google apunta en la misma dirección. En las Condiciones del Servicio de Google Maps Platform, Google y el cliente aceptan los Controller-Controller Data Protection Terms, de modo que Google actúa como responsable independiente del tratamiento de los datos que los visitantes le envían, no como tu encargado del tratamiento. Las condiciones también te obligan a cumplir la normativa de privacidad “relativa a los Servicios que almacenan Cookies y acceden a ellas en los dispositivos de los Usuarios Finales” (traducción propia). Si la dirección de tu cuenta de facturación está en el Espacio Económico Europeo, tu uso se rige por las condiciones del servicio específicas del EEE. Para las transferencias a Estados Unidos, la Comisión Europea adoptó el 10 de julio de 2023 su decisión de adecuación sobre el Marco de Privacidad de Datos UE-EE. UU., que cubre las transferencias a empresas estadounidenses certificadas en ese marco.
En la práctica, el mapa se carga tras el consentimiento o tras un clic en un marcador de posición claramente rotulado. La política de privacidad nombra a Google como destinatario y enlaza a la política de privacidad de Google, y la herramienta de consentimiento incluye el mapa en la categoría que lo bloquea. Esto es información general, no asesoramiento jurídico. La base jurídica de tu sitio la decide tu delegado de protección de datos o tu abogado.
Cómo gestionar el botón “mi ubicación”
Un localizador de tiendas suele tener un botón que centra el mapa en el visitante. El navegador pide permiso antes de que navigator.geolocation devuelva ningún dato, pero las condiciones de Maps Platform añaden requisitos propios. Tu sitio tiene que informar de antemano a los visitantes de qué datos de ubicación recoge y para qué, y “no obtendrá ni almacenará en caché la ubicación de ningún Usuario Final salvo con el consentimiento expreso, previo y revocable del Usuario Final” (traducción propia). Por eso el aviso del navegador no basta por sí solo. Explica el botón junto a él, no guardes coordenadas en cookies ni en los metadatos de usuario sin ese consentimiento y ofrece siempre un campo de código postal o ciudad como alternativa para quien lo rechace.
Paso 4: estilos personalizados con Map IDs
Los Map IDs permiten personalizar la apariencia del mapa desde Google Cloud Console, sin cambiar código en tu sitio.
- Ve a Google Cloud Console > Google Maps Platform > Map Management
- Crea un nuevo Map ID
- Asigna un estilo de mapa (puedes usar los predefinidos o crear uno personalizado)
- Usa el Map ID en tu código JavaScript
Ventajas de Map IDs:
- Cambiar estilos sin redesplegar código
- A/B testing de estilos de mapa
- Modo oscuro automático
- Estilos consistentes entre desarrollo y producción
Paso 5: optimización de rendimiento
Precarga condicional
// Precargar la API de Google Maps solo en páginas que la necesitan
function wppoland_precargar_maps_api() {
global $post;
if ($post && has_shortcode($post->post_content, 'google_mapa')) {
echo '<link rel="preconnect" href="https://maps.googleapis.com" crossorigin>' . "\n";
echo '<link rel="preconnect" href="https://maps.gstatic.com" crossorigin>' . "\n";
}
}
add_action('wp_head', 'wppoland_precargar_maps_api', 1);Imagen estática como placeholder
Para un placeholder visual más atractivo, usa la Static Maps API:
function wppoland_imagen_estatica_mapa($lat, $lng, $zoom = 15, $ancho = 640, $alto = 400) {
$api_key = get_option('wppoland_maps_api_key');
return sprintf(
'https://maps.googleapis.com/maps/api/staticmap?center=%s,%s&zoom=%d&size=%dx%d&key=%s&style=feature:all|saturation:-100',
$lat, $lng, $zoom, $ancho, $alto, $api_key
);
}Cómo usar OpenStreetMap con Leaflet como alternativa a Google Maps en WordPress
Si tu API key de Google Maps alcanza su cuota mensual o se topa con errores de red, el visitante ve un contenedor vacío. Para evitarlo, monta un sistema de respaldo que cargue OpenStreetMap (OSM) mediante Leaflet.js cuando la API de Google no esté disponible.
Cómo configurar marcadores para pantallas de alta densidad (Retina) y polígonos en Leaflet
En el mapa de respaldo con OpenStreetMap conviene sustituir los marcadores por defecto de Leaflet y añadir polígonos propios, por ejemplo para marcar zonas de reparto o el área de servicio de un negocio local:
function iniciarCargaMapa(contenedor) {
const lat = parseFloat(contenedor.dataset.lat);
const lng = parseFloat(contenedor.dataset.lng);
const zoom = parseInt(contenedor.dataset.zoom, 10);
const titulo = contenedor.dataset.title;
const googleApiKey = 'TU_API_KEY_DE_GOOGLE_MAPS';
// Si Google no responde en 3 segundos, se pasa a Leaflet
let temporizadorGoogle = setTimeout(() => {
console.warn('La API de Google Maps no responde. Se carga OpenStreetMap.');
cargarRespaldoLeaflet(contenedor, lat, lng, zoom, titulo);
}, 3000);
if (!window.google || !window.google.maps) {
const script = document.createElement('script');
script.src = `https://maps.googleapis.com/maps/api/js?key=${googleApiKey}&callback=initGoogleMap`;
script.async = true;
script.defer = true;
document.head.appendChild(script);
window.initGoogleMap = () => {
clearTimeout(temporizadorGoogle);
renderizarMapa(contenedor, lat, lng, zoom, titulo);
};
} else {
clearTimeout(temporizadorGoogle);
renderizarMapa(contenedor, lat, lng, zoom, titulo);
}
}
/**
* Carga Leaflet.js y OpenStreetMap de forma dinámica
*/
function cargarRespaldoLeaflet(contenedor, lat, lng, zoom, titulo) {
contenedor.innerHTML = ''; // Vaciar el marcado del placeholder
// Hoja de estilos de Leaflet
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = 'https://unpkg.com/[email protected]/dist/leaflet.css';
document.head.appendChild(link);
// Script de Leaflet
const script = document.createElement('script');
script.src = 'https://unpkg.com/[email protected]/dist/leaflet.js';
document.head.appendChild(script);
script.onload = () => {
const mapaL = L.map(contenedor).setView([lat, lng], zoom);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(mapaL);
// Marcador propio con versión para pantallas Retina
const iconoPropio = L.icon({
iconUrl: '/wp-content/themes/tu-tema/assets/images/custom-pin.png',
iconRetinaUrl: '/wp-content/themes/tu-tema/assets/images/[email protected]',
shadowUrl: '/wp-content/themes/tu-tema/assets/images/pin-shadow.png',
iconSize: [32, 32],
iconAnchor: [16, 32],
popupAnchor: [0, -32],
shadowSize: [41, 41]
});
L.marker([lat, lng], { icon: iconoPropio }).addTo(mapaL)
.bindPopup(titulo)
.openPopup();
// Polígono con la zona de servicio
const puntosPoligono = [
[lat + 0.01, lng - 0.01],
[lat + 0.01, lng + 0.01],
[lat - 0.01, lng + 0.01],
[lat - 0.01, lng - 0.01]
];
const poligono = L.polygon(puntosPoligono, {
color: '#E53E3E',
fillColor: '#FEB2B2',
fillOpacity: 0.4,
weight: 2
}).addTo(mapaL);
poligono.bindPopup('Nuestra zona de servicio');
};
}Con este enfoque híbrido el visitante sigue teniendo un mapa y una ubicación visible aunque las restricciones de la clave o la cuota de facturación bloqueen los servicios de Google. Ten en cuenta que el respaldo con OpenStreetMap también carga recursos de terceros (las teselas de OSM y, en este ejemplo, Leaflet desde unpkg), así que entra en la misma decisión de consentimiento que el mapa de Google.
Cómo mostrar cientos de marcadores en Google Maps con GeoJSON
En un directorio con cientos de ubicaciones físicas, crear un marcador independiente para cada par de coordenadas empeora el rendimiento del renderizado. Es mejor cargar las coordenadas de forma dinámica en una capa de datos GeoJSON.
Cómo cargar GeoJSON desde un endpoint REST de WordPress
function cargarUbicacionesGeoJson(mapa) {
// Descargar las coordenadas en GeoJSON
mapa.data.loadGeoJson('/wp-json/tu-plugin/v1/map-locations');
// Estilo común para todos los puntos
mapa.data.setStyle({
icon: {
url: '/wp-content/themes/tu-tema/assets/images/custom-pin.png',
scaledSize: new google.maps.Size(32, 32)
}
});
// Ventana de información al hacer clic
const ventanaInfo = new google.maps.InfoWindow();
mapa.data.addListener('click', (evento) => {
const nombre = evento.feature.getProperty('storeName');
const direccion = evento.feature.getProperty('address');
ventanaInfo.setContent(`<div><strong>${nombre}</strong><br>${direccion}</div>`);
ventanaInfo.setPosition(evento.latLng);
ventanaInfo.setOptions({ pixelOffset: new google.maps.Size(0, -30) });
ventanaInfo.open(mapa);
});
}El endpoint de WordPress devuelve un FeatureCollection con un punto por ubicación, y la capa de datos aplica un único estilo y un único listener de clics a todos ellos. Así los datos quedan separados del script de presentación: añadir una sucursal es crear una entrada en WordPress, no tocar el JavaScript. Si los nombres o direcciones vienen de campos que editan otras personas, escápalos antes de insertarlos en setContent(), porque la cadena se interpreta como HTML.
Paso 6: schema markup para la ubicación
// Agregar Schema markup de LocalBusiness con coordenadas.
// Nombre, coordenadas y dirección salen de los ajustes del propio sitio.
function mi_tema_schema_ubicacion() {
$schema = array(
'@context' => 'https://schema.org',
'@type' => 'LocalBusiness',
'name' => get_bloginfo('name'),
'geo' => array(
'@type' => 'GeoCoordinates',
'latitude' => get_option('empresa_lat'),
'longitude' => get_option('empresa_lng'),
),
'address' => array(
'@type' => 'PostalAddress',
'addressLocality' => get_option('empresa_ciudad'),
'addressCountry' => get_option('empresa_pais'),
),
);
echo '<script type="application/ld+json">' . wp_json_encode($schema) . '</script>' . "\n";
}
add_action('wp_head', 'mi_tema_schema_ubicacion');Cómo sustituir el google.maps.Marker obsoleto
La mayoría de los fragmentos de código, plugins y tutoriales antiguos para WordPress crean los marcadores con new google.maps.Marker(). La página de obsolescencias de Google indica que google.maps.Marker está obsoleto desde febrero de 2024 y señala google.maps.marker.AdvancedMarkerElement como sustituto. La clase antigua sigue funcionando, pero las funciones nuevas solo llegan a los marcadores avanzados.
Los marcadores avanzados tienen un requisito ineludible: el mapa necesita un Map ID. La guía de marcadores avanzados de Google dice que sin un Map ID “los marcadores avanzados no pueden cargarse” (traducción propia). El ID se crea en la Cloud Console, en la gestión de mapas, y se pasa como mapId. Es el mismo ID que lleva los estilos basados en la nube.
async function initMap(el, lat, lng) {
const [{ Map }, { AdvancedMarkerElement }] = await Promise.all([
google.maps.importLibrary('maps'),
google.maps.importLibrary('marker'),
]);
const map = new Map(el, { center: { lat, lng }, zoom: 15, mapId: 'YOUR_MAP_ID' });
new AdvancedMarkerElement({ map, position: { lat, lng }, title: 'Oficina' });
}También ha cambiado el patrón de carga. La guía de carga de Google describe la importación dinámica de bibliotecas: añades el cargador de arranque en línea (bootstrap loader) y llamas a importLibrary() solo para las bibliotecas que usas. Si mantienes la etiqueta script clásica, añade loading=async a su URL. La documentación lo califica de “muy recomendable” (traducción propia) para el rendimiento. Carga las bibliotecas en paralelo, como en el ejemplo, y no con líneas await separadas una tras otra. Los parámetros language y region del cargador deciden el idioma de los controles y de los avisos de copyright y orientan los resultados hacia un país. Esto importa en un sitio WordPress multilingüe, donde cada versión de idioma debería cargar el mapa en su propio idioma.
Lo mismo vale para la búsqueda de direcciones. El widget Autocomplete heredado pertenece a Places API (legacy), que los proyectos de Cloud nuevos no pueden habilitar. El widget actual es google.maps.places.PlaceAutocompleteElement, de Places API (New), que se crea y se añade a la página como un único elemento.
Cómo solucionar los errores habituales de Google Maps en WordPress
Cuando un mapa se queda gris o muestra “This page can’t load Google Maps correctly”, la causa aparece en la consola del navegador como Google Maps API error: ERROR_CODE, seguida de un enlace. La referencia de mensajes de error de Google enumera los códigos. Estos son los que aparecen en sitios WordPress:
| Código de error | Causa | Solución |
|---|---|---|
RefererNotAllowedMapError | La URL de la página no está en la lista de sitios web permitidos de la clave | Añade el dominio exacto, incluidos www y los hosts de staging |
ApiNotActivatedMapError | La Maps JavaScript API no está habilitada en el proyecto | Habilítala en la biblioteca de APIs de la Cloud Console |
BillingNotEnabledMapError | El proyecto no tiene cuenta de facturación | Vincula una cuenta de facturación al proyecto |
ApiTargetBlockedMapError | Las restricciones de API de la clave no incluyen la API que se llama | Añade la API que falta a las restricciones de la clave |
InvalidKeyMapError | La clave de la etiqueta script no existe | Busca errores al copiarla o crea una clave nueva |
MissingKeyMapError | La URL del script no tiene el parámetro key | Comprueba dónde imprime la clave el tema o el plugin |
ExpiredKeyMapError | La clave ha caducado o todavía no se reconoce | Espera unos minutos después de crearla y vuelve a intentarlo |
Hay dos causas propias de WordPress que no aparecen como códigos de error. Un plugin de caché u optimización que combina o retrasa el JavaScript puede ejecutar tu código de inicialización antes de que el cargador de Maps haya terminado, así que excluye los scripts del mapa de la combinación. Y un contenedor de mapa sin altura se muestra como una franja vacía. Da al contenedor una altura explícita o una relación de aspecto en CSS, lo que además evita el desplazamiento del diseño cuando aparece el mapa.
Qué métricas medir tras integrar Google Maps
Realiza un seguimiento de estos indicadores clave:
- Impacto en Core Web Vitals (LCP, INP, CLS) antes y después
- Tasa de interacción con el mapa
- Costo mensual de la API de Google Maps
- Cumplimiento GDPR (tasa de consentimiento)
- Clics en marcadores y direcciones
El monitoreo regular te permite ajustar tu implementación basándote en datos reales.
¿Necesitas ayuda con la integración de Google Maps en tu sitio WordPress? Como desarrollador WordPress, puedo implementar una solución optimizada para rendimiento y privacidad. Contáctame.






