Integration Examples
Beta Feature
Interactive maps are still in development. For customers with a package S (or higher), this function is available free of charge until the end of July 2025, after which usage-based billing will apply. The availability is currently limited and there may be errors. Give FeedbackReady-to-use code examples for embedding interactive maps in different platforms.
HTML Example
Basic HTML integration that works on any website:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My Interactive Map</title>
<!-- Preload and CSS for optimal performance -->
<link rel="preload" href="https://share.mapstudio.ai/embed.js" as="script" />
<link rel="stylesheet" href="https://share.mapstudio.ai/embed.css">
</head>
<body>
<h1>Welcome to Our Store Locations</h1>
<!-- Map container with fallback -->
<div id="store-map" style="width: 100%; height: 500px; border: 1px solid #ddd; border-radius: 8px;">
<noscript>
<img
src="https://share.mapstudio.ai/embed/your-export-id/fallback.webp"
alt="Store Locations Map"
style="width: 100%; height: 100%; object-fit: cover;"
/>
</noscript>
</div>
<!-- Initialize map (script will be loaded automatically via preload) -->
<script>
mapstudio.createMap({
containerId: "store-map",
exportId: "your-export-id-here", // Replace with your actual export ID
display: {
showNavigationControl: "top-left"
}
});
</script>
</body>
</html>
WordPress Example
Method 1: Custom HTML Block
Add this to a custom HTML block in WordPress:
html
<!-- Map container -->
<div id="wp-map" style="width: 100%; height: 400px; margin: 20px 0;">
<noscript>
<img src="https://share.mapstudio.ai/embed/your-export-id/fallback.webp"
alt="Interactive Map" style="width: 100%; height: 100%; object-fit: cover;" />
</noscript>
</div>
<!-- CSS for mapstudio.ai -->
<link rel="stylesheet" href="https://share.mapstudio.ai/embed.css">
<!-- Load and initialize map -->
<script src="https://share.mapstudio.ai/embed.js"></script>
<script>
mapstudio.createMap({
containerId: "wp-map",
exportId: "your-export-id-here",
display: {
showNavigationControl: "top-right"
}
});
</script>
Method 2: Functions.php Integration
Add to your theme's functions.php
:
php
<?php
// Add mapstudio.ai resources to WordPress
function add_mapstudio_assets() {
wp_enqueue_style('mapstudio-embed', 'https://share.mapstudio.ai/embed.css', array(), null);
wp_enqueue_script('mapstudio-embed', 'https://share.mapstudio.ai/embed.js', array(), null, true);
}
add_action('wp_enqueue_scripts', 'add_mapstudio_assets');
// Shortcode for easy map embedding
function mapstudio_map_shortcode($atts) {
$atts = shortcode_atts(array(
'id' => '',
'height' => '400px',
'controls' => 'top-right'
), $atts);
if (empty($atts['id'])) {
return '<p style="color: #d32f2f;">Error: Map ID required. Usage: [mapstudio id="your-export-id"]</p>';
}
$container_id = 'mapstudio-' . uniqid();
$export_id = esc_attr($atts['id']);
$height = esc_attr($atts['height']);
$controls = esc_attr($atts['controls']);
ob_start();
?>
<div id="<?php echo $container_id; ?>" style="width: 100%; height: <?php echo $height; ?>;">
<noscript>
<img src="https://share.mapstudio.ai/embed/<?php echo $export_id; ?>/fallback.webp"
alt="Interactive Map"
style="width: 100%; height: 100%; object-fit: cover;" />
</noscript>
</div>
<script>
mapstudio.createMap({
containerId: "<?php echo $container_id; ?>",
exportId: "<?php echo $export_id; ?>",
display: {
showNavigationControl: "<?php echo $controls; ?>"
}
});
</script>
<?php
return ob_get_clean();
}
add_shortcode('mapstudio', 'mapstudio_map_shortcode');
?>
Usage in posts:
[mapstudio id="your-export-id" height="500px" controls="top-left"]
Next.js Example
App Router Implementation with Script Component
Create a reusable component:
typescript
// components/MapstudioMap.tsx
'use client';
import { useEffect, useRef } from 'react';
interface MapstudioMapProps {
exportId: string;
height?: string;
showControls?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | false;
className?: string;
}
declare global {
interface Window {
mapstudio?: {
createMap: (config: any) => void;
};
}
}
export default function MapstudioMap({
exportId,
height = '400px',
showControls = 'top-right',
className = ''
}: MapstudioMapProps) {
const containerRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (window.mapstudio && containerRef.current) {
window.mapstudio.createMap({
containerId: containerRef.current.id,
exportId,
display: {
showNavigationControl: showControls
}
});
}
}, [exportId, showControls]);
const containerId = `mapstudio-${exportId}-${Math.random().toString(36).substr(2, 9)}`;
return (
<div
ref={containerRef}
id={containerId}
style={{ height, width: '100%' }}
className={`rounded-lg overflow-hidden ${className}`}
>
<noscript>
<img
src={`https://share.mapstudio.ai/embed/${exportId}/fallback.webp`}
alt="Interactive Map"
style={{ width: '100%', height: '100%', objectFit: 'cover' }}
/>
</noscript>
</div>
);
}
Layout Integration with Script Component
typescript
// app/layout.tsx
import Script from 'next/script'
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html>
<head>
{/* CSS for mapstudio.ai */}
<link rel="stylesheet" href="https://share.mapstudio.ai/embed.css" />
{/* Load mapstudio.ai script globally */}
<Script
src="https://share.mapstudio.ai/embed.js"
strategy="beforeInteractive"
/>
</head>
<body>
{children}
</body>
</html>
)
}
You may want to use separate layout handling to avoid unnecessarily loading the script for all pages.
Usage in Next.js Pages
typescript
// app/page.tsx
import MapstudioMap from '@/components/MapstudioMap';
export default function HomePage() {
return (
<div className="container mx-auto py-8">
<h1 className="text-3xl font-bold mb-6">Our Locations</h1>
<MapstudioMap
exportId="your-export-id-here"
height="500px"
showControls="top-right"
className="mb-6"
/>
<p className="mt-4 text-gray-600">
Find us at one of these convenient locations.
</p>
</div>
);
}
Performance Optimization
Lazy Loading Example
Load maps only when they become visible:
javascript
// Intersection Observer for Lazy Loading
const mapObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting && window.mapstudio) {
const containerId = entry.target.id;
const exportId = entry.target.dataset.exportId;
mapstudio.createMap({
containerId,
exportId,
display: {
showNavigationControl: "top-right"
}
});
mapObserver.unobserve(entry.target);
}
});
});
// HTML
<div
id="lazy-map"
data-export-id="your-export-id"
style="width: 100%; height: 400px;">
<noscript>
<img src="https://share.mapstudio.ai/embed/your-export-id/fallback.webp"
alt="Interactive Map" style="width: 100%; height: 100%; object-fit: cover;" />
</noscript>
</div>
// Initialize observer
document.addEventListener('DOMContentLoaded', function() {
const lazyMap = document.getElementById('lazy-map');
if (lazyMap) {
mapObserver.observe(lazyMap);
}
});
Advanced Configuration
Content Security Policy (CSP)
For websites with Content Security Policy, add these directives:
text
script-src 'self' 'unsafe-inline' https://share.mapstudio.ai;
style-src 'self' https://share.mapstudio.ai;
img-src 'self' data: blob: https://map.cdn.mapstudio.ai;
connect-src 'self' https://map.cdn.mapstudio.ai https://fonts.mapstudio.ai;
worker-src 'self' data: blob:;
font-src 'self';
Adding CSP Headers in Next.js
Add to next.config.js
:
javascript
/** @type {import('next').NextConfig} */
const nextConfig = {
async headers() {
return [
{
source: '/(.*)',
headers: [
{
key: 'Content-Security-Policy',
value: [
"default-src 'self'",
"script-src 'self' 'unsafe-inline' https://share.mapstudio.ai",
"style-src 'self' https://share.mapstudio.ai",
"img-src 'self' data: blob: https://map.cdn.mapstudio.ai",
"connect-src 'self' https://map.cdn.mapstudio.ai https://fonts.mapstudio.ai",
"worker-src 'self' data: blob:",
"font-src 'self'"
].join('; ')
}
]
}
];
}
};
module.exports = nextConfig;
Testing Your Integration
- Check allowed domains in mapstudio.ai workspace settings
- Test on different devices and screen sizes
- Verify fallback image displays without JavaScript
- Monitor browser console for errors
- Test loading performance with network throttling
Next: Learn more about billing and pricing for interactive maps.