Interactive maps

Mobile-friendly interactive maps powered by Leaflet.js.

Finder component

Basic example (no markers passed)

import dynamic from 'next/dynamic'
const MapContainer = dynamic(() => 
  import('react-leaflet').then(mod => mod.MapContainer),
  { ssr: false }
)
const TileLayer = dynamic(() => 
  import('react-leaflet').then(mod => mod.TileLayer),
  { ssr: false }
)
import 'leaflet/dist/leaflet.css'  

{/* Basic map example (no markers passed) */}
<MapContainer
  center={[0, 0]}
  zoom={1}
  scrollWheelZoom={false} // Enable/disable scroll wheel zooming
  style={{height: '400px'}}
>
  <TileLayer
    url='https://api.maptiler.com/maps/voyager/{z}/{x}/{y}.png?key=YOUR_API_KEY'
    // To rgister API key with Maptiler check https://docs.maptiler.com/cloud/api/
    tileSize={512}
    zoomOffset={-1}
    minZoom={1}
    attribution={'<a href='https://www.maptiler.com/copyright/' target='_blank'>&copy; MapTiler</a> <a href='https://www.openstreetmap.org/copyright' target='_blank'>&copy; OpenStreetMap contributors</a>'}
  />
</MapContainer>

Default custom marker with popup

import dynamic from 'next/dynamic'
const MapContainer = dynamic(() => 
  import('react-leaflet').then(mod => mod.MapContainer),
  { ssr: false }
)
const TileLayer = dynamic(() => 
  import('react-leaflet').then(mod => mod.TileLayer),
  { ssr: false }
)
const CustomMarker = dynamic(() => 
  import('../../components/partials/CustomMarker'),
  { ssr: false }
)
const Popup = dynamic(() => 
  import('react-leaflet').then(mod => mod.Popup),
  { ssr: false }
)
import 'leaflet/dist/leaflet.css'

{/* Map featuring custom marker with popup */}
<MapContainer
  center={[51.5074, -0.1278]}
  zoom={10}
  scrollWheelZoom={false} // Enable/disable scroll wheel zooming
  style={{height: '400px'}}
>
  <TileLayer
    url='https://api.maptiler.com/maps/streets/{z}/{x}/{y}.png?key=YOUR_API_KEY'
    // To rgister API key with Maptiler check https://docs.maptiler.com/cloud/api/
    tileSize={512}
    zoomOffset={-1}
    minZoom={1}
    attribution={'<a href='https://www.maptiler.com/copyright/' target='_blank'>&copy; MapTiler</a> <a href='https://www.openstreetmap.org/copyright' target='_blank'>&copy; OpenStreetMap contributors</a>'}
  />
  <CustomMarker position={[51.5074, -0.1278]}>
    <Popup>
      <div className='p-3'>
        <h6>Hi, I&apos;m in London</h6>
        <p className='fs-sm pt-1 mt-n3 mb-0'>Lorem ipsum dolor sit amet elit.</p>
      </div>
    </Popup>
  </CustomMarker>
</MapContainer>

Multiple dot markers with popups

import dynamic from 'next/dynamic'
const MapContainer = dynamic(() => 
  import('react-leaflet').then(mod => mod.MapContainer),
  { ssr: false }
)
const TileLayer = dynamic(() => 
  import('react-leaflet').then(mod => mod.TileLayer),
  { ssr: false }
)
const CustomMarker = dynamic(() => 
  import('../../components/partials/CustomMarker'),
  { ssr: false }
)
const Popup = dynamic(() => 
  import('react-leaflet').then(mod => mod.Popup),
  { ssr: false }
)
import 'leaflet/dist/leaflet.css'

{/* Map featuring multiple dot markers with popups */}
<MapContainer
  center={[40.7128, -74.0060]}
  zoom={11}
  scrollWheelZoom={false} // Enable/disable scroll wheel zooming
  style={{height: '400px'}}
>
  <TileLayer
    url='https://api.maptiler.com/maps/pastel/{z}/{x}/{y}.png?key=YOUR_API_KEY'
    // To rgister API key with Maptiler check https://docs.maptiler.com/cloud/api/
    tileSize={512}
    zoomOffset={-1}
    minZoom={1}
    attribution={'<a href='https://www.maptiler.com/copyright/' target='_blank'>&copy; MapTiler</a> <a href='https://www.openstreetmap.org/copyright' target='_blank'>&copy; OpenStreetMap contributors</a>'}
  />
  <CustomMarker position={[40.702, -74.0068]} icon='dot'>
    <Popup>
      <div className='p-3'>
        <h6>Hi, I&apos;m in New York</h6>
        <p className='fs-sm pt-1 mt-n3 mb-0'>Lorem ipsum dolor sit amet elit.</p>
      </div>
    </Popup>
  </CustomMarker>
  <CustomMarker position={[40.716, -74.078]} icon='dot'>
    <Popup>
      <div className='p-3'>
        <h6>Hi, I&apos;m in Jersey Cty</h6>
        <p className='fs-sm pt-1 mt-n3 mb-0'>Lorem ipsum dolor sit amet elit.</p>
      </div>
    </Popup>
  </CustomMarker>
  <CustomMarker position={[40.650, -74.209]} icon='dot'>
    <Popup>
      <div className='p-3'>
        <h6>Hi, I&apos;m in Elizabeth</h6>
        <p className='fs-sm pt-1 mt-n3 mb-0'>Lorem ipsum dolor sit amet elit.</p>
      </div>
    </Popup>
  </CustomMarker>
</MapContainer>

Multiple custom markers stored in a variable

import dynamic from 'next/dynamic'
const MapContainer = dynamic(() => 
  import('react-leaflet').then(mod => mod.MapContainer),
  { ssr: false }
)
const TileLayer = dynamic(() => 
  import('react-leaflet').then(mod => mod.TileLayer),
  { ssr: false }
)
const CustomMarker = dynamic(() => 
  import('../../components/partials/CustomMarker'),
  { ssr: false }
)
const Popup = dynamic(() => 
  import('react-leaflet').then(mod => mod.Popup),
  { ssr: false }
)
import 'leaflet/dist/leaflet.css'

{/* Markers array */}
const markers = [
  {
    position: [52.52, 13.407],
    iconUrl: '/images/map/marker-accomodation.png',
    iconSize: [48, 48],
    popup: {
      href: '#',
      img: '/images/city-guide/catalog/02.jpg',
      title: 'Grand Resort & Spa',
      rating: 4.6,
      reviews: 43,
      address: 'Ollenhauer Str. 29, 10118, Berlin',
      price: '$$$'
    }
  },
  {
    position: [52.51, 13.36],
    iconUrl: '/images/map/marker-fitness.png',
    iconSize: [48, 48],
    popup: {
      href: '#',
      img: '/images/city-guide/catalog/16.jpg',
      title: 'Power Fitness Club',
      rating: 4.2,
      reviews: 317,
      address: 'Genslerstraße 84, 10118, Berlin',
      price: '$$'
    }
  },
  {
    position: [52.528, 13.37],
    iconUrl: '/images/map/marker-cafe.png',
    iconSize: [48, 48],
    popup: {
      href: '#',
      img: '/images/city-guide/catalog/17.jpg',
      title: 'ClubFood Restaurant & Bar',
      rating: 4.7,
      reviews: 239,
      address: 'Antwerpener str. 47, 13253, Berlin',
      price: '$$'
    }
  },
  {
    position: [52.525, 13.45],
    iconUrl: '/images/map/marker-nightlife.png',
    iconSize: [48, 48],
    popup: {
      href: '#',
      img: '/images/city-guide/catalog/18.jpg',
      title: 'Egoist Night Club & Bar',
      rating: 4.8,
      reviews: 117,
      address: 'Kochhannstraße str. 32, 11060, Berlin',
      price: '$$'
    }
  },
  {
    position: [52.503, 13.409],
    iconUrl: '/images/map/marker-meds.png',
    iconSize: [48, 48],
    popup: {
      href: '#',
      img: '/images/city-guide/catalog/19.jpg',
      title: 'Fair Meds Pharmacy',
      rating: 4.9,
      reviews: 561,
      address: 'Lansstraße 81, D-11179, Berlin',
      price: '$'
    }
  },
  {
    position: [52.54, 13.403],
    iconUrl: '/images/map/marker-shopping.png',
    iconSize: [48, 48],
    popup: {
      href: '#',
      img: '/images/city-guide/catalog/20.jpg',
      title: 'Fetishist Shopping Mall',
      rating: 4.3,
      reviews: 1274,
      address: 'Mellingburgredder 3, 13250, Berlin',
      price: '$$'
    }
  }
]

{/* Map featuring multiple custom markers with popups passed via markers array */}
<MapContainer
  center={[52.53, 13.405]}
  zoom={12}
  scrollWheelZoom={false}
  style={{height: '600px'}}
>
  <TileLayer
    url='https://api.maptiler.com/maps/pastel/{z}/{x}/{y}.png?key=BO4zZpr0fIIoydRTOLSx'
    tileSize={512}
    zoomOffset={-1}
    minZoom={1}
    attribution={'<a href='https://www.maptiler.com/copyright/' target='_blank'>&copy; MapTiler</a> <a href='https://www.openstreetmap.org/copyright' target='_blank'>&copy; OpenStreetMap contributors</a>'}
  />
  {markers.map((marker, indx) => {
    return <CustomMarker
      key={indx}
      position={marker.position}
      icon='custom'
      iconOptions={{
        url: marker.iconUrl,
        size: [marker.iconSize[0], marker.iconSize[1]],
      }}
    >
      <Popup>
        <Link href={marker.popup.href} className='d-block'>
          <ImageLoader src={marker.popup.img} width={280} height={128} alt='Image' />
        </Link>
        <div className='card-body'>
          <h5 className='card-title fs-base'>
            <Link href={marker.popup.href} className='nav-link'>{marker.popup.title}</Link>
          </h5>
          <div className='d-flex align-items-center mb-2'>
            <StarRating rating={marker.popup.rating} className='mt-n1 me-2' />
            <span className='fs-xs'>
              <strong>{marker.popup.rating}</strong>
              <span className='text-muted ms-1'>({marker.popup.reviews})</span>
            </span>
          </div>
          <div className='mb-2'>
            <i className='fi-map-pin text-muted fs-sm mt-n1 me-1'></i>
            {marker.popup.address}
          </div>
          <i className='fi-credit-card text-muted fs-sm mt-n1 me-1'></i>
          {marker.popup.price}
        </div>
      </Popup>
    </CustomMarker>
  })}
</MapContainer>