๐ฑ๏ธ Click Handling & Data Attributes
Every geographic region (state, province, or country) in the generated SVG is automatically equipped with standard HTML5 data-* attributes. This makes it incredibly easy to capture click events, identify the selected region, and build dynamic, interactive dashboardsโwithout any framework-specific wrappers.
๐ Available Data Attributesโ
When a user interacts with a map region, you can read the following attributes directly from the clicked <path> element:
| Attribute | Description | Example Values |
|---|---|---|
data-code | The short, unique identifier for the region. | "US-CA", "IN-MH", "DE-BY", "GB-ENG" |
data-name | The full, human-readable name of the region. | "California", "Maharashtra", "Bavaria", "England" |
๐ป Code Examplesโ
Because the map is just a standard SVG, you can use standard DOM event delegation. Here is how to implement it in both React and Vanilla JavaScript.
- React / Next.js
- Vanilla JavaScript
import { useEffect, useRef, useState } from "react";
import { createMap, registerMapData } from "svg-world-maps";
import usaData from "./maps/usa";
// 1. Register the map data
registerMapData("usa", usaData);
const App = () => {
const [selected, setSelected] = useState(null);
const containerRef = useRef(null);
// 2. Generate the map SVG string
const mapSVG = createMap("usa", {
background: "#e6f3ff",
borders: "#2c3e50",
size: "md",
hoverColor: "purple",
showTooltip: true // Note: use showTooltip, not tooltip
});
useEffect(() => {
const container = containerRef.current;
if (!container) return;
// 3. Attach event listener to the container (Event Delegation)
const handleClick = (e) => {
// Ensure we clicked a path (region), not the background or a label
if (e.target.tagName === "path") {
const code = e.target.dataset.code;
const name = e.target.dataset.name;
if (code && name) {
setSelected({ name, code });
// Auto-clear selection after 3 seconds
setTimeout(() => setSelected(null), 3000);
}
}
};
container.addEventListener("click", handleClick);
// 4. Cleanup on unmount
return () => container.removeEventListener("click", handleClick);
}, []);
return (
<div>
<div ref={containerRef} dangerouslySetInnerHTML={{ __html: mapSVG }} />
{selected && (
<div style={{ marginTop: "1rem", padding: "1rem", background: "#f0f0f0", borderRadius: "8px" }}>
<strong>Selected:</strong> {selected.name} ({selected.code})
</div>
)}
</div>
);
};
export default App;
import { createMap, registerMapData } from 'svg-world-maps';
import usaData from './maps/usa.js';
// 1. Register the map data
registerMapData('usa', usaData);
// 2. Generate and render the map
const mapSVG = createMap('usa', {
background: '#e6f3ff',
borders: '#2c3e50',
size: 'md',
hoverColor: 'purple',
showTooltip: true
});
const container = document.getElementById('map-container');
container.innerHTML = mapSVG;
// 3. Attach event listener using event delegation
container.addEventListener('click', (e) => {
// Check if the clicked element is a map region (path)
if (e.target.tagName === 'path') {
const code = e.target.dataset.code;
const name = e.target.dataset.name;
if (code && name) {
console.log(`You clicked on: ${name} (${code})`);
// Example: Update UI
document.getElementById('selection-display').textContent = `${name} (${code})`;
}
}
});
๐ฏ Common Use Casesโ
The data-code and data-name attributes unlock a wide variety of interactive features for your application:
- Dynamic Dashboards: Filter charts, tables, or KPI cards based on the
data-codeof the clicked region. - Client-Side Routing: Navigate users to a dedicated detail page (e.g.,
`router.push('/regions/' + code)`in Next.js or React Router). - Custom Tooltips/Modals: Trigger a custom, styled HTML modal or floating tooltip with rich data fetched from your API, instead of relying on the native SVG
<title>tag. - Analytics Tracking: Fire an event to your analytics provider (e.g., Google Analytics, Mixpanel) to track which regions users are interacting with most frequently.
๐ก Pro Tips for Event Handlingโ
Instead of attaching hundreds of individual event listeners to every single <path> element, attach one listener to the parent container. This is vastly more performant and prevents memory leaks, especially on complex maps like Great Britain (232 regions) or Slovenia (212 regions).
If you have showLabels: true, clicking directly on the text might trigger the event on the <text> element instead of the <path>.
Solution: Always check e.target.tagName === 'path' (as shown in the examples above), or use e.target.closest('path') to safely traverse up the DOM tree and find the parent region.
Because this relies on standard DOM APIs, the exact same logic works seamlessly in Vue, Svelte, Angular, Alpine.js, or plain JavaScript. The library never locks you into a specific framework's event system.