В классическом Google Maps JavaScript API стандартный объект маркера
предоставляет ограниченные возможности для отображения текста рядом с
иконкой. Свойство label позволяет вывести короткую подпись,
но оно не подходит для сложной верстки, стилизации и динамического
контента. Для решения этих ограничений используется расширение
MarkerWithLabel, позволяющее привязывать произвольный
HTML-контент к маркеру карты.
Данный подход был особенно востребован в версиях API до появления AdvancedMarkerElement, когда требовалось создавать интерактивные подписи, стилизованные бейджи, числовые метки, кастомные подписи объектов и элементы UI поверх карты.
MarkerWithLabel реализуется как надстройка над стандартным
google.maps.Marker. Внутри он:
Ключевая идея заключается в разделении:
MarkerWithLabel не входит в основной пакет Google Maps JavaScript API и подключается отдельно.
Типичный способ установки через npm:
npm install @googlemaps/markerwithlabel
Далее импорт:
import MarkerWithLabel from "@googlemaps/markerwithlabel";
При использовании без сборщиков возможно подключение через CDN или локальную копию скрипта (в старых проектах).
Для работы требуется уже созданная карта:
const map = new google.maps.Map(document.getElementById("map"), {
center: { lat: 55.751244, lng: 37.618423 },
zoom: 10,
});
Создание маркера с меткой:
const marker = new MarkerWithLabel({
position: { lat: 55.751244, lng: 37.618423 },
map: map,
labelContent: "Москва",
labelAnchor: new google.maps.Point(50, 0),
labelClass: "map-label",
labelStyle: { opacity: 0.9 },
});
Определяет содержимое метки. Поддерживается HTML.
labelContent: "<div>Центр города</div>"
Использование HTML позволяет:
CSS-класс, применяемый к контейнеру метки.
labelClass: "custom-marker-label"
Пример CSS:
.custom-marker-label {
background: white;
padding: 6px 10px;
border-radius: 6px;
font-size: 13px;
color: #333;
box-shadow: 0 2px 6px rgba(0,0,0,0.2);
}
Определяет точку привязки метки относительно позиции маркера.
labelAnchor: new google.maps.Point(0, 0)
Это важно для корректного позиционирования, особенно при нестандартных иконках.
Позволяет задать inline-стили:
labelStyle: {
fontSize: "14px",
fontWeight: "bold",
color: "#000",
}
MarkerWithLabel позволяет создавать полноценные UI-элементы:
const marker = new MarkerWithLabel({
position: { lat: 55.76, lng: 37.64 },
map: map,
labelContent: `
<div class="price-tag">
<div class="price">1200 ₽</div>
<div class="desc">квартира</div>
</div>
`,
labelClass: "price-label",
labelAnchor: new google.maps.Point(40, 40),
});
CSS:
.price-label {
pointer-events: none;
}
.price-tag {
background: #1e88e5;
color: white;
padding: 8px 12px;
border-radius: 8px;
text-align: center;
min-width: 80px;
}
MarkerWithLabel поддерживает события маркера Google Maps, включая:
Пример:
marker.addListener("click", () => {
console.log("Маркер нажат");
});
Для интерактивных меток важно учитывать pointer-events в
CSS, иначе события могут не доходить до карты.
При большом количестве маркеров возникает проблема перекрытия. MarkerWithLabel позволяет управлять порядком отображения:
zIndex: 1000
Логика:
zIndex отображается поверх другихMarkerWithLabel поддерживает перетаскивание:
draggable: true
Обновление позиции метки происходит автоматически, но при кастомной логике можно слушать событие:
marker.addListener("dragend", (event) => {
console.log(event.latLng.lat(), event.latLng.lng());
});
Несмотря на гибкость, библиотека имеет ряд ограничений:
Современная замена MarkerWithLabel — AdvancedMarkerElement, который предоставляет:
Пример современного подхода:
const marker = new google.maps.marker.AdvancedMarkerElement({
map,
position: { lat: 55.75, lng: 37.61 },
content: document.createElement("div"),
});
MarkerWithLabel:
AdvancedMarkerElement:
При отображении множества объектов MarkerWithLabel часто используется в цикле:
const points = [
{ lat: 55.75, lng: 37.61, title: "A" },
{ lat: 55.76, lng: 37.62, title: "B" },
];
points.forEach((p) => {
new MarkerWithLabel({
position: { lat: p.lat, lng: p.lng },
map,
labelContent: p.title,
labelClass: "simple-label",
});
});
В таких сценариях важно контролировать:
При большом количестве меток критично учитывать:
Кластеризация обычно реализуется через отдельные библиотеки и не зависит напрямую от MarkerWithLabel, но архитектурно применяется совместно.
labelAnchor, приводящий к смещению
текстаpointer-events и событий картыMarkerWithLabel чаще всего применяется в:
Его основная ценность заключается в возможности превращать маркер из простой точки в полноценный UI-компонент, связанный с географическими координатами.