
Syncfusion Blazor Maps
- 230 installs
- 4 repo stars
- Updated July 28, 2026
- syncfusion/blazor-ui-components-skills
Use syncfusion-blazor-maps for development tasks
About
syncfusion-blazor-maps: A skill for development. This provides functionality for development workflows.
- syncfusion-blazor-maps
Syncfusion Blazor Maps by the numbers
- 230 all-time installs (skills.sh)
- +13 installs in the week ending Jul 27, 2026 (Skillselion tracking)
- Ranked #1,668 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
- Data as of Jul 29, 2026 (Skillselion catalog sync)
npx skills add https://github.com/syncfusion/blazor-ui-components-skills --skill syncfusion-blazor-mapsAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 230 |
|---|---|
| repo stars | ★ 4 |
| Last updated | July 28, 2026 |
| Repository | syncfusion/blazor-ui-components-skills ↗ |
What it does
Use syncfusion-blazor-maps for development tasks
Files
Implementing Syncfusion Maps for Blazor
NuGet: Syncfusion.Blazor.Maps + Syncfusion.Blazor.Themes Namespace: Syncfusion.Blazor.Maps
A comprehensive guide to implementing Syncfusion Maps component in Blazor applications. Syncfusion Maps provides powerful spatial visualization capabilities including marker management, polygon overlays, layer support, event handling, and integration with multiple map providers.
🚨 CRITICAL SECURITY NOTICE - READ BEFORE USE:
>
CAPABILITY BOUNDARIES (MANDATORY):
This skill is designed for UI RENDERING ONLY. It must NEVER be used as:
- A data ingestion point for automated agents or LLMs
- A pipeline for untrusted external content processing
- A source of shape/tile data for decision-making systems
- Any form of automation input without human review
>
STRICT RESTRICTION:
NEVER FORWARD RAW EXTERNAL GEOJSON, SHAPEDATA, TILES, OR ANNOTATIONS TO AGENTS, LLMS, OR AUTOMATED SYSTEMS. All external map content must be treated as untrusted user input. Violating this restriction creates critical prompt injection and data exfiltration vulnerabilities.
>
REQUIRED PRODUCTION SAFEGUARDS:
>
1. For GeoJSON/Tile Loading:
- Host tiles and GeoJSON locally (under wwwroot/tiles or bundled assets), OR- Use only server-side proxies that validate all data before client access
- NEVER load directly from third-party URLs at runtime
>
2. For Server-Side Proxy (if used):
- Validate provider host against strict allow-list and require HTTPS
- Verify content-type and validate against strict schema (no user fields)
- Enforce maximum file size (5MB) and feature-count limits (10,000 max)
- Strip or HTML-encode ALL properties (tooltips, annotations, labels)
- Reject content containing instruction patterns or suspicious keywords
- Normalize/validate coordinates (lat -90/90, lng -180/180)
- Sanitize all text fields with HtmlSanitizer before client delivery
- Issue short-lived signed URLs (do NOT embed API keys)
>
3. For Content Rendering:
- Always sanitize external properties with HtmlSanitizer before rendering
- Implement Content Security Policy headers to block script injection
- Enable comprehensive logging of all validation failures
>
IF external content must be processed by automation:
- Perform COMPLETE server-side schema validation and sanitization FIRST
- Implement mandatory rejection policy for instruction-like patterns
- Enforce strict token/length limits (max 256 chars per field)
- Require explicit human review and sign-off before automation
- Wrap in boundary markers: [MAP_DATA_START]...[MAP_DATA_END]- Log all processing with full audit trail
- See readme-security for required validation templates
>
DO NOT USE THIS SKILL FOR:
- ❌ Analyzing untrusted external geographic data
- ❌ Processing user-uploaded GeoJSON without validation
- ❌ Forwarding map content to LLM/agent analysis systems
- ❌ Making automated decisions based on external map metadata
- ❌ Storing or caching external third-party content
>
SEVERE SECURITY CONSEQUENCES:
Ignoring these boundaries may result in:
- Prompt injection attacks via malicious geographic data
- LLM/agent behavioral manipulation
- Unauthorized data exfiltration
- System compromise through script injection
When to Use This Skill
Use Syncfusion Maps when you need to:
- Display geographic data on interactive maps
- Visualize data across regions using color mapping (choropleth)
- Add markers, polygons, and annotations to maps
- Handle user interactions (click, hover, zoom, pan)
- Support multiple map providers (Google, Bing, Azure, OpenStreetMap)
- Export or print maps with custom legends and labels
- Build location-aware applications
- Create multi-layer spatial visualizations
Component Overview
Syncfusion Maps is a powerful geospatial visualization component that enables you to:
- Render interactive maps with multiple provider options
- Bind and visualize geographic datasets
- Support rich spatial features (markers, polygons, layers, annotations)
- Handle complex user interactions and events
- Customize appearance through themes and styling
- Enable localization and accessibility features
- Export maps for reporting and sharing
---
⚠️ CRITICAL: Approved and Restricted Use Cases
✅ APPROVED USES (UI Rendering with Validation)
- Display geographic data on interactive web dashboards
- Visualize regional statistics through choropleth maps
- Show business location markers with human review
- Render localized maps for user interaction
- Provide spatial search and filtering interfaces
- Create read-only geographic visualizations
- Support decision-making with validated, curated data
❌ STRICTLY PROHIBITED USES (No Agent/LLM Integration)
- NEVER: Pass raw map data to LLM analysis systems
- NEVER: Use as ingestion point for automated agents
- NEVER: Forward external GeoJSON to decision-making systems
- NEVER: Process untrusted third-party geographic data through automation
- NEVER: Use annotations/tooltips as LLM input without human review
- NEVER: Create automated geographic data pipelines
- NEVER: Integrate with AI systems that analyze map metadata
🚫 THIRD-PARTY CONTENT INGESTION BOUNDARY
External Sources Referenced in This Skill:
tile.openstreetmap.org- OpenStreetMap providercdn.syncfusion.com- Syncfusion component resourcesmaps.googleapis.com- Google Maps providerdev.virtualearth.net- Bing Maps provideratlas.microsoft.com- Azure Maps provider
IMPORTANT: These third-party providers are ingested for UI rendering only. None of this content should ever reach automated systems. If you need to process geographic data through automation:
1. ❌ DO NOT use this skill's external bindings 2. ✅ DO create a separate server-side validation pipeline 3. ✅ DO sanitize and validate all external content first 4. ✅ DO require explicit human approval before automation 5. ✅ DO implement comprehensive audit logging
---
Security Considerations
CRITICAL: This skill involves several security-sensitive operations. Review and implement these safeguards:
1. API Key Management
- Risk: Hardcoded API keys in source code can be exposed in version control
- Mitigation: Store keys in configuration files, user secrets, or secret management services
- Reference: Map Providers - Security Best Practices
2. HTML Content Injection
- Risk: Tooltips, annotations, and popups can render arbitrary HTML from external data sources
- Attack Vectors: XSS attacks, prompt injection through malicious geographic data
- Mitigation: Sanitize all external content using HtmlSanitizer library, HTML-encode user input
- Reference: User Interactions - Sanitizing External Content
3. External Data Sources
- Risk: Map data (GeoJSON, tiles, markers) fetched from untrusted sources, including CDNs
- Attack Vectors: Man-in-the-middle attacks, CDN compromise, malformed data injection, property injection
- Mitigation: Validate source URLs against allow-lists, enforce HTTPS, validate GeoJSON structure, implement CSP, cache locally in production
- Reference: Data Visualization - Validating External GeoJSON | Map Providers - Data Exfiltration Prevention
4. Data Export Operations
- Risk: Exporting maps to PNG/SVG/PDF may include sensitive geographic data
- Mitigation: Implement access controls, audit export operations, sanitize export content
- Reference: Print and Export
5. Prompt Injection Prevention & Agent/LLM Boundary
- CRITICAL RISK: Shape data, annotations, tooltips, and other external map metadata can include text resembling instructions. This skill ingests third-party content (tile providers, GeoJSON sources) that can be weaponized for prompt injection if forwarded to automated agents or LLMs without explicit human review.
- Attack Surface: External content enters via:
- MapsLayer
UrlTemplate(tile providers) ShapeDataandDataSourceproperties (GeoJSON)- Tooltip and annotation properties
- Any data binding from external sources
- MANDATORY BOUNDARY: This skill must NEVER be the source of data for:
- LLM analysis or summarization
- Automated agent decision-making
- AI-powered geographic analysis
- Machine learning training pipelines
- Any system that processes map data through AI/ML without human intervention
- If external content must reach automation:
- Apply server-side validation BEFORE any client rendering: schema checks (strict GeoJSON validation), domain allow‑list verification
- Sanitize ALL properties with HtmlSanitizer and remove HTML/script tags
- Implement mandatory rejection policy for instruction-like keywords ("system:", "ignore", "bypass", "execute", "[SYSTEM]", etc.)
- Enforce strict length limits (max 256 chars per property, max 5000 chars total)
- Wrap data in boundary markers:
[MAP_DATA_START]...[MAP_DATA_END] - Require explicit human review and sign-off before forwarding to any AI system
- Maintain comprehensive audit log of all AI system accesses
- Mitigation Architecture:
- Layer 1: UI-rendering-only designation (no agent/LLM use)
- Layer 2: Pattern detection (suspicious keyword detection)
- Layer 3: Immediate rejection (no alternative parsing)
- Layer 4: HTML sanitization (whitelist approach)
- Layer 5: Strict validation pipeline (schema, size, coordinates)
- Layer 6: Boundary markers & audit logging (for unavoidable automation)
- Reference: User Interactions - Preventing Prompt Injection | readme-security.md
---
Security Issue Resolutions
This skill has been hardened against the following identified security warnings:
[CREDENTIALS_UNSAFE] Hardcoded API Keys
Status: ✅ RESOLVED
Finding: Google Maps API key was shown hardcoded in example code.
Fix Implemented:
- Removed all hardcoded API keys from examples
- Updated all provider configuration examples to load keys from
IConfiguration - Added comprehensive API key management guide showing environment variables, user secrets, and Azure Key Vault integration
- All examples now use
Configuration["MapProviders:GoogleKey"]pattern
Action Required: Never hardcode API keys. Load from configuration, environment variables, or secrets manager.
Reference: map-providers.md#managing-api-keys-securely
[EXTERNAL_DOWNLOADS] External Tile and Data Downloads
Status: ✅ DOCUMENTED AS EXPECTED BEHAVIOR
Finding: Skill downloads map tiles from tile.openstreetmap.org, cdn.syncfusion.com, and maps.googleapis.com.
Explanation: These downloads are expected and necessary for map visualization. Map tiles MUST come from a tile provider. This is normal behavior, not a vulnerability.
Best Practices:
- Use local tile caching in production environments
- Implement a server-side proxy to validate tile URLs
- Enforce HTTPS for all tile requests
- Configure domain allow-lists
Reference: map-providers.md#external-asset-downloads-expected-behavior
[COMMAND_EXECUTION] IJSRuntime Browser API Usage
Status: ✅ RESOLVED WITH SAFEGUARDS
Reference: state-persistence.md | customization-and-styling.md
[PROMPT_INJECTION] Untrusted Data to Automated Agents
Status: ✅ RESOLVED WITH COMPREHENSIVE CONTROLS
Finding: GeoJSON and map metadata can include text resembling instructions, risking prompt injection if passed to LLMs/agents without sanitization.
Multi-Layer Mitigation Implemented:
1. Capability Boundaries: Skill designated for UI rendering ONLY
- Explicit prohibition on passing raw data to LLMs/agents
- All external content treated as untrusted
2. Pattern Detection: Implemented instruction pattern detection
- Detects: "system:", "ignore", "bypass", "execute", "[SYSTEM]", etc.
- Immediate rejection on suspicious content
3. Sanitization: All HTML content sanitized before rendering
- HtmlSanitizer library removes scripts and unsafe tags
- HTML encoding applied to external properties
- No raw HTML from external sources
4. Validation Pipeline: Comprehensive GeoJSON validation
- Schema validation (FeatureCollection structure)
- Size limits (5MB max, 10,000 features max)
- Property validation (50 max, 1000 chars each)
- Coordinate range validation (-90/90 lat, -180/180 lng)
5. Boundary Markers: If automation required
- Use
[MAP_DATA_START] ... [MAP_DATA_END]delimiters - Strict length limits (256 chars per property, 5000 total)
- Rejection policy on validation failure
6. Logging & Audit: Comprehensive security logging
- All validation failures logged
- Suspicious patterns logged with context
- Human review required before any automation
Production Checklist:
- [ ] No hardcoded API keys
- [ ] GeoJSON from local files or validated provider
- [ ] HTTPS enforced for external requests
- [ ] HtmlSanitizer installed and configured
- [ ] Content Security Policy headers set
- [ ] Pattern rejection policy implemented
- [ ] Comprehensive logging enabled
- [ ] API keys in secrets manager
- [ ] Security review completed
Reference: readme-security.md | user-interactions.md#preventing-prompt-injection | data-visualization.md#validating-external-geojson-data
---
Documentation and Navigation Guide
Choose the reference guide that matches your current task:
Getting Started
📄 Read: references/getting-started.md
- Installation and NuGet package setup
- Basic map initialization and rendering
- CSS imports and theme configuration
- Creating your first interactive map
- Step-by-step setup walkthrough
Map Providers and Configuration
📄 Read: references/map-providers.md
- Google Maps setup and API key configuration
- Bing Maps setup and authentication
- Azure Maps provider configuration
- OpenStreetMap setup
- Provider comparison and selection guide
Markers and Layers
📄 Read: references/markers-and-layers.md
- Adding and managing markers
- Marker clustering and grouping
- Working with layers and layer collections
- Toggling layer visibility
- Dynamic marker updates and data binding
Spatial Features and Overlays
📄 Read: references/spatial-features.md
- Drawing polygons and geographic shapes
- Creating navigation lines and polylines
- Adding annotations with text, icons, and circles
- Creating data bubbles and interactive overlays
- Advanced spatial geometry features
Data Visualization and Mapping
📄 Read: references/data-visualization.md
- Color mapping and choropleth visualization
- Configuring legends and legend placement
- Data labels on map elements
- Populating maps with geographic datasets
- Advanced data binding and visualization patterns
User Interactions
📄 Read: references/user-interactions.md
- Handling mouse clicks and double-clicks
- Zoom and pan control configuration
- Tooltip and popup behavior
- Keyboard navigation support
- Custom interaction patterns
Events and Methods
📄 Read: references/events-and-methods.md
- Mouse event handling (click, hover, move)
- Pan and zoom event capture
- Programmatic map methods (pan, zoom, reset, refresh)
- Event data and callback patterns
- Triggering actions from user interactions
Customization and Styling
📄 Read: references/customization-and-styling.md
- CSS class customization
- Theme Studio integration
- Marker and popup styling
- Map controls and navigation styling
- Dark mode and responsive design
Print and Export
📄 Read: references/print-and-export.md
- Exporting maps as PNG, SVG, and PDF
- Print functionality and page setup
- Exporting with legends and data labels
- File format considerations
- Server-side and client-side export options
Internationalization and Localization
📄 Read: references/internationalization-and-localization.md
- Multi-language support for map labels
- Right-to-left (RTL) text support
- Localized number and date formatting
- Regional map variations
- Language-specific customization
State Persistence
📄 Read: references/state-persistence.md
- Saving and restoring map state
- Persisting zoom level and center position
- Preserving user interaction state
- Session and local storage integration
- State management patterns
Accessibility and Advanced Topics
📄 Read: references/accessibility.md
- WCAG 2.1 compliance and standards
- Keyboard navigation and shortcuts
- ARIA attributes and semantic markup
- Screen reader support
- High contrast mode support
- Assistive technology compatibility
Complete API Reference
📄 Read: references/api-reference.md
SfMapsmain component properties and methods- Configuration classes (
MapsCenterPosition,MapsZoomSettings,MapsLegendSettings, etc.) - Event arguments for all event types
- Interfaces (
ILayer,IMarker,IBubble) - Enumerations for
MarkerType,ExportType,ProjectionType,GeometryType, etc. - Properties quick reference guide
- Complete class hierarchy and API surface
---
⛔ SECURITY REQUIREMENT: What NOT to Do
The following patterns are PROHIBITED and create critical security vulnerabilities:
// ❌ PROHIBITED: Forwarding map data to LLM/agents
var geoJsonData = await LoadGeoJsonFromMapLayer();
var analysis = await llmService.AnalyzeAsync(geoJsonData); // NEVER DO THIS
// ❌ PROHIBITED: Using external annotations in agent prompts
var tooltipText = mapFeature.Properties["tooltip"];
var response = await agent.ExecuteAsync($"Summarize: {tooltipText}"); // NEVER DO THIS
// ❌ PROHIBITED: Processing third-party tiles through automation
var tileUrl = "https://tile.openstreetmap.org/{z}/{x}/{y}.png";
await automationPipeline.IngestAsync(tileUrl); // NEVER DO THIS
// ❌ PROHIBITED: Making decisions based on untrusted GeoJSON
var externalGeoJson = await httpClient.GetAsync("https://external-source.com/map.json");
var decision = MakeCriticalDecision(externalGeoJson); // NEVER DO THISIf you believe you need to use map data with AI/ML systems:
1. Stop and re-evaluate your architecture 2. Create a separate server-side ingestion pipeline 3. Implement complete validation and sanitization 4. Get explicit security review and approval 5. Implement human review gates before AI processing 6. Maintain comprehensive audit trails
---
Quick Start Example
// Basic map setup in Blazor (use validated tile URL or local tiles in production)
@page "/maps-demo"
@using Syncfusion.Blazor.Maps
<SfMaps>
<MapsLayers>
<!-- ✅ SAFE: Use local bundled tiles (recommended for production) -->
<MapsLayer UrlTemplate="@TileUrl">
</MapsLayer>
</MapsLayers>
</SfMaps>
@code {
// SAFE: Host tiles locally or use a validated, domain-restricted provider
private string TileUrl = "/tiles/{level}/{tileX}/{tileY}.png"; // local/cached tiles
// This data stays in the UI layer only - NEVER forwarded to agents or LLMs
}Common Patterns
Pattern 1: Adding Markers to a Map
<SfMaps>
<MapsLayers>
<MapsLayer TValue="MarkerData" UrlTemplate="@TileUrl">
<MapsMarkerSettings>
<MapsMarker TValue="MarkerData" Latitude="37.368" Longitude="-122.095"
Width="15" Height="15">
</MapsMarker>
</MapsMarkerSettings>
</MapsLayer>
</MapsLayers>
</SfMaps>
@code {
public class MarkerData
{
public double Latitude { get; set; }
public double Longitude { get; set; }
}
}Pattern 2: Binding Data with Color Mapping
<SfMaps>
<MapsLayers>
<MapsLayer ShapeDataSource="@ShapeData"
ShapePropertyPath="@ShapePropertyPath"
DataSource="@DataSource" TValue="DataType">
<MapsShapeSettings ColorValuePath="Population">
<MapsShapeColorMappings>
<MapsShapeColorMapping From="0" To="50000" Color="#B3E5FC"></MapsShapeColorMapping>
<MapsShapeColorMapping From="50000" To="100000" Color="#81D4FA"></MapsShapeColorMapping>
</MapsShapeColorMappings>
</MapsShapeSettings>
</MapsLayer>
</MapsLayers>
</SfMaps>Pattern 3: Handling Map Click Events
<SfMaps @ref="mapInstance" OnShapeSelected="ShapeSelected"
OnMarkerClick="MarkerClicked">
<MapsLayers>
<MapsLayer UrlTemplate="@TileUrl">
</MapsLayer>
</MapsLayers>
</SfMaps>
@code {
private SfMaps mapInstance;
private void MarkerClicked(MarkerClickEventArgs args)
{
Console.WriteLine($"Marker clicked at: {args.Latitude}, {args.Longitude}");
}
private void ShapeSelected(ShapeSelectedEventArgs args)
{
Console.WriteLine($"Shape selected: {args.Data}");
}
}Key Features Summary
- Multiple Map Providers: Support for Google Maps, Bing Maps, Azure Maps, and OpenStreetMap
- Rich Geospatial Features: Markers, polygons, polylines, annotations, and bubbles
- Data Visualization: Color mapping, choropleth support, legends, and data labels
- Interactivity: Click handling, hover tooltips, zoom/pan controls, keyboard navigation
- Layer Management: Multi-layer support with visibility toggling and dynamic updates
- Export Capabilities: PNG, SVG, and PDF export with legends and labels
- Internationalization: Multi-language support and RTL text rendering
- Accessibility: WCAG compliance with keyboard navigation and screen reader support
- Customization: Theme Studio integration, CSS customization, marker styling
- Performance: Optimized rendering for large datasets and marker clustering
MANDATORY SECURITY NOTICE: Do NOT load GeoJSON, ShapeData, tile, or image resources directly from untrusted third‑party URLs at runtime. Host assets locally or return server-validated, signed URLs; validate GeoJSON/ShapeData against a strict schema, sanitize/HTML-encode properties, enforce size/complexity limits, and require human review before automated processing or forwarding to agents.
Table of Contents
- WCAG 2.1 Compliance
- Semantic HTML Structure
- Color Contrast Requirements
- Keyboard Navigation and Shortcuts
- Enable Keyboard Navigation
- Skip Links
- ARIA Attributes and Labels
- Comprehensive ARIA Implementation
- Screen Reader Support
- Text Alternatives for Visual Elements
- Descriptive Tooltips
- High Contrast Mode Support
- Detect and Apply High Contrast
- Focus Management
- Focus Indicators
- Focus Trap for Modal-Like Behavior
- Testing for Accessibility
- Accessibility Audit Checklist
- Browser DevTools Accessibility Audit
Accessibility and Advanced Topics
W011 Security Note: Accessibility examples in this topic load external map data and tiles. If the content is sourced from third parties, validate it before rendering and sanitize any text that could appear in tooltips or annotations.
WCAG 2.1 Compliance
Semantic HTML Structure
Ensure map container has proper semantic markup:
@page "/accessible-map"
@using Syncfusion.Blazor.Maps
<main>
<section role="region" aria-label="Interactive map of population density">
<h1>Population Density Map</h1>
<p>This interactive map displays population density by region.</p>
<div role="region" aria-live="polite" aria-label="Map container">
<SfMaps @ref="mapInstance">
<MapsLayers>
<MapsLayer ShapeData='new {dataOptions = "/data/world-map.json"}' TValue="string">
</MapsLayer>
</MapsLayers>
</SfMaps>
</div>
</section>
</main>
@code {
private SfMaps mapInstance;
}Color Contrast Requirements
Ensure sufficient contrast for all map elements:
<style>
/* WCAG AA: Minimum 4.5:1 contrast for normal text */
.e-maps {
color: #000000; /* High contrast */
background: #FFFFFF;
}
/* WCAG AAA: Minimum 7:1 contrast */
.e-tooltip {
color: #000000; /* Very high contrast */
background: #FFFF00;
}
/* Ensure legend is readable */
.e-legend {
color: #1A1A1A; /* Dark text */
background: #FFFFFF;
}
/* Shape colors must have sufficient contrast */
.e-shape {
fill: #0066CC; /* Accessible blue */
stroke: #000000; /* High contrast border */
}
.e-shape.high-value {
fill: #DD0000; /* WCAG AA compliant red */
}
</style>Use contrast checkers:
- WebAIM Contrast Checker
- WCAG Color Contrast Checker
- Chrome DevTools Accessibility audit
Keyboard Navigation and Shortcuts
Enable Keyboard Navigation
@page "/keyboard-accessible"
@using Syncfusion.Blazor.Maps
<div role="region" aria-label="Map keyboard navigation controls">
<h2>Keyboard Navigation Help</h2>
<ul>
<li><kbd>Tab</kbd> - Focus map controls</li>
<li><kbd>+</kbd> - Zoom in</li>
<li><kbd>-</kbd> - Zoom out</li>
<li><kbd>Arrow Keys</kbd> - Pan map</li>
<li><kbd>Home</kbd> - Reset to default view</li>
<li><kbd>Enter</kbd> - Activate focused element</li>
</ul>
</div>
<SfMaps>
<MapsZoomSettings Enable="true" ZoomFactor="2"></MapsZoomSettings>
<MapsLayers>
<!-- Use a validated TileUrl variable; prefer local/cached tiles for production -->
<MapsLayer UrlTemplate="@TileUrl" TValue="string">
</MapsLayer>
</MapsLayers>
</SfMaps>
Skip Links
Allow users to skip to map content:
<!-- Place at top of page -->
<a href="#map-content" class="skip-link">Skip to map content</a>
<style>
/* Hide skip link but visible on focus */
.skip-link {
position: absolute;
left: -9999px;
z-index: 999;
}
.skip-link:focus {
position: fixed;
top: 0;
left: 0;
background: #000;
color: #FFF;
padding: 8px;
z-index: 999;
}
</style>ARIA Attributes and Labels
Comprehensive ARIA Implementation
@page "/aria-map"
@using Syncfusion.Blazor.Maps
<div role="region" aria-labelledby="map-title" aria-describedby="map-description">
<h1 id="map-title">Global Temperature Map</h1>
<p id="map-description">
Interactive choropleth map showing average temperature by region.
Use keyboard arrows to pan, +/- to zoom. Click regions for details.
</p>
<SfMaps @ref="mapInstance">
<MapsZoomSettings Enable="true" ZoomFactor="4"></MapsZoomSettings>
<MapsLayers>
<MapsLayer ShapeData='new {dataOptions = "/data/world-map.json"}' TValue="TemperatureRegion" DataSource="@TemperatureData">
<MapsShapeSettings ColorValuePath="Temperature">
<MapsShapeColorMappings>
<MapsShapeColorMapping StartRange="-20" EndRange="0" Color='new string[] { "#4575B4" }' />
<MapsShapeColorMapping StartRange="0" EndRange="15" Color='new string[] { "#91BFDB" }' />
<MapsShapeColorMapping StartRange="15" EndRange="25" Color='new string[] { "#FEE090" }' />
<MapsShapeColorMapping StartRange="25" EndRange="40" Color='new string[] { "#F46D43" }' />
</MapsShapeColorMappings>
</MapsShapeSettings>
<MapsDataLabelSettings Visible="true" LabelPath="RegionName">
</MapsDataLabelSettings>
</MapsLayer>
</MapsLayers>
<MapsLegendSettings Visible="true" />
</SfMaps>
</div>
@code {
private SfMaps mapInstance;
private List<TemperatureRegion> TemperatureData = new();
public class TemperatureRegion
{
public string RegionName { get; set; }
public double Temperature { get; set; }
}
}Screen Reader Support
Text Alternatives for Visual Elements
@page "/screen-reader-friendly"
@using Syncfusion.Blazor.Maps
<!-- Alternative text representation -->
<details>
<summary>Text description of map (for screen readers)</summary>
<table>
<thead>
<tr>
<th>Region</th>
<th>Population</th>
<th>Density</th>
</tr>
</thead>
<tbody>
@foreach (var region in RegionData)
{
<tr>
<td>@region.Name</td>
<td>@region.Population.ToString("N0")</td>
<td>@region.Density.ToString("F1") per km</td>
</tr>
}
</tbody>
</table>
</details>
<SfMaps @ref="mapInstance">
<MapsZoomSettings ZoomFactor="1"></MapsZoomSettings>
<MapsLayers>
<MapsLayer ShapeData='new {dataOptions= "/data/usa-map.json"}' TValue="RegionInfo" DataSource="@RegionData">
<MapsDataLabelSettings Visible="true" LabelPath="name">
</MapsDataLabelSettings>
</MapsLayer>
</MapsLayers>
</SfMaps>
@code {
private SfMaps mapInstance;
// Use a validated tile URL in production; prefer bundling tiles locally
private string TileUrl = "/tiles/{level}/{tileX}/{tileY}.png";
}
private List<RegionInfo> RegionData = new()
{
new RegionInfo { Name = "Texas", Population = 5000000, Density = 120 },
new RegionInfo { Name = "Region B", Population = 3000000, Density = 85 }
};
public class RegionInfo
{
public string Name { get; set; }
public int Population { get; set; }
public double Density { get; set; }
}
}Descriptive Tooltips
<MapsMarker Visible="true" Shape="Syncfusion.Blazor.Maps.MarkerType.Circle" Fill="white" Width="20"
DataSource="HighestPopulation" TValue="City">
<MapsMarkerBorder Width="2" Color="#333"></MapsMarkerBorder>
<MapsMarkerTooltipSettings Visible="true" ValuePath="Name"></MapsMarkerTooltipSettings>
</MapsMarker>
</MapsMarkerSettings>Testing for Accessibility
Accessibility Audit Checklist
- [ ] Keyboard Navigation: All interactive elements accessible via Tab/Shift+Tab
- [ ] Focus Indicators: Clear visual focus indicator on all elements
- [ ] Color Contrast: All text meets WCAG AA (4.5:1) minimum
- [ ] ARIA Labels: All regions and interactive elements properly labeled
- [ ] Alt Text: Meaningful descriptions for all visual content
- [ ] Heading Structure: Proper heading hierarchy (h1 > h2 > h3)
- [ ] Link Text: Links have descriptive text (avoid "click here")
- [ ] Form Labels: All inputs associated with labels
- [ ] Error Messages: Clear, helpful error descriptions
- [ ] Skip Links: Users can skip repetitive content
- [ ] Zoom: Page works at 200% zoom
- [ ] Motion: No content that flashes more than 3 times/second
- [ ] Screen Reader: Tested with NVDA, JAWS, or VoiceOver
Browser DevTools Accessibility Audit
// Run in browser console
// Chrome: Lighthouse, Edge: DevTools Accessibility
// Firefox: WAVE extension
// All browsers: axe DevTools extensionAPI Reference - Syncfusion Maps for Blazor
Complete API reference for the Syncfusion Blazor Maps component, including all classes, interfaces, enums, and events.
MANDATORY SECURITY NOTICE: Do NOT load GeoJSON, ShapeData, tile, or image resources directly from untrusted third‑party URLs at runtime. Host assets locally or return server-validated, signed URLs; validate GeoJSON/ShapeData against a strict schema, sanitize/HTML-encode properties, enforce size/complexity limits, and require human review before automated processing or forwarding to agents.
Table of Contents
- Main Component
- SfMaps
- Core Components
- MapsMarker<TValue>
- MapsLayer<TValue>
- Configuration Classes
- MapsMargin
- MapsTitleSettings
- MapsSubtitleSettings
- MapsLegendSettings
- MapsZoomSettings
- MapsAreaSettings
- MapsSelectionSettings
- MapsHighlightSettings
- MapsTooltipSettings
- MapsMarkerSettings
- MapsMarkerClusterSettings
- MapsBubbleSettings
- MapsShapeSettings
- MapsDataLabelSettings
- MapsAnnotation
- MapsNavigationLine
- MapsPolygon
- Event Arguments
- MarkerClickEventArgs
- MarkerDragStartEventArgs
- MarkerDragEndEventArgs
- MarkerMoveEventArgs
- BubbleClickEventArgs
- ShapeSelectedEventArgs
- SelectionEventArgs
- MapZoomEventArgs
- MapPanEventArgs
- LabelRenderingEventArgs
- LayerRenderingEventArgs
- ShapeRenderingEventArgs
- MarkerRenderingEventArgs
- BubbleRenderingEventArgs
- AnimationCompleteEventArgs
- TooltipRenderEventArgs
- LegendRenderingEventArgs
- PrintEventArgs
- ResizeEventArgs
- LoadEventArgs
- LoadedEventArgs
- AnnotationRenderingEventArgs
- Interfaces
- ILayer
- IMarker
- IBubble
- Enums
- MarkerType
- ExportType
- ProjectionType
- GeometryType
- LegendPosition
- LegendMode
- LegendType
- LegendArrangement
- LegendShape
- Alignment
- Orientation
- TooltipGesture
- BubbleType
- SmartLabelMode
- IntersectAction
- LabelPosition
- ArrowPosition
- PolygonShapeType
- PanDirection
- ToolbarItem
- Type
- Properties Quick Reference
- Map Container Properties
- Interactive Properties
- Display Properties
- Marker Properties
- Shape Properties
Main Component
SfMaps
The primary Maps component for rendering interactive geospatial visualizations.
Namespace: Syncfusion.Blazor.Maps
Basic Usage:
@using Syncfusion.Blazor.Maps
<SfMaps @ref="mapInstance">
<MapsEvents ShapeSelected="@ShapeSelectedEvent"></MapsEvents>
<MapsLayers>
<!-- In production, bundle GeoJSON locally or validate external sources. Example uses local path: /data/world-map.json -->
<MapsLayer ShapeData='new {dataOptions= "/data/world-map.json"}' TValue="string">
<MapsLayerSelectionSettings Enable="true" Fill="green">
<MapsLayerSelectionBorder Color="White" Width="2"></MapsLayerSelectionBorder>
</MapsLayerSelectionSettings>
</MapsLayer>
</MapsLayers>
</SfMaps>
@code {
SfMaps mapInstance;
public void ShapeSelectedEvent(Syncfusion.Blazor.Maps.ShapeSelectedEventArgs args)
{
// Here you can customize your code
}
}Key Properties:
| Property | Type | Default | Description |
|---|---|---|---|
ZoomLevel | int | 1 | Initial zoom level (1-20) |
Width | string | "100%" | Container width |
Height | string | "400px" | Container height |
Margin | MapsMargin | null | Map margins (Top, Bottom, Left, Right) |
Orientation | Orientation | Orientation.Portrait | Layout orientation |
BaseLayerIndex | int | 0 | Index of base tile layer |
EnableLegend | bool | true | Show/hide legend |
EnableNavigation | bool | false | Show/hide navigation lines |
AllowImageExport | bool | true | Enable PNG/SVG export functionality |
AllowPdfExport | bool | true | Enable PDF export functionality |
AllowPrint | bool | true | Enable map printing |
EnablePersistence | bool | false | Save and restore map state (zoom, pan, selection) |
ProjectionType | ProjectionType | Mercator | Map projection type (Mercator, EquirectangularProjection, GnomnicProjection, PolyconicProjection, MercatorSpherical) |
Theme | string | "Material" | Visual theme (Material, Fabric, Bootstrap, Bootstrap4, Bootstrap5, HighContrast, FluentDark) |
TitleSettings | MapsTitleSettings | null | Title configuration |
SubtitleSettings | MapsSubtitleSettings | null | Subtitle configuration |
LegendSettings | MapsLegendSettings | null | Legend configuration |
ZoomSettings | MapsZoomSettings | null | Zoom behavior configuration |
AreaSettings | MapsAreaSettings | null | Map area/background settings |
SelectionSettings | MapsSelectionSettings | null | Shape/marker selection behavior |
HighlightSettings | MapsHighlightSettings | null | Highlight behavior on hover |
TooltipSettings | MapsTooltipSettings | null | Tooltip configuration |
Locale | string | "en-US" | Localization identifier |
TabIndex | int | 0 | Tab index for keyboard navigation |
Background | string | "white" | Map background color |
Format | string | null | Number/date format strings for data binding |
EnableGroupingSeparator | bool | false | Add thousands separator to numbers |
Description | string | null | ARIA description for accessibility |
Methods:
// ✅ Refresh map rendering
mapInstance.Refresh();
// ✅ Zoom to coordinates region (Zoom to fit specific area)
await mapInstance.ZoomToCoordinates(35, -120, 40, -115); // minLat, minLng, maxLat, maxLng
// ✅ Get min/max coordinates of visible area
var visibleBounds = mapInstance.GetMinMaxLatitudeLongitude();
Console.WriteLine($"Visible area: Lat {visibleBounds.MinLatitude} to {visibleBounds.MaxLatitude}");
// ✅ Zoom by position factor (Zoom in/out from specific point)
await mapInstance.ZoomByPosition(new MapsCenterPosition { Latitude = 37, Longitude = -122 }, 1.5);
// ✅ Programmatically select shapes
await mapInstance.ShapeSelectionAsync(layerIndex: 0, propertyName: "name", name: "California", enable: true);
// ✅ Export map as image
await mapInstance.ExportAsync(ExportType.PNG, "map-export");
// ✅ Export map as SVG
await mapInstance.ExportAsync(ExportType.SVG, "map-export");
// ✅ Export map as PDF with orientation
await mapInstance.ExportAsync(ExportType.PDF, "map-export", PdfPageOrientation.Portrait);
await mapInstance.ExportAsync(ExportType.PDF, "map-export", PdfPageOrientation.Landscape);
// ✅ Print map
await mapInstance.PrintAsync();
// ✅ Get Bing Maps URL template (Static method)
string bingUrlTemplate = await SfMaps.GetBingUrlTemplate("BingMapsServiceLink_Key");Export and Print Requirements:
- Ensure
AllowImageExport="true"for PNG/SVG export - Ensure
AllowPdfExport="true"for PDF export - Ensure
AllowPrint="true"for print functionality
---
Core Components
MapsMarker<TValue>
Generic marker component for rendering markers on the map with support for data binding.
Namespace: Syncfusion.Blazor.Maps
Basic Usage:
<MapsMarker DataSource="MarkerDataSource"
TValue="City"
Shape="MarkerType.Circle"
Width="20"
Height="20"
Fill="red"
Opacity="0.8"
Visible="true"
EnableDrag="false">
</MapsMarker>
@code {
public class City
{
public double Latitude { get; set; }
public double Longitude { get; set; }
}
public List<City> MarkerDataSource = new List<City> {
};
}Key Properties:
| Property | Type | Default | Description |
|---|---|---|---|
Shape | MarkerType | Balloon | Marker shape (Circle, Rectangle, Triangle, Cross, Diamond, Image, Balloon) |
Latitude | double | - | Y-coordinate (-90 to 90) |
Longitude | double | - | X-coordinate (-180 to 180) |
Width | double | 10 | Marker width in pixels |
Height | double | 10 | Marker height in pixels |
Fill | string | #FF471A | Marker color (hex or named) |
Opacity | double | 1 | Transparency (0-1) |
ImageUrl | string | null | Custom image URL (when Shape is Image) |
Visible | bool | true | Show/hide marker |
EnableDrag | bool | false | Allow marker dragging |
AnimationDuration | double | 1000 | Animation duration in milliseconds |
AnimationDelay | double | 0 | Animation delay in milliseconds |
OffsetX | double | 0 | Horizontal offset from longitude |
OffsetY | double | 0 | Vertical offset from latitude |
DashArray | string | null | Dash pattern for marker outline |
Data Binding Properties:
| Property | Type | Description |
|---|---|---|
DataSource | IEnumerable<object> | Collection of marker data |
LatitudeValuePath | string | Field for latitude values |
LongitudeValuePath | string | Field for longitude values |
ColorValuePath | string | Field for dynamic marker color |
WidthValuePath | string | Field for dynamic marker width |
HeightValuePath | string | Field for dynamic marker height |
ShapeValuePath | string | Field for dynamic marker shape |
ImageUrlValuePath | string | Field for dynamic image URL |
LegendText | string | Legend label text |
MapsLayer<TValue>
Generic layer component for rendering geographic data including shapes, markers, and bubbles.
Namespace: Syncfusion.Blazor.Maps
Key Properties:
| Property | Type | Description |
|---|---|---|
UrlTemplate | string | Tile provider URL template for base maps |
Type | Type | Layer type: GeometryNormalShape, ShapeGeometry, OSMShapeGeometry |
ShapeDataSource | object | GeoJSON data for shapes and polygons |
DataSource | object | Data for color/value mapping |
ShapePropertyPath | string | Data field for matching shapes |
ShapeSettings | MapsShapeSettings | Shape appearance configuration |
MarkerSettings | MapsMarkerSettings | Marker appearance defaults |
---
Configuration Classes
public class MapsCenterPosition
{
public double Latitude { get; set; } // -90 to 90
public double Longitude { get; set; } // -180 to 180
}MapsMargin
Defines space around map edges.
public class MapsMargin
{
public double Left { get; set; }
public double Right { get; set; }
public double Top { get; set; }
public double Bottom { get; set; }
}MapsTitleSettings
Configures the map title.
public class MapsTitleSettings
{
public string Text { get; set; }
public MapsTitleTextStyle TextStyle { get; set; }
public Alignment Alignment { get; set; }
public string Description { get; set; }
}MapsSubtitleSettings
Configures the map subtitle.
public class MapsSubtitleSettings
{
public string Text { get; set; }
public MapsSubtitleTextStyle TextStyle { get; set; }
public Alignment Alignment { get; set; }
public string Description { get; set; }
}MapsLegendSettings
Controls legend appearance and behavior.
public class MapsLegendSettings
{
public bool Visible { get; set; }
public LegendPosition Position { get; set; } // Top, Bottom, Left, Right
public LegendMode Mode { get; set; } // Default, Interactive
public LegendType Type { get; set; } // Layers, Markers, Bubbles, Shapes
public LegendArrangement Arrangement { get; set; } // Vertical, Horizontal
public double Width { get; set; }
public double Height { get; set; }
public MapsLegendBorder Border { get; set; }
public MapsLegendTextStyle TextStyle { get; set; }
public bool ToggleLegendVisibility { get; set; }
}MapsZoomSettings
Controls zoom behavior.
public class MapsZoomSettings
{
public bool EnableZoom { get; set; } // Enable/disable zooming
public bool EnableDynamicZoom { get; set; } // Dynamic zoom on interaction
public bool EnableZoomOnDoubleClick { get; set; } // Double-click to zoom
public bool EnablePinchZooming { get; set; } // Touch pinch zoom
public double MinZoom { get; set; } // Minimum zoom level
public double MaxZoom { get; set; } // Maximum zoom level
public Orientation ToolbarOrientation { get; set; } // Toolbar placement
public MapsZoomToolbarSettings ToolbarSettings { get; set; }
}MapsAreaSettings
Configures map background and borders.
public class MapsAreaSettings
{
public string Background { get; set; }
public MapsAreaBorder Border { get; set; }
}MapsSelectionSettings
Controls shape/marker selection behavior.
public class MapsSelectionSettings
{
public bool Enable { get; set; }
public string Fill { get; set; }
public double Opacity { get; set; }
public MapsSelectionSettingsBorder Border { get; set; }
public bool EnableMultiSelect { get; set; }
}MapsHighlightSettings
Controls hover highlight behavior.
public class MapsHighlightSettings
{
public bool Enable { get; set; }
public string Fill { get; set; }
public double Opacity { get; set; }
public MapsHighlightSettingsBorder Border { get; set; }
}MapsTooltipSettings
Configures tooltip appearance.
public class MapsTooltipSettings
{
public bool Visible { get; set; }
public string Template { get; set; }
public TooltipGesture Gesture { get; set; } // Click, Move
public bool EnableAnimation { get; set; }
public MapsTooltipBorder Border { get; set; }
public MapsFontSettings TextStyle { get; set; }
}MapsMarkerSettings
Configures default marker appearance.
public class MapsMarkerSettings
{
public string Fill { get; set; }
public double Opacity { get; set; }
public double Width { get; set; }
public double Height { get; set; }
public MapsMarkerBorder Border { get; set; }
public MarkerType Shape { get; set; }
public MapsMarkerTooltipSettings TooltipSettings { get; set; }
public MapsMarkerHighlightSettings HighlightSettings { get; set; }
public MapsMarkerSelectionSettings SelectionSettings { get; set; }
}MapsMarkerClusterSettings
Configures marker clustering.
public class MapsMarkerClusterSettings
{
public bool AllowClustering { get; set; }
public MarkerType Shape { get; set; }
public double Width { get; set; }
public double Height { get; set; }
public string Fill { get; set; }
public string LabelFill { get; set; }
public MapsMarkerClusterBorder Border { get; set; }
public int ClusterDistance { get; set; }
}MapsBubbleSettings
Configures bubble appearance.
public class MapsBubbleSettings
{
public string Fill { get; set; }
public double MinRadius { get; set; }
public double MaxRadius { get; set; }
public double Opacity { get; set; }
public MapsBubbleBorder Border { get; set; }
public MapsBubbleColorMappings ColorMappings { get; set; }
public MapsBubbleHighlightSettings HighlightSettings { get; set; }
public MapsBubbleSelectionSettings SelectionSettings { get; set; }
}MapsShapeSettings
Configures shape/polygon appearance.
public class MapsShapeSettings
{
public string Fill { get; set; }
public double Opacity { get; set; }
public MapsShapeBorder Border { get; set; }
public MapsShapeColorMappings ColorMappings { get; set; }
public MapsLayerHighlightSettings HighlightSettings { get; set; }
public MapsLayerSelectionSettings SelectionSettings { get; set; }
}MapsDataLabelSettings
Configures data labels on shapes.
public class MapsDataLabelSettings
{
public bool Visible { get; set; }
public string LabelPath { get; set; }
public SmartLabelMode SmartLabelMode { get; set; } // None, Trim, Hide
public IntersectAction IntersectAction { get; set; } // None, Trim, Wrap, Hide
public MapsFontSettings TextStyle { get; set; }
}MapsAnnotation
Defines annotations (text, images, circles).
public class MapsAnnotation
{
public string Content { get; set; }
public double X { get; set; }
public double Y { get; set; }
public double VerticalAlignment { get; set; }
public double HorizontalAlignment { get; set; }
public AnnotationAlignment Alignment { get; set; }
public double ZIndex { get; set; }
}MapsNavigationLine
Defines navigation lines connecting locations.
public class MapsNavigationLine
{
public double[] Latitude { get; set; }
public double[] Longitude { get; set; }
public string Color { get; set; }
public double Width { get; set; }
public double Angle { get; set; }
public string DashArray { get; set; }
public bool Visible { get; set; }
public double Opacity { get; set; }
public MapsNavigationLineHighlightSettings HighlightSettings { get; set; }
public MapsNavigationLineSelectionSettings SelectionSettings { get; set; }
}MapsPolygon
Defines polygon shapes.
public class MapsPolygon
{
public PolygonShapeType PolygonType { get; set; }
public Coordinate[] Points { get; set; }
public string Fill { get; set; }
public double Opacity { get; set; }
public MapsPolygonHighlightSettings HighlightSettings { get; set; }
public MapsPolygonSelectionSettings SelectionSettings { get; set; }
}---
Event Arguments
MarkerClickEventArgs
Triggered when marker is clicked.
public class MarkerClickEventArgs
{
public double Latitude { get; set; }
public double Longitude { get; set; }
public Dictionary<string, string> Data { get; set; }
public string Target { get; set; }
public double X { get; set; }
public double Y { get; set; }
public bool IsTouch { get; set; }
public string Value { get; set; }
}
// Usage:
private void OnMarkerClick(MarkerClickEventArgs args)
{
Console.WriteLine($"Marker clicked: ({args.Latitude}, {args.Longitude})");
}MarkerDragStartEventArgs
Triggered when marker drag starts.
public class MarkerDragStartEventArgs
{
public double Latitude { get; set; }
public double Longitude { get; set; }
public double X { get; internal set; }
public double Y { get; internal set; }
public int LayerIndex { get; internal set; }
public int MarkerIndex { get; internal set; }
public int DataIndex { get; internal set; }
}MarkerDragEndEventArgs
Triggered when marker drag ends.
public class MarkerDragEndEventArgs
{
public double Latitude { get; set; }
public double Longitude { get; set; }
public double X { get; internal set; }
public double Y { get; internal set; }
public int LayerIndex { get; internal set; }
public int MarkerIndex { get; internal set; }
public int DataIndex { get; internal set; }
public Dictionary<string, object> Data { get; set; }
}MarkerMoveEventArgs
Triggered as marker moves (drag).
public class MarkerMoveEventArgs
{
public double Latitude { get; set; }
public double Longitude { get; set; }
public Dictionary<string, string> Data { get; set; }
public string Target { get; set; }
public double X { get; set; }
public double Y { get; set; }
public bool IsTouch { get; set; }
}BubbleClickEventArgs
Triggered when bubble is clicked.
public class BubbleClickEventArgs
{
public double Latitude { get; set; }
public double Longitude { get; set; }
public Dictionary<string, string> Data { get; set; }
public double X { get; set; }
public double Y { get; set; }
}ShapeSelectedEventArgs
Triggered when shape/polygon is selected.
public class ShapeSelectedEventArgs
{
public MapsBorderSettings Border { get; set; }
public Dictionary<string, string> Data { get; set; }
public string Fill { get; set; }
public double Opacity { get; set; }
public Dictionary<string, string> ShapeData { get; set; }
public string Target { get; set; }
}SelectionEventArgs
Generic selection event.
public class SelectionEventArgs
{
public Dictionary<string, string> Data { get; set; }
public string Fill { get; set; }
public double Opacity { get; set; }
public Dictionary<string, string> ShapeData { get; set; }
public string Target { get; set; }
}MapZoomEventArgs
Triggered on zoom change.
public class MapZoomEventArgs
{
public double Scale { get; set; }
public string Type { get; set; } // "ZoomIn", "ZoomOut", or programmatic
public PointF TileTranslatePoint { get; set; }
public double TileZoomLevel { get; set; }
public PointF TranslatePoint { get; set; }
}MapPanEventArgs
Triggered on pan.
public class MapPanEventArgs
{
public double Latitude { get; set; }
public double Longitude { get; set; }
public double Scale { get; set; }
public PositionValues TileTranslatePoint { get; set; } = null!;
public double TileZoomLevel { get; set; }
public PositionValues TranslatePoint { get; set; } = null!;
}LabelRenderingEventArgs
Triggered before label rendering.
public class LabelRenderingEventArgs
{
public string Text { get; set; }
public string Fill { get; set; }
public int LayerIndex { get; set; }
public double OffsetX { get; set; }
public double OffsetY { get; set; }
}LayerRenderingEventArgs
Triggered before layer rendering.
public class LayerRenderingEventArgs
{
public double Index { get; set; }
public bool Visible { get; set; }
}ShapeRenderingEventArgs
Triggered before shape rendering.
public class ShapeRenderingEventArgs
{
public Dictionary<string, string> Data { get; set; }
public double Index { get; set; }
}MarkerRenderingEventArgs
Triggered before marker rendering.
public class MarkerRenderingEventArgs
{
public string ColorValuePath { get; set; }
public string WidthValuePath { get; set; }
public string HeightValuePath { get; set; }
public Dictionary<string, string> Data { get; set; }
public string Fill { get; set; }
public double Height { get; set; }
public string ImageUrl { get; set; }
public string ImageUrlValuePath { get; set; }
public MarkerType Shape { get; set; }
public string ShapeValuePath { get; set; }
public string Template { get; set; }
public double Width { get; set; }
}BubbleRenderingEventArgs
Triggered before bubble rendering.
public class BubbleRenderingEventArgs
{
public Dictionary<string, string> Data { get; set; }
public string Fill { get; set; }
public double Radius { get; set; }
public double CenterX { get; set; }
public double CenterY { get; set; }
}AnimationCompleteEventArgs
Triggered when animation completes.
public class AnimationCompleteEventArgs
{
public DOM Element { get; set; }
}TooltipRenderEventArgs
Triggered before tooltip rendering.
public class TooltipRenderEventArgs
{
public Dictionary<string, string> Data { get; set; }
public string Fill { get; set; }
public string Content { get; set; }
}LegendRenderingEventArgs
Triggered before legend rendering.
public class LegendRenderingEventArgs
{
public string Text { get; set; }
public string Fill { get; set; }
public LegendShape Shape { get; set; }
}PrintEventArgs
Triggered before print.
public class PrintEventArgs
{
public bool Cancel { get; set; }
}ResizeEventArgs
Triggered on map resize.
public class ResizeEventArgs
{
public SizeF CurrentSize { get; set; }
public SizeF PreviousSize { get; set; }
}LoadEventArgs
Triggered before map load.
public class LoadEventArgs
{
public bool Cancel { get; set; }
}LoadedEventArgs
Triggered after map load.
public class LoadedEventArgs
{
public object Maps { get; set; }
}AnnotationRenderingEventArgs
Triggered before annotation rendering.
public class AnnotationRenderingEventArgs
{
public bool Cancel { get; set; }
}---
Interfaces
ILayer
Represents a layer in the map.
public interface ILayer
{
string Type { get; set; }
object ShapeData { get; set; }
object DataSource { get; set; }
}IMarker
Represents a marker.
public interface IMarker
{
double Latitude { get; set; }
double Longitude { get; set; }
MarkerType MarkerType { get; set; }
}IBubble
Represents a data bubble.
public interface IBubble
{
object Data { get; set; }
double Radius { get; set; }
}---
Enums
MarkerType
Defines marker shapes.
public enum MarkerType
{
Circle, // Circular marker
Rectangle, // Square/rectangular marker
Triangle, // Triangular marker
Cross, // Plus/cross marker
Diamond, // Diamond-shaped marker
Image, // Custom image marker
Balloon // Balloon/callout shape
}ExportType
Defines export formats.
public enum ExportType
{
PNG, // Export as PNG image
SVG, // Export as SVG vector
PDF // Export as PDF document
}ProjectionType
Defines map projections.
public enum ProjectionType
{
Mercator, // Web Mercator (default)
Winkel3,
Miller,
Eckert3,
Eckert5,
Eckert6,
AitOff,
Equirectangular
}GeometryType
Defines GeoJSON geometry types.
public enum GeometryType
{
Geographic,
Normal
}LegendPosition
Defines legend placement.
public enum LegendPosition
{
Top,
Bottom,
Left,
Right,
Float
}LegendMode
Defines legend rendering mode.
public enum LegendMode
{
Default, // Static legend
Interactive // Interactive/togglable legend
}LegendType
Defines which elements are represented in legend.
public enum LegendType
{
Layers,
Markers,
Bubbles
}LegendArrangement
Defines legend item layout.
public enum LegendArrangement
{
Vertical, // Items stacked vertically
Horizontal // Items arranged horizontally
}LegendShape
Defines shape used in legend items.
public enum LegendShape
{
Circle,
Rectangle,
Triangle,
Diamond,
Cross,
Star,
HorizontalLine,
VerticalLine,
Pentagon,
Balloon,
InvertedTriangle
}Alignment
Defines text/element alignment.
public enum Alignment
{
Near, // Left/Top
Center,
Far // Right/Bottom
}Orientation
Defines layout orientation.
public enum Orientation
{
Portrait,
Landscape
}TooltipGesture
Defines interaction for tooltip display.
public enum TooltipGesture
{
Click, // Show on click
Move // Show on hover/move
}BubbleType
Defines bubble sizing.
public enum BubbleType
{
Circle, // Circular bubble
Square // Square bubble
}SmartLabelMode
Defines data label handling strategies.
public enum SmartLabelMode
{
None, // No adjustment
Trim, // Truncate overflow text
Hide, // Hide labels that overlap
Wrap // Wrap text to multiple lines
}IntersectAction
Defines label intersection handling.
public enum IntersectAction
{
None, // No adjustment
Trim, // Truncate text
Wrap, // Wrap to lines
Hide // Hide label
}LabelPosition
Defines label placement relative to legend.
public enum LabelPosition
{
Before,
After
}ArrowPosition
Defines arrow placement on navigation line.
public enum ArrowPosition
{
Start, // Arrow at line start
End, // Arrow at line end
Both // Arrows at both ends
}PolygonShapeType
Defines polygon shape types.
public enum PolygonShapeType
{
Polygon,
LineString
}PanDirection
Defines pan direction.
public enum PanDirection
{
Left,
Right,
Top,
Bottom,
None
}ToolbarItem
Defines zoom toolbar buttons.
public enum ToolbarItem
{
ZoomIn,
ZoomOut,
Reset,
Zoom,
Pan
}Type
Defines layer data type.
public enum Type
{
Layer,
SubLayer
}---
Properties Quick Reference
Map Container Properties
| Property | Type | Purpose |
|---|---|---|
Width | string | Container width (e.g., "100%", "800px") |
Height | string | Container height (e.g., "600px", "100vh") |
Background | string | Background color |
Margin | MapsMargin | Map margins |
CenterPosition | MapsCenterPosition | Initial center coordinates |
ZoomLevel | int | Initial zoom (1-20) |
MinZoom | double | Minimum zoom allowed |
MaxZoom | double | Maximum zoom allowed |
Interactive Properties
| Property | Type | Purpose |
|---|---|---|
EnableZoom | bool | Allow zoom |
EnableZoomOnDoubleClick | bool | Zoom on double-click |
EnablePinchZooming | bool | Touch pinch zoom |
EnableDynamicZoom | bool | Dynamic zoom interaction |
EnableNavigation | bool | Show navigation controls |
EnableLegend | bool | Show legend |
EnableSelection | bool | Allow shape selection |
EnableHighlight | bool | Hover highlight effect |
Display Properties
| Property | Type | Purpose |
|---|---|---|
TitleSettings | MapsTitleSettings | Main title |
SubtitleSettings | MapsSubtitleSettings | Subtitle |
LegendSettings | MapsLegendSettings | Legend configuration |
TooltipSettings | MapsTooltipSettings | Tooltip settings |
AreaSettings | MapsAreaSettings | Background/border |
Marker Properties
| Property | Type | Purpose |
|---|---|---|
Fill | string | Marker color |
Width | double | Marker width |
Height | double | Marker height |
BorderColor | string | Border color |
BorderWidth | double | Border width |
Opacity | double | Transparency (0-1) |
Shape | MarkerType | Shape type |
ImageUrl | string | Custom image URL |
Shape Properties
| Property | Type | Purpose |
|---|---|---|
Fill | string | Shape color |
Stroke | string | Border color |
StrokeWidth | double | Border width |
Opacity | double | Transparency |
ColorValuePath | string | Data field for color mapping |
ValuePath | string | Data field for values |
---
For complete API documentation, visit the Official Syncfusion Blazor Maps API Reference
Customization and Styling
MANDATORY SECURITY NOTICE: Do NOT load GeoJSON, ShapeData, tile, or image resources directly from untrusted third‑party URLs at runtime. Host assets locally or return server-validated, signed URLs; validate GeoJSON/ShapeData against a strict schema, sanitize/HTML-encode properties, enforce size/complexity limits, and require human review before automated processing or forwarding to agents.
COMMAND_EXECUTION WARNING (IJSRuntime): Dynamic CSS theme switching uses IJSRuntime to manipulate the DOM (adding/removing stylesheet links). Ensure theme URLs come from your application only. Never allow external or user-controlled URLs for stylesheets. Validate all CSS injection points and use CSP headers to prevent unauthorized script execution. Always use rel="stylesheet" and verify the href is from a trusted source before injecting via JavaScript.Table of Contents
- Themes and Visual Styles
- SfMaps Theme Property (NEW - Previously Missing)
- CSS Class Customization
- Targeting Map Elements with CSS
- API Reference for Styling
- MapsFontSettings
- MapsTitleSettings & MapsSubtitleSettings
- MapsMargin
- Border Classes
- MapsAreaSettings
- Highlight and Selection Settings
- MapsLegendSettings for Styling
- MapsTooltipSettings
- CSS Class Customization
- Marker Custom Styling
- Shape Custom Styling
- Theme Studio Integration
- Using Default Themes
- Switching Themes Dynamically
- Theme Studio Custom Themes
- Marker and Shape Styling
- Individual Marker Styling
- Conditional Marker Styling
- Shape Styling with Color Gradients
- Map Controls Styling
- Navigation Buttons
- Custom Control Positioning
- Dark Mode and Responsive Design
- Dark Mode Implementation
- Responsive Container
Themes and Visual Styles
SfMaps Theme Property (NEW - Previously Missing)
Apply predefined visual themes to your maps:
<SfMaps Theme="Theme.Bootstrap5">
<MapsLayers>
<!-- Use validated TileUrl variable or local tiles in production -->
<MapsLayer UrlTemplate="@TileUrl" TValue="string">
</MapsLayer>
</MapsLayers>
</SfMaps>Available Themes:
| Theme | Description | Best For |
|---|---|---|
Theme.Material | Material Design theme | Modern apps, Google-inspired look |
Theme.Fabric | Microsoft Fabric design | Microsoft ecosystem integration |
Theme.Bootstrap | Bootstrap 4 theme | Bootstrap-based applications |
Theme.Bootstrap4 | Bootstrap 4 specific | Legacy Bootstrap 4 projects |
Theme.Bootstrap5 | Bootstrap 5 theme | Latest Bootstrap projects |
Theme.HighContrast | High contrast theme | Accessibility, low-vision users |
Theme.FluentDark | Fluent Dark theme | Dark mode applications, Microsoft Fluent |
Theme Application:
// In your Blazor component
<SfMaps Theme="Theme.Bootstrap5" Width="100%" Height="600px">
<!-- Map configuration -->
</SfMaps>Themeing with Multiple Components:
<!-- Apply theme to all Syncfusion components in layout -->
<!-- In App.razor or Layout.razor -->
<SyncfusionBlazor Theme="Bootstrap5">
<!-- All Syncfusion components use Bootstrap5 theme -->
@Body
</SyncfusionBlazor>---
CSS Class Customization
Targeting Map Elements with CSS
The Syncfusion Maps component renders with specific CSS classes you can override:
<!-- In your CSS file or style block -->
<style>
/* Target the main map container */
.e-maps {
background-color: #f5f5f5;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
/* Target map layers */
.e-layer {
opacity: 0.9;
}
/* Target markers */
.e-marker {
filter: drop-shadow(0 2px 4px rgba(0,0,0,0.3));
}
/* Target shapes (polygons) */
.e-shape {
transition: fill 0.3s ease;
}
.e-shape:hover {
opacity: 0.8;
}
/* Target tooltips -->
.e-tooltip {
background-color: rgba(0,0,0,0.8) !important;
color: white;
padding: 8px 12px;
border-radius: 4px;
}API Reference for Styling
MapsFontSettings
Configure text appearance globally or for specific elements.
<MapsFontSettings Size="12px"
FontFamily="Arial, sans-serif"
FontStyle="normal"
FontWeight="normal"
Color="#333333"
Opacity="1">
</MapsFontSettings>| Property | Type | Description |
|---|---|---|
FontSize | string | Text size (e.g., "12px", "1em") |
FontFamily | string | Font name or stack |
FontStyle | string | normal, italic, oblique |
FontWeight | string | normal, bold, lighter, or 100-900 |
Color | string | Text color (hex or named) |
Opacity | double | Text transparency (0-1) |
MapsTitleSettings & MapsSubtitleSettings
Configure title and subtitle appearance.
<MapsTitleSettings Text="World Population Map"
Alignment="Alignment.Center"
Description="Population density by country">
<MapsTitleTextStyle Size="18px"
FontWeight="bold"
Color="#333333">
</MapsTitleTextStyle>
</MapsTitleSettings>
<MapsSubtitleSettings Text="2023 Data"
Alignment="Alignment.Center">
<MapsSubtitleTextStyle Size="14px"
Color="#666666">
</MapsSubtitleTextStyle>
</MapsSubtitleSettings>MapsMargin
Set space around the map.
<SfMaps>
<MapsMargin Left="50" Right="50" Top="50" Bottom="60" />
</SfMaps>Border Classes
Configure borders for various elements.
// MapsBorder - General border styling
<MapsBorder Color="#cccccc"
Width="1"
Opacity="1">
</MapsBorder>
// MapsMarkerBorder - Marker outline
<MapsMarkerBorder Color="darkblue"
Width="2"
Opacity="0.8">
</MapsMarkerBorder>
// DataLabelBorder - label outline
<MapsLayerDataLabelBorder Color="darkblue"
Width="2"
Opacity="0.8">
</MapsLayerDataLabelBorder>
// MapsShapeBorder - Shape outline
<MapsShapeBorder Color="blue"
Width="1"
Opacity="0.9">
</MapsShapeBorder>
// MapsLegendShapeBorder - legend Shape outline
<MapsLegendShapeBorder Color="blue"
Width="1"
Opacity="0.9">
</MapsLegendShapeBorder>
// MapsBubbleBorder - Bubble outline
<MapsBubbleBorder Color="blue"
Width="1"
Opacity="0.8">
</MapsBubbleBorder>MapsAreaSettings
Configure map background and outer border.
<MapsAreaSettings Background="white">
<MapsAreaBorder Color="#cccccc"
Width="2"
Opacity="1">
</MapsAreaBorder>
</MapsAreaSettings>Highlight and Selection Settings
Configure interactive element styling.
<!-- Highlight on hover -->
<MapsLayerHighlightSettings Enable="true"
Fill="yellow"
Opacity="0.5">
<MapsLayerHighlightBorder Color="orange"
Width="2">
</MapsLayerHighlightBorder>
</MapsLayerHighlightSettings>
<!-- Selection styling -->
<MapsLayerSelectionSettings Enable="true"
Fill="cyan"
Opacity="0.7">
<MapsLayerSelectionBorder Color="blue"
Width="3">
</MapsLayerSelectionBorder>
</MapsLayerSelectionSettings>
<!-- Marker hover effect -->
<MapsMarkerHighlightSettings Enable="true"
Fill="red"
Opacity="0.8">
<MapsMarkerHighlightBorder Color="darkred"
Width="2">
</MapsMarkerHighlightBorder>
</MapsMarkerHighlightSettings>
<!-- Bubble hover effect -->
<MapsBubbleHighlightSettings Enable="true"
Fill="red"
Opacity="0.8">
<MapsBubbleHighlightBorder Color="darkred"
Width="2">
</MapsBubbleHighlightBorder>
</MapsBubbleHighlightSettings>MapsLegendSettings for Styling
Configure legend appearance.
<MapsLegendSettings Visible="true"
Position="LegendPosition.Bottom"
Arrangement="LegendArrangement.Vertical">
<MapsLegendBorder Color="#cccccc"
Width="1"
Opacity="1">
</MapsLegendBorder>
<MapsLegendShapeBorder Color="#cccccc"
Width="1"
Opacity="1">
</MapsLegendShapeBorder>
<MapsLegendTextStyle Size="12px"
Color="#333333">
</MapsLegendTextStyle>
<MapsLegendTitle Text="Legend">
<MapsLegendTitleStyle Size="14px"
FontWeight="bold">
</MapsLegendTitleStyle>
</MapsLegendTitle>
</MapsLegendSettings>MapsTooltipSettings
Style tooltips globally.
<MapsTooltipSettings Visible="true">
<MapsTooltipBorder Color="black"
Width="1"
Opacity="1">
</MapsTooltipBorder>
<MapsTooltipTextStyle Size="12px"
Color="white">
</MapsTooltipTextStyle>
</MapsTooltipSettings>Marker Custom Styling
@using Syncfusion.Blazor.Maps
<SfMaps>
<MapsLayers>
<!-- Use local or validated GeoJSON in production -->
<MapsLayer ShapeData='new {dataOptions= "/data/world-map.json"}' TValue="string">
<MapsMarkerSettings>
<MapsMarker Visible="true" Datasource="@MarkerData" TValue="MapMarkerDataSource"
Shape="Syncfusion.Blazor.Maps.MarkerType.Circle" Width="15" Height="15">
</MapsMarker>
</MapsMarkerSettings>
</MapsLayer>
</MapsLayers>
</SfMaps>
@code {
public class MapMarkerDataSource
{
public double Latitude { get; set; }
public double Longitude { get; set; }
};
public List<MapMarkerDataSource> MarkerData = new List<MapMarkerDataSource>
{
new MapMarkerDataSource { Latitude = 47.60621, Longitude = -122.332071 }
};
}Shape Custom Styling
@using Syncfusion.Blazor.Maps
<SfMaps>
<MapsLayers>
<MapsLayer ShapeData='new {dataOptions= "/data/world-map.json"}' TValue="string">
<MapsMarkerSettings>
<MapsMarker Visible="true" Datasource="@MarkerData" TValue="MapMarkerDataSource"
Shape="Syncfusion.Blazor.Maps.MarkerType.Circle" Width="15" Height="15" Fill="lightblue">
</MapsMarker>
</MapsMarkerSettings>
</MapsLayer>
</MapsLayers>
</SfMaps>
@code {
public class MapMarkerDataSource
{
public double Latitude { get; set; }
public double Longitude { get; set; }
};
public List<MapMarkerDataSource> MarkerData = new List<MapMarkerDataSource>
{
new MapMarkerDataSource { Latitude = 47.60621, Longitude = -122.332071 }
};
}Theme Studio Integration
Switching Themes Dynamically
@page "/theme-switcher"
@using Syncfusion.Blazor.Maps
@inject IJSRuntime JS
<div style="margin-bottom: 20px;">
<button @onclick='() => SwitchTheme("bootstrap5")'>Bootstrap</button>
<button @onclick='() => SwitchTheme("material")'>Material</button>
<button @onclick='() => SwitchTheme("fabric")'>Fabric</button>
<button @onclick='() => SwitchTheme("tailwind")'>Tailwind</button>
</div>
<SfMaps @ref="mapInstance" Theme="Theme">
<MapsZoomSettings ZoomFactor="1"></MapsZoomSettings>
<MapsLayers>
<!-- Use local or validated GeoJSON in production -->
<MapsLayer ShapeData='new {dataOptions= "/data/world-map.json"}' TValue="string">
</MapsLayer>
</MapsLayers>
</SfMaps>
@code {
private SfMaps mapInstance;
Syncfusion.Blazor.Theme Theme;
private async Task SwitchTheme(string theme)
{
Theme = theme == "bootstrap5" ? Syncfusion.Blazor.Theme.Bootstrap5 : theme == "material" ? Syncfusion.Blazor.Theme.Material : theme == "fabric" ? Syncfusion.Blazor.Theme.Fabric : Syncfusion.Blazor.Theme.Tailwind;
}
}JavaScript helper (in your wwwroot/js/app.js):
window.removeThemeLink = function() {
const link = document.querySelector('link[rel="stylesheet"][href*="Syncfusion"]');
if (link) {
link.remove();
}
};
window.addThemeLink = function(url) {
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = url;
document.head.appendChild(link);
};Theme Studio Custom Themes
Create custom themes with Syncfusion Theme Studio:
1. Go to Theme Studio 2. Customize colors, fonts, spacing 3. Export CSS file 4. Add to your wwwroot/css/ folder
<!-- Your custom theme -->
<link href="css/custom-theme.css" rel="stylesheet" />Marker and Shape Styling
Individual Marker Styling
<MapsMarker DataSource="@MarkerData"
Shape="MarkerType.Circle"
Width="20" Height="20"
Fill="red"
OffsetX="20"
OffsetY="20"
Opacity="0.8"
Visible="true">
</MapsMarker>Conditional Marker Styling
Style markers based on data:
@page "/conditional-markers"
@using Syncfusion.Blazor.Maps
<SfMaps>
<MapsLayers>
<!-- Use local or validated GeoJSON in production -->
<MapsLayer ShapeData='new {dataOptions= "/data/world-map.json"}' TValue="string">
<MapsMarkerSettings>
<MapsMarker DataSource="@LocationOne" Visible="true"
Shape="Syncfusion.Blazor.Maps.MarkerType.Circle"
Width="20" Height="20"
Fill="red" TValue="LocationData">
</MapsMarker>
<MapsMarker DataSource="@LocationTwo" Visible="true"
Shape="Syncfusion.Blazor.Maps.MarkerType.Circle"
Width="20" Height="20"
Fill="red" TValue="LocationData">
</MapsMarker>
</MapsMarkerSettings>
</MapsLayer>
</MapsLayers>
</SfMaps>
@code {
private List<LocationData> LocationOne = new()
{
new LocationData { Latitude = 37.368, Longitude = -122.095, Name = "SF", Value = 75 },
new LocationData { Latitude = 40.7128, Longitude = -74.0060, Name = "NYC", Value = 45 }
};
private List<LocationData> LocationTwo = new()
{
new LocationData { Latitude = 34.0522, Longitude = -118.2437, Name = "LA", Value = 20 }
};
public class LocationData
{
public double Latitude { get; set; }
public double Longitude { get; set; }
public string Name { get; set; }
public int Value { get; set; }
}
}Shape Styling with Color
<MapsShapeSettings>
<MapsShapeBorder Color="darkblue" Width="2"></MapsShapeBorder>
</MapsShapeSettings>Map Controls Styling
Custom Zoom Control Positioning
@using Syncfusion.Blazor.Maps
<SfMaps>
<MapsZoomSettings Enable="true">
<MapsZoomToolbarSettings BackgroundColor="pink" BorderColor="green" BorderOpacity="1" BorderWidth="3" Orientation="Syncfusion.Blazor.Maps.Orientation.Vertical" VerticalAlignment="Syncfusion.Blazor.Maps.Alignment.Near">
<MapsZoomToolbarButton ToolbarItems="new List<Syncfusion.Blazor.Maps.ToolbarItem>() { Syncfusion.Blazor.Maps.ToolbarItem.Zoom, Syncfusion.Blazor.Maps.ToolbarItem.ZoomIn, Syncfusion.Blazor.Maps.ToolbarItem.ZoomOut, Syncfusion.Blazor.Maps.ToolbarItem.Pan, Syncfusion.Blazor.Maps.ToolbarItem.Reset }"></MapsZoomToolbarButton>
</MapsZoomToolbarSettings>
</MapsZoomSettings>
<MapsLayers>
<!-- Use local or validated GeoJSON in production -->
<MapsLayer ShapeData='new {dataOptions= "/data/world-map.json"}' TValue="string">
</MapsLayer>
</MapsLayers>
</SfMaps>Dark Mode and Responsive Design
Dark Mode Implementation
@using Syncfusion.Blazor.Maps
<button @onclick="ToggleDarkMode">Toggle Dark Mode</button>
<SfMaps Theme="@Theme">
<MapsLayers>
<!-- Use local or validated GeoJSON in production -->
<MapsLayer ShapeData='new {dataOptions= "/data/world-map.json"}' TValue="string">
</MapsLayer>
</MapsLayers>
</SfMaps>
@code {
private bool IsDarkMode = false;
private Syncfusion.Blazor.Theme Theme = Syncfusion.Blazor.Theme.Bootstrap5;
private void ToggleDarkMode()
{
IsDarkMode = !IsDarkMode;
// Toggle data-theme attribute on root element
Theme = IsDarkMode ? Syncfusion.Blazor.Theme.Bootstrap5Dark : Syncfusion.Blazor.Theme.Bootstrap5;
// Implementation depends on your framework setup
}
}Responsive Container
@using Syncfusion.Blazor.Maps
<style>
.map-container {
width: 100%;
height: 100vh;
position: relative;
}
/* Mobile devices (≤768px) */
@@media (max-width: 768px) {
.map-container {
height: 70vh;
}
.map-controls-custom {
top: 10px;
right: 10px;
}
.control-button {
padding: 8px 12px;
font-size: 14px;
}
}
/* Tablets (769px - 1024px) */
@@media (min-width: 769px) and (max-width: 1024px) {
.map-container {
height: 80vh;
}
}
/* Desktops (>1024px) */
@@media (min-width: 1025px) {
.map-container {
height: 100vh;
}
}
</style>
<div class="map-container">
<SfMaps Width="100%" Height="100%">
<MapsZoomSettings Enable="true" ZoomFactor="4"></MapsZoomSettings>
<MapsLayers>
<MapsLayer ShapeData='new {dataOptions= "/data/world-map.json"}' TValue="string">
</MapsLayer>
</MapsLayers>
</SfMaps>
</div>
Data Visualization and Mapping
Table of Contents
- Color Mapping and Choropleth
- Basic Color Mapping
- Equal Range Intervals
- Quantile-Based Classification
- Multiple Data Fields
- Legends
- Basic Legend
- Legend with Custom Title and Labels
- Legend Positioning Options
- Toggle Legend Visibility
- Data Labels
- Labels on Shapes (Regions)
- Custom Label Formatting
- Labels on Bubbles
- Conditional Labels
- Populating Maps with Data
- Binding Data to Shapes
- Real-Time Data Updates
- API Reference for Data Visualization
- MapsShapeSettings
- MapsShapeColorMapping
- MapsDataLabelSettings
- MapsLegendSettings
- MapsBubbleSettings
- MapsColorMapping
- Advanced Data Binding
- Multiple Data Sources
- Aggregated Data Visualization
- Data Filtering by Attribute
Color Mapping and Choropleth
Color mapping visualizes data values across geographic regions by applying colors based on data ranges. This technique (called choropleth) is perfect for displaying statistics like population density, income levels, or disease prevalence by region.
MANDATORY SECURITY NOTICE: GeoJSON and tile data examples in this document are for demonstration only. In production you MUST either host GeoJSON/tiles locally (for example underwwwroot/dataorwwwroot/tiles) or serve them through a server-side proxy that:
>
- validates provider host against an allow‑list and requires HTTPS,
- verifies content-type and GeoJSON structure against a strict schema,
- enforces maximum file size and feature-count limits,
- strips or HTML-encodes properties (tooltips/annotations) to remove markup and scripts,
- normalizes coordinates and limits geometry complexity, and
- issues short‑lived signed URLs/tokens for client consumption (do NOT embed provider API keys in client code).
>
NEVER forward raw ShapeData, tooltips, or annotation content to automated agents or LLM prompts without server-side validation, sanitization, and documented human review. See readme-security for required validation templates and deployment checklist.Basic Color Mapping
@page "/choropleth-map"
@using Syncfusion.Blazor.Maps
<SfMaps>
<MapsLayers>
<MapsLayer TValue="StateData"
ShapeData='new { dataOptions = "/data/usa-map.json" }'
DataSource="@StateDataSource"
ShapeDataPath="Name"
ShapePropertyPath='new string[] { "name" }'>
<MapsShapeSettings Fill="#E5E5E5" ColorValuePath="Population">
<MapsShapeColorMappings>
<MapsShapeColorMapping StartRange="0" EndRange="1000000" Color='new string[] { "#B3E5FC" }'>
</MapsShapeColorMapping>
<MapsShapeColorMapping StartRange="1000000" EndRange="5000000" Color='new string[] { "#81D4FA" }'>
</MapsShapeColorMapping>
<MapsShapeColorMapping StartRange="5000000" EndRange="10000000" Color='new string[] { "#4FC3F7" }'>
</MapsShapeColorMapping>
<MapsShapeColorMapping StartRange="10000000" EndRange="30000000" Color='new string[] { "#29B6F6" }'>
</MapsShapeColorMapping>
</MapsShapeColorMappings>
</MapsShapeSettings>
</MapsLayer>
</MapsLayers>
</SfMaps>
@code {
private object StateGeoJson;
private List<StateData> StateDataSource = new()
{
new StateData { Name = "California", Population = 39000000 },
new StateData { Name = "Texas", Population = 29000000 },
new StateData { Name = "Florida", Population = 21500000 },
// ... more states ...
};
public class StateData
{
public string Name { get; set; }
public int Population { get; set; }
}
}Equal Range Intervals
Create equal-width ranges automatically:
<MapsShapeColorMappings>
<MapsShapeColorMapping StartRange="0" EndRange="25000" Color='new string[] { "rgb(173, 216, 230)" }'>
</MapsShapeColorMapping>
<MapsShapeColorMapping StartRange="25000" EndRange="50000" Color='new string[] { "rgb(135, 206, 250)" }'>
</MapsShapeColorMapping>
<MapsShapeColorMapping StartRange="50000" EndRange="75000" Color='new string[] { "rgb(0, 150, 255)" }'>
</MapsShapeColorMapping>
<MapsShapeColorMapping StartRange="75000" EndRange="100000" Color='new string[] { "rgb(0, 100, 200)" }'>
</MapsShapeColorMapping>
</MapsShapeColorMappings>Quantile-Based Classification
Use data quartiles for better distribution:
<MapsShapeColorMappings>
<!-- 0-25th percentile -->
<MapsShapeColorMapping StartRange="0" EndRange="500000" Color='new string[] { "#FEE5D9" }'>
</MapsShapeColorMapping>
<!-- 25-50th percentile -->
<MapsShapeColorMapping StartRange="500000" EndRange="2000000" Color='new string[] { "#FCAE91" }'>
</MapsShapeColorMapping>
<!-- 50-75th percentile -->
<MapsShapeColorMapping StartRange="2000000" EndRange="8000000" Color='new string[] { "#FB6A4A" }'>
</MapsShapeColorMapping>
<!-- 75-100th percentile -->
<MapsShapeColorMapping StartRange="8000000" EndRange="40000000" Color='new string[] { "#CB181D" }'>
</MapsShapeColorMapping>
</MapsShapeColorMappings>Multiple Data Fields
Map different fields to different color ranges:
<MapsLayer TValue="string">
<!-- First visualization: Population density -->
<MapsShapeSettings ColorValuePath="PopulationDensity">
<MapsShapeColorMappings>
<MapsShapeColorMapping StartRange="0" EndRange="100" Color='new string[] { "lightgreen" }'>
</MapsShapeColorMapping>
<MapsShapeColorMapping StartRange="100" EndRange="1000" Color='new string[] { "orange" }'>
</MapsShapeColorMapping>
</MapsShapeColorMappings>
</MapsShapeSettings>
<!-- Alternative: Unemployment rate (toggle with button) -->
@if (ShowUnemployment)
{
<MapsShapeSettings ColorValuePath="UnemploymentRate">
<MapsShapeColorMappings>
<MapsShapeColorMapping StartRange="0" EndRange="5" Color='new string[] { "lightblue" }'>
</MapsShapeColorMapping>
<MapsShapeColorMapping StartRange="5" EndRange="15" Color='new string[] { "red" }'>
</MapsShapeColorMapping>
</MapsShapeColorMappings>
</MapsShapeSettings>
}
</MapsLayer>
@code {
private bool ShowUnemployment = false;
}Legends
Legends explain the color mapping and help users interpret the visualization. They should appear clearly and update dynamically when data changes.
Basic Legend
<SfMaps>
<MapsLayers>
<MapsLayer TValue="string">
<MapsShapeSettings ColorValuePath="Population">
<MapsShapeColorMappings>
<MapsShapeColorMapping StartRange="0" EndRange="1000000" Color='new string[] { "#B3E5FC" }'>
</MapsShapeColorMapping>
<MapsShapeColorMapping StartRange="1000000" EndRange="10000000" Color='new string[] { "#0288D1" }'>
</MapsShapeColorMapping>
</MapsShapeColorMappings>
</MapsShapeSettings>
</MapsLayer>
</MapsLayers>
<MapsLegendSettings Visible="true" Position="LegendPosition.Bottom">
</MapsLegendSettings>
</SfMaps>Legend with Custom Title and Labels
<MapsLegendSettings Visible="true" Position="Syncfusion.Blazor.Maps.LegendPosition.Bottom" LabelDisplayMode="Syncfusion.Blazor.Maps.LabelIntersectAction.Hide">
<MapsLegendTitle Text="Population by State">
<MapsLegendTitleStyle Size = "16px" Color = "black" FontWeight = "bold" />
</MapsLegendTitle>
</MapsLegendSettings>Legend Positioning Options
<!-- Left -->
<MapsLegendSettings Visible="true" Position="LegendPosition.Left">
</MapsLegendSettings>
<!-- Top -->
<MapsLegendSettings Visible="true" Position="LegendPosition.Top">
</MapsLegendSettings>
<!-- Right -->
<MapsLegendSettings Visible="true" Position="LegendPosition.Right">
</MapsLegendSettings>
<!-- Left, Bottom, Right, Top, Float -->Toggle Legend Visibility
@page "/legend-toggle"
@using Syncfusion.Blazor.Maps
<button @onclick="() => ShowLegend = !ShowLegend"> Legend </button>
<SfMaps>
<MapsLayers>
<MapsLayer TValue="string">
<!-- Layer configuration -->
</MapsLayer>
</MapsLayers>
<MapsLegendSettings Visible="@ShowLegend" Position="Syncfusion.Blazor.Maps.LegendPosition.Bottom" LabelDisplayMode="Syncfusion.Blazor.Maps.LabelIntersectAction.Hide">
</MapsLegendSettings>
</SfMaps>
@code {
private bool ShowLegend = true;
}Data Labels
Data labels display text directly on map elements (regions, bubbles, markers) to show values, names, or statistics.
Labels on Shapes (Regions)
<MapsLayer ShapeData='new {dataOptions= "/data/usa-map.json"}' TValue="string">
<MapsDataLabelSettings Visible="true" LabelPath="name" />
</MapsLayer>This displays the state name on each state polygon.
Custom Label Formatting
<MapsLayer ShapeData='new {dataOptions= "/data/usa-map.json"}' TValue="string">
<MapsDataLabelSettings Visible="true" LabelPath="name">
<MapsLayerDataLabelBorder Color="green" Width="2"></MapsLayerDataLabelBorder>
<MapsLayerDataLabelTextStyle Color="blue" Size="12px" FontStyle="Sans-serif" FontWeight="normal">
</MapsLayerDataLabelTextStyle>
</MapsDataLabelSettings>
</MapsLayer>Conditional Labels
Show labels only for selected features:
@page "/conditional-labels"
@using Syncfusion.Blazor.Maps
<SfMaps>
<MapsLayers>
<MapsLayer ShapeData='new {dataOptions= "/data/usa-map.json"}' TValue="string">
<MapsDataLabelSettings Visible="@ShowAllLabels" LabelPath="name">
</MapsDataLabelSettings>
</MapsLayer>
</MapsLayers>
</SfMaps>
<button @onclick="() => ShowAllLabels = !ShowAllLabels"> Labels </button>
@code {
private bool ShowAllLabels = false;
}Populating Maps with Data
Binding Data to Shapes
Match geographic boundaries with your data:
@using Syncfusion.Blazor.Maps
<SfMaps>
<MapsLayers>
<MapsLayer ShapeData='new {dataOptions ="/data/world-map.json"}' DataSource="PopulationDetails"
ShapeDataPath="Name" ShapePropertyPath='new string[] {"name"}' TValue="PopulationDetail">
<MapsShapeSettings Fill="#E5E5E5" ColorValuePath="Density">
<MapsShapeColorMappings>
<MapsShapeColorMapping StartRange="0.00001" EndRange="100" Color='new string[] {"yellow"}' />
<MapsShapeColorMapping StartRange="100" EndRange="400" Color='new string[] {"green"}' />
</MapsShapeColorMappings>
</MapsShapeSettings>
</MapsLayer>
</MapsLayers>
</SfMaps>
@code {
public class PopulationDetail
{
public string Code { get; set; }
public double Value { get; set; }
public string Name { get; set; }
public double Population { get; set; }
public double Density { get; set; }
};
public List<PopulationDetail> PopulationDetails = new List<PopulationDetail> {
new PopulationDetail { Code = "US", Value = 34, Name ="United States", Population = 325020000, Density = 33 },
new PopulationDetail { Code ="RU", Value = 9, Name = "Russia", Population = 142905208, Density = 8.3 },
new PopulationDetail { Code = "In", Value = 384, Name = "India", Population = 1198003000, Density = 364 },
new PopulationDetail { Code = "CN", Value = 143, Name = "China", Population = 1389750000,Density = 144 }
};
}Key: ShapePropertyPath must match property names in your GeoJSON data.
Real-Time Data Updates
@page "/live-data-map"
@using Syncfusion.Blazor.Maps
@using System.Threading
<SfMaps @ref="mapInstance">
<MapsLayers>
<MapsLayer ShapeData='new {dataOptions= "/data/world-map.json"}' TValue="RegionData" DataSource="@LiveData">
<MapsShapeSettings ColorValuePath="CurrentValue">
<MapsShapeColorMappings>
<MapsShapeColorMapping StartRange="0" EndRange="50" Color='new string[] { "green" }' />
<MapsShapeColorMapping StartRange="50" EndRange="100" Color='new string[] { "red" }' />
</MapsShapeColorMappings>
</MapsShapeSettings>
</MapsLayer>
</MapsLayers>
</SfMaps>
@code {
private SfMaps mapInstance;
private List<RegionData> LiveData = new();
private PeriodicTimer updateTimer;
private CancellationTokenSource cts = new();
protected override async Task OnInitializedAsync()
{
LiveData = await LoadInitialData();
StartLiveUpdates();
}
private async void StartLiveUpdates()
{
updateTimer = new PeriodicTimer(TimeSpan.FromSeconds(5));
try
{
while (await updateTimer.WaitForNextTickAsync(cts.Token))
{
await InvokeAsync(async () =>
{
LiveData = await FetchLatestData();
mapInstance.Refresh();
});
}
}
catch (OperationCanceledException)
{
// Expected on dispose
}
}
public void Dispose()
{
cts.Cancel();
updateTimer?.Dispose();
}
private Task<List<RegionData>> LoadInitialData()
{
return Task.FromResult(new List<RegionData>());
}
private Task<List<RegionData>> FetchLatestData()
{
return Task.FromResult(new List<RegionData>());
}
public class RegionData
{
public string RegionId { get; set; }
public double CurrentValue { get; set; }
}
}API Reference for Data Visualization
MapsShapeSettings
Configure shape appearance and data mapping.
<MapsShapeSettings Fill="lightblue"
Opacity="0.7"
ColorValuePath="population"
DashArray="5,5">
<MapsShapeColorMappings>
<MapsShapeColorMapping StartRange="0" EndRange="50000" Color="#B3E5FC"></MapsShapeColorMapping>
<MapsShapeColorMapping StartRange="50000" EndRange="100000" Color="#81D4FA"></MapsShapeColorMapping>
</MapsShapeColorMappings>
</MapsShapeSettings>| Property | Type | Description |
|---|---|---|
Fill | string | Default shape color |
DashArray | string | SVG dash pattern for outline (e.g., "5,5") |
Opacity | double | Transparency (0-1) |
ColorValuePath | string | Data field for color mapping |
ValuePath | string | Data field for values |
BorderColorValuePath | string | Data field for border color |
BorderWidthValuePath | string | Data field for border width |
MapsShapeColorMapping
Maps data ranges to colors.
<MapsShapeColorMapping StartRange="0"
EndRange="50000"
Color='new string[] {"#B3E5FC"}'
Label="Low">
</MapsShapeColorMapping>| Property | Type | Description |
|---|---|---|
StartRange | double | Range minimum |
EndRange | double | Range maximum |
Color | string | Color for range (hex or named) |
Label | string | Legend label |
MapsDataLabelSettings
Configure data labels on shapes.
<MapsDataLabelSettings Visible="true"
LabelPath="name"
SmartLabelMode="Syncfusion.Blazor.Maps.SmartLabelMode.Hide"
IntersectionAction="Syncfusion.Blazor.Maps.IntersectAction.Trim">
<MapsLayerDataLabelBorder Color="green" Width="2"></MapsLayerDataLabelBorder>
<MapsLayerDataLabelTextStyle Color="blue" Size="12px" FontFamily="Arial">
</MapsLayerDataLabelTextStyle>
</MapsDataLabelSettings>| Property | Type | Description |
|---|---|---|
Visible | bool | Show/hide labels |
LabelPath | string | Data field for label text |
SmartLabelMode | SmartLabelMode | Overflow handling: None, Trim, Hide, Wrap |
IntersectAction | IntersectAction | Intersection handling |
MapsLegendSettings
Configure legend appearance.
<MapsLegendSettings Visible="true"
Position="Syncfusion.Blazor.Maps.LegendPosition.Bottom"
Mode="Syncfusion.Blazor.Maps.LegendMode.Default"
Type="Syncfusion.Blazor.Maps.LegendType.Layers"
Width="200"
Height="100">
<MapsLegendTitle Text="Population">
<MapsLegendTitleStyle Size="14px" FontWeight="bold">
</MapsLegendTitleStyle>
</MapsLegendTitle>
<MapsLegendTextStyle Size="12px">
</MapsLegendTextStyle>
</MapsLegendSettings>| Property | Type | Description |
|---|---|---|
Visible | bool | Show/hide legend |
Position | LegendPosition | Placement: Top, Bottom, Left, Right, etc. |
Mode | LegendMode | Default (static) or Interactive (clickable) |
Type | LegendType | Items shown: Layers, Markers, Bubbles, Shapes |
Orientation | LegendArrangement | Layout: Vertical or Horizontal |
Width | double | Legend width |
Height | double | Legend height |
ToggleVisibility | bool | Allow clicking items to toggle visibility |
MapsBubbleSettings
Configure bubble visualization.
@using Syncfusion.Blazor.Maps
<SfMaps>
<MapsLayers>
<MapsLayer ShapeData='new {dataOptions ="/data/world-map.json"}'
ShapeDataPath="Name" ShapePropertyPath='new string[] {"name"}' TValue="Country">
@* To add bubbles based on population count *@
<MapsBubbleSettings>
<MapsBubble Visible="true" ValuePath="Population" ColorValuePath="Color" MinRadius=20 MaxRadius=40
DataSource="PopulationDetails" TValue="Country">
</MapsBubble>
</MapsBubbleSettings>
</MapsLayer>
</MapsLayers>
</SfMaps>
@code {
public class Country
{
public string Name { get; set; }
public double Population { get; set; }
public string Color { get; set; }
};
public List<Country> PopulationDetails = new List<Country> {
new Country { Name = "Australia", Population = 325020000, Color = "#0000FF" },
new Country { Name = "Russia", Population = 142905208, Color = "#09156D" },
new Country { Name = "India", Population = 1198003000, Color = "#C2D2D6" }
};
}| Property | Type | Description |
|---|---|---|
MinRadius | double | Smallest bubble radius |
MaxRadius | double | Largest bubble radius |
ValuePath | string | Data field for bubble size |
ColorValuePath | string | Data field for bubble color |
Fill | string | Default bubble color |
Opacity | double | Transparency |
MapsColorMapping
Maps values to colors.
public class MapsColorMapping
{
public double From { get; set; }
public double To { get; set; }
public string Color { get; set; }
public string Label { get; set; }
}Advanced Data Binding
Multiple Data Sources
Layer multiple datasets on the same map:
<MapsLayers>
<!-- Population data -->
<MapsLayer TValue="PopulationData"
DataSource="@PopulationData">
<MapsShapeSettings ColorValuePath="Population">
</MapsShapeSettings>
</MapsLayer>
<!-- Economic data overlay -->
<MapsLayer TValue="EconomicData"
DataSource="@EconomicData">
<MapsShapeSettings ColorValuePath="GdpPerCapita" Opacity="0.5">
</MapsShapeSettings>
</MapsLayer>
<!-- Markers for cities -->
<MapsLayer>
<MapsMarkerSettings DataSource="@CityMarkers">
<MapsMarker Visible="true" DataSource="MarkerDataSourceOne" />
</MapsMarker>
<MapsMarker Visible="true" DataSource="MarkerDataSourceTwo" />
</MapsMarker>
</MapsMarkerSettings>
</MapsLayer>
</MapsLayers>Aggregated Data Visualization
Combine multiple data points into regional summaries:
@page "/aggregated-data-map"
@using Syncfusion.Blazor.Maps
<SfMaps>
<MapsLayers>
<MapsLayer ShapeData='new {dataOptions= "/data/world-map.json"}' TValue="RegionalSales"
DataSource="@AggregatedData">
<MapsShapeSettings ColorValuePath="TotalSales">
<MapsShapeColorMappings>
<MapsShapeColorMapping StartRange="0" EndRange="100000" Color='new string[] { "lightgreen" }'>
</MapsShapeColorMapping>
<MapsShapeColorMapping StartRange="100000" EndRange="500000" Color='new string[] { "orange" }'>
</MapsShapeColorMapping>
<MapsShapeColorMapping StartRange="500000" EndRange="1000000" Color='new string[] { "red" }'>
</MapsShapeColorMapping>
</MapsShapeColorMappings>
</MapsShapeSettings>
<MapsDataLabelSettings Visible="true" LabelPath="RegionName">
</MapsDataLabelSettings>
</MapsLayer>
</MapsLayers>
<MapsLegendSettings Visible="true" Position="Syncfusion.Blazor.Maps.LegendPosition.Bottom">
</MapsLegendSettings>
</SfMaps>
@code {
private List<RegionalSales> AggregatedData = new()
{
new RegionalSales { RegionName = "West", TotalSales = 250000 },
new RegionalSales { RegionName = "Central", TotalSales = 180000 },
new RegionalSales { RegionName = "East", TotalSales = 420000 }
};
public class RegionalSales
{
public string RegionName { get; set; }
public decimal TotalSales { get; set; }
}
}Data Filtering by Attribute
Filter and visualize specific data subsets:
<button @onclick='() => FilterData("high")'>High Values</button>
<button @onclick='() => FilterData("all")'>All Values</button>
<SfMaps @ref="mapInstance" >
<MapsLayers>
<MapsLayer ShapeData='new {dataOptions= "/data/world-map.json"}' TValue="DataPoint"
DataSource="@FilteredData">
<MapsShapeSettings ColorValuePath="Value">
</MapsShapeSettings>
</MapsLayer>
</MapsLayers>
</SfMaps>
@code {
private SfMaps mapInstance;
private List<DataPoint> FullData = new();
private List<DataPoint> FilteredData = new();
private async Task FilterData(string filter)
{
FilteredData = filter switch
{
"high" => FullData.Where(d => d.Value > 75).ToList(),
"low" => FullData.Where(d => d.Value <= 25).ToList(),
_ => FullData
};
mapInstance.Refresh();
}
public class DataPoint
{
public string RegionId { get; set; }
public double Value { get; set; }
}
}MANDATORY SECURITY NOTICE: Do NOT load GeoJSON, ShapeData, tile, or image resources directly from untrusted third‑party URLs at runtime. Host assets locally or return server-validated, signed URLs; validate GeoJSON/ShapeData against a strict schema, sanitize/HTML-encode properties, enforce size/complexity limits, and require human review before automated processing or forwarding to agents.
Table of Contents
- Installation and Setup
- Step 1: Install NuGet Package
- Step 2: Register in Program.cs
- Step 3: Add CSS Theme Reference
- Basic Map Component
- Minimal Map Setup
- Map with Default Center Position
- Map with Fixed Size
- First Interactive Map Example
- Understanding Map Layers
- What is a Layer?
- CSS and Theme Configuration
- Import via CSS File
- Dynamic Theme Switching
- Container Requirements
- Troubleshooting Setup Issues
- Map appears blank or doesn't load
- "SfMaps is not defined" or compilation error
- Map renders but tiles don't load
- Key Properties for Basic Setup
- SfMaps Component API
- Essential Properties
- Essential Methods
- Next Steps
Getting Started with Syncfusion Maps
Installation and Setup
Step 1: Install NuGet Package
Security Note: This step installs the Syncfusion.Blazor NuGet package from the official NuGet.org repository. This is a legitimate vendor package required for the Maps component functionality. The package integrates into your Blazor application and is loaded at runtime.
Install the Syncfusion.Blazor package via NuGet Package Manager:
dotnet add package Syncfusion.BlazorOr using Package Manager Console:
Install-Package Syncfusion.BlazorPackage Verification:
- Publisher: Syncfusion Inc
- Source: https://www.nuget.org/packages/Syncfusion.Blazor
- Verify package signature before installation in production environments
Step 2: Register in Program.cs
For Blazor Web App (Server or Auto), add the Syncfusion service in Program.cs:
using Syncfusion.Blazor;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
builder.Services.AddSyncfusionBlazor();
var app = builder.Build();
app.Run();For older Blazor WASM apps, register in Main.cs or Program.cs:
builder.Services.AddSyncfusionBlazor();Basic Map Component
Minimal Map Setup
Create a new component or page with a basic map:
@page "/maps"
@using Syncfusion.Blazor.Maps
<SfMaps>
<MapsLayers>
<MapsLayer UrlTemplate="@TileUrl" TValue="string">
</MapsLayer>
</MapsLayers>
</SfMaps>This creates an interactive map using OpenStreetMap tiles. Users can immediately zoom and pan.
Map with Default Center Position
Control the initial map view:
<SfMaps >
<MapsCenterPosition Latitude="25.54244147012483" Longitude="-89.62646484375"></MapsCenterPosition>
<MapsZoomSettings Enable="false" ZoomFactor="11"></MapsZoomSettings>
<MapsLayers>
<MapsLayer ShapeData='new {dataOptions= "/data/world-map.json"}' TValue="string">
</MapsLayer>
</MapsLayers>
</SfMaps>Properties:
CenterPosition.Latitude: Initial latitude (e.g., 37.368)CenterPosition.Longitude: Initial longitude (e.g., -122.095)ZoomLevel: Initial zoom level (1-10, default is 1)
Map with Fixed Size
Set explicit dimensions for the map container:
<div style="width: 100%; height: 600px;">
<SfMaps>
<MapsLayers>
<MapsLayer ShapeData='new {dataOptions= "/data/world-map.json"}' TValue="string">
</MapsLayer>
</MapsLayers>
</SfMaps>
</div>Without explicit sizing, maps default to 400px height. Always wrap in a container with defined height.
First Interactive Map Example
Complete working example with markers and basic interaction:
@page "/maps-demo"
@using Syncfusion.Blazor.Maps
<SfMaps>
<MapsLayers>
<MapsLayer ShapeData='new {dataOptions= "/data/world-map.json"}' TValue="string">
<MapsMarkerSettings>
<MapsMarker Visible="true" Datasource="@MarkerData" TValue="MapMarkerDataSource"
Shape="Syncfusion.Blazor.Maps.MarkerType.Circle" Width="15" Height="15">
</MapsMarker>
</MapsMarkerSettings>
</MapsLayer>
</MapsLayers>
</SfMaps>
@code {
public class MapMarkerDataSource
{
public double Latitude { get; set; }
public double Longitude { get; set; }
};
public List<MapMarkerDataSource> MarkerData = new List<MapMarkerDataSource>
{
new MapMarkerDataSource { Latitude = 47.60621, Longitude = -122.332071 }
};
}This creates a map centered on the continental US with two markers. Users can click, zoom, and drag to navigate.
Understanding Map Layers
What is a Layer?
A layer is a collection of visual elements (tiles, shapes, markers) displayed on the map at a specific level. Maps can have multiple layers:
<SfMaps>
<MapsLayers>
<MapsLayer ShapeData='new {dataOptions= "/data/world-map.json"}' TValue="string">
<MapsShapeSettings Fill="#E5E5E5">
<MapsShapeBorder Color="black" Width="0.1"></MapsShapeBorder>
</MapsShapeSettings>
</MapsLayer>
<MapsLayer ShapeData='new {dataOptions= "/data/usa-map.json"}' TValue="string" Type="Syncfusion.Blazor.Maps.Type.SubLayer">
<MapsShapeSettings Fill="rgba(141, 206, 255, 0.6)">
<MapsShapeBorder Color="#1a9cff" Width="0.25"></MapsShapeBorder>
</MapsShapeSettings>
</MapsLayer>
<MapsLayer ShapeData='new {dataOptions= "/data/california-map.json"}' TValue="string" Type="Syncfusion.Blazor.Maps.Type.SubLayer">
<MapsShapeSettings Fill="rgba(141, 206, 255, 0.6)">
<MapsShapeBorder Color="#1a9cff" Width="0.25"></MapsShapeBorder>
</MapsShapeSettings>
</MapsLayer>
</MapsLayers>
</SfMaps>Each layer renders independently and can be toggled on/off.
Dynamic Theme Switching
Switch themes at runtime:
@page "/maps"
@using Syncfusion.Blazor.Maps
@inject IJSRuntime JS
<div style="margin-bottom: 20px;">
<button @onclick='() => SwitchTheme("bootstrap5")'>Bootstrap</button>
<button @onclick='() => SwitchTheme("material")'>Material</button>
</div>
<SfMaps @ref="mapInstance" Theme="Theme">
<MapsZoomSettings ZoomFactor="1"></MapsZoomSettings>
<MapsLayers>
<MapsLayer ShapeData='new {dataOptions= "https://cdn.syncfusion.com/maps/map-data/world-map.json"}' TValue="string">
</MapsLayer>
</MapsLayers>
</SfMaps>
@code {
private SfMaps mapInstance;
Syncfusion.Blazor.Theme Theme;
private async Task SwitchTheme(string theme)
{
Theme = theme == "bootstrap5" ? Syncfusion.Blazor.Theme.Bootstrap5 : Syncfusion.Blazor.Theme.Material;
}
}Container Requirements
Maps need a properly sized container:
Correct - Container with explicit height:
<div style="width: 100%; height: 500px;">
<SfMaps>...</SfMaps>
</div>Incorrect - Missing height:
<SfMaps>...</SfMaps> <!-- Collapses to 0 height -->Responsive Container:
<div style="width: 100%; height: 100vh;"> <!-- Full viewport height -->
<SfMaps>...</SfMaps>
</div>Troubleshooting Setup Issues
Map appears blank or doesn't load
- Check CSS import: Verify
bootstrap5.css(or your chosen theme) is imported - Check service registration: Confirm
AddSyncfusionBlazor()is called in Program.cs - Check container size: Map must have explicit height and width
- Check internet connection: Tile providers (OpenStreetMap, Google Maps) require network access
"SfMaps is not defined" or compilation error
- Confirm NuGet package is installed:
dotnet add package Syncfusion.Blazor - Add
@using Syncfusion.Blazor.Mapsdirective - Rebuild the project
Map renders but tiles don't load
- Verify UrlTemplate is correct and accessible
- Check network in browser DevTools
- Ensure your ISP/firewall allows tile server access
Key Properties for Basic Setup
| Property | Type | Example | Purpose |
|---|---|---|---|
CenterPosition.Latitude | double | 37.368 | Initial map center latitude |
CenterPosition.Longitude | double | -122.095 | Initial map center longitude |
ZoomLevel | int | 4 | Initial zoom level (1-20) |
UrlTemplate | string | "@TileUrl" | Tile provider URL |
Width | string | "100%" | Map container width |
Height | string | "600px" | Map container height |
SfMaps Component API
Essential Properties
@using Syncfusion.Blazor.Maps
<SfMaps Width="100%"
Height="600px"
BaseLayerIndex="0"
Background="blue">
<MapsZoomSettings ZoomFactor="2"></MapsZoomSettings>
<MapsLayers>
<MapsLayer ShapeData='new {dataOptions= "/data/world-map.json"}' TValue="string">
</MapsLayer>
</MapsLayers>
</SfMaps>| Property | Type | Description |
|---|---|---|
CenterPosition | MapsCenterPosition | Set initial map center |
ZoomLevel | int | Initial zoom (1-20) |
Width | string | Container width |
Height | string | Container height |
BaseLayerIndex | int | Index of base tile layer |
Background | string | Background color |
Essential Methods
// Refresh map rendering
await mapInstance.RefreshAsync();
// Get current bounds
MinMaxLatitudeLongitude bounds = mapInstance.GetMinMaxLatitudeLongitude();
// Export map
await mapInstance.ExportAsync(ExportType.PNG, "mymap");
// Print map
await mapInstance.PrintAsync();Next Steps
Once you have a basic map rendering, you can:
- Add markers: Use
<MapsMarker>to display points of interest - Handle interactions: Bind to click events and user interactions
- Integrate map providers: Configure Google Maps, Bing Maps, or Azure Maps
- Add shapes and polygons: Display geographic boundaries and regions
- Implement data visualization: Use color mapping for choropleth displays
- Review complete API: See references/api-reference.md for all classes, methods, and properties
🚨 SECURITY: External GeoJSON Data Loading
CRITICAL WARNING FOR PRODUCTION USE
ALL code examples in this skill documentation use external GeoJSON URLs for demonstration purposes ONLY.
❌ UNSAFE FOR PRODUCTION
// ❌ DO NOT USE THIS IN PRODUCTION
<MapsLayer ShapeData='new {dataOptions = "SERVER_VALIDATED_GEOJSON_URL"}' TValue="string">Why this is unsafe:
- Loads data from external CDN without validation
- Vulnerable to CDN compromise
- Susceptible to man-in-the-middle attacks
- No GeoJSON structure validation
- Could inject malicious geographic data
✅ SECURE FOR PRODUCTION
// ✅ PRODUCTION-READY: Load from local cached file
<MapsLayer ShapeData='new {dataOptions = "/data/usa-map.json"}' TValue="string">OR with validation:
@code {
private object ValidatedGeoJson;
protected override async Task OnInitializedAsync()
{
// Load with validation
ValidatedGeoJson = await LoadSecureGeoJson(
"SERVER_VALIDATED_GEOJSON_URL"
);
}
private async Task<object> LoadSecureGeoJson(string url)
{
// 1. Validate URL format
if (!Uri.TryCreate(url, UriKind.Absolute, out var uri))
throw new SecurityException("Invalid URL");
// 2. Enforce HTTPS
if (uri.Scheme != "https")
throw new SecurityException("HTTPS required");
// 3. Check trusted domains
var trusted = new[] { "cdn.syncfusion.com", "yourdomain.com" };
if (!trusted.Any(d => uri.Host.EndsWith(d)))
throw new SecurityException($"Untrusted: {uri.Host}");
// 4. Fetch and validate
var data = await Http.GetStringAsync(url);
return ValidateGeoJsonStructure(data);
}
}Quick Security Checklist
Before deploying to production, ensure:
- [ ] NOT loading GeoJSON directly from external URLs
- [ ] GeoJSON files cached locally in `wwwroot/data/`
- [ ] If loading externally, URLs are validated against allow-list
- [ ] HTTPS enforced for all external requests
- [ ] GeoJSON structure validated before rendering
- [ ] Content Security Policy headers configured
- [ ] No hardcoded API keys in code
- [ ] External HTML content (tooltips/annotations) sanitized
Production Deployment Steps
Step 1: Download and Bundle GeoJSON Files
# Download GeoJSON files during build
New-Item -Path "wwwroot/data" -ItemType Directory -Force
Invoke-WebRequest -Uri "SERVER_VALIDATED_GEOJSON_URL" `
-OutFile "wwwroot/data/usa-map.json"Step 2: Update Code to Use Local Files
// Change from:
ShapeData='new {dataOptions = "https://cdn.syncfusion.com/maps/map-data/usa.json"}'
// To:
ShapeData='new {dataOptions = "/data/usa-map.json"}'Step 3: Configure Content Security Policy
// Program.cs
app.Use(async (context, next) =>
{
context.Response.Headers.Add("Content-Security-Policy",
"default-src 'self'; " +
"connect-src 'self'; " + // No external data sources
"img-src 'self' data: https://tile.openstreetmap.org;");
await next();
});Documentation References
- Complete Security Guidance: security-review
- GeoJSON Validation: data-visualization.md#validating-external-geojson-data
- API Key Security: map-providers.md#security-best-practices
- Content Sanitization: user-interactions.md#sanitizing-external-content
Development vs Production
| Aspect | Development | Production |
|---|---|---|
| GeoJSON Source | External CDN URLs | Local bundled files |
| Validation | Optional | MANDATORY |
| HTTPS | Recommended | REQUIRED |
| Domain Allow-list | Optional | REQUIRED |
| CSP Headers | Optional | REQUIRED |
| API Keys | appsettings.json | Azure Key Vault/Secrets |
Service Implementation Templates
Template 1: GeoJson Validator Service
using System;
using System.Collections.Generic;
using System.Linq;
public class GeoJsonValidator
{
private static readonly string[] SuspiciousPatterns = new[]
{
"system:", "ignore", "bypass", "execute", "admin:",
"[system]", "[command]", "do not", "javascript:"
};
private static readonly string[] TrustedDomains = new[]
{
"yourdomain.com", "api.yourdomain.com"
};
public bool ValidateCoordinates(double latitude, double longitude)
{
return latitude >= -90 && latitude <= 90 &&
longitude >= -180 && longitude <= 180;
}
public bool ContainsSuspiciousPatterns(string content)
{
if (string.IsNullOrEmpty(content))
return false;
return SuspiciousPatterns.Any(p => content.ToLower().Contains(p));
}
public bool IsValidDomain(string hostname)
{
return TrustedDomains.Any(d => hostname.EndsWith(d));
}
}Template 2: Content Sanitizer Service
# Install NuGet package
dotnet add package HtmlSanitizerusing HtmlSanitizer;
public class ContentSanitizer
{
private readonly HtmlSanitizer.HtmlSanitizer _sanitizer;
public ContentSanitizer()
{
_sanitizer = new HtmlSanitizer.HtmlSanitizer();
_sanitizer.AllowedTags.Clear();
_sanitizer.AllowedTags.Add("b");
_sanitizer.AllowedTags.Add("i");
_sanitizer.AllowedTags.Add("strong");
_sanitizer.AllowedAttributes.Clear();
}
public string SanitizeHtml(string unsafeContent)
{
if (string.IsNullOrEmpty(unsafeContent))
return "";
try
{
return _sanitizer.Sanitize(unsafeContent);
}
catch
{
return System.Net.WebUtility.HtmlEncode(unsafeContent);
}
}
}Register Services
Add to Program.cs:
builder.Services.AddScoped<GeoJsonValidator>();
builder.Services.AddScoped<ContentSanitizer>();Content Security Policy
Add to Program.cs:
app.Use(async (context, next) =>
{
context.Response.Headers["Content-Security-Policy"] =
"default-src 'self'; " +
"img-src 'self' data: https://tile.openstreetmap.org; " +
"style-src 'self' 'unsafe-inline' _content/Syncfusion.Blazor/; " +
"script-src 'self' 'unsafe-inline' 'unsafe-eval'; " +
"connect-src 'self'; " +
"base-uri 'self'; " +
"form-action 'self'";
await next();
});Need Help?
If you're unsure about implementing secure GeoJSON loading:
1. Review the complete validation guide: data-visualization.md 2. Check the security review document: security-review 3. Follow the production checklist above 4. Test with security audit tools
Remember: Security is not optional. Always validate external data sources before production deployment.