Maps

note

When rendering HomeflowJS map elements into DOM nodes, remember to set a height on the container DOM node or the map will not be visible.

Property Results Map

The property results map will be included by default with the PropertyResults component, on the route #/map.

If you wish to render the map separately (like if you want to render the map and results side-by-side), pass the noMap prop to PropertyResults and render the PropertiesMap yourself:

import { PropertiesMap } from 'homeflowjs/properties';
const myPropertiesMap = () => (
<PropertiesMap />
);

Whether you render the map yourself or let PropertyResults do so, you must define a template with an id of property-map-popup-template somewhere in your markup for Leaflet to use as a popup when a property marker is clicked.

As much of the code for the property results map depends on older libraries and legacy JS, this template uses lodash.template instead of React.

Here is a simple example:

<script id="property-map-popup-template" type="text/template">
<p>
<img style="width:120px;" src="<%= property.photo %>" />
<br/>
<% if (property.bedrooms) { %>
<%= property.bedrooms %> bed -
<% } %>
<%= property.price %> <br/>
<a href="<%= property.property_url %>"><%= property.display_address %></a>
</p>
</script>

You can optionally set the type of layer to use on the Leaflet map. The default is the normal leaflet map layer, but you can pass the string google to use the google maps layer:

Homeflow.set('leaflet_layer', 'google');

If you use google, make sure the agency has a google_maps_api_key set up in their admin area.

If you need to render a custom layer, you can instead pass a callback function (it's important you pass this as a function that returns the tile layer instead of trying to pass the L.tileLayer object itself):

Homeflow.set('leaflet_layer', function() {
return new L.tileLayer('https://{s}.google.com/vt/lyrs=m&x={x}&y={y}&z={z}&hl=en', {
maxZoom: 20,
subdomains:['mt0','mt1','mt2','mt3']
})
});

PropertyMap

The PropertyMap component will render a map for a single property on the property show page.

By default it will render a leaflet map. Pass the prop google to render a Google map instead (ensure the agent has a google_maps_api_key set in admin if you use this).

import { withHomeflowState } from 'homeflowjs';
import { PropertyMap } from 'homeflowjs/properties';
ReactDOM.render(
withHomeflowState(PropertyMap),
document.getElementById('property-map'),
);

Leaflet property map zoom level is defaulted to 100. You can set it to the agency property zoom level (editable in exampleagency.homeflow.co.uk/configure/website/appearance/preferences -> Zoom on property maps) by adding to your views/properties/_show.ljson file the following:

agency_zoom_level: {{ agency.preferences.google_maps_property_zoom_level | yaml_safe }}
PropTypeDescription
google BooleanUse Google Maps instead of Leaflet to render the map.
customStringPass "simple_bw" to render a simplified grayscale google map.
CustomPopupComponentComponent to render as a popup when marker is clicked

How to add a popup to the Property Map depends on whether it is a google map or leaflet map. Unlike the Property Results Map, which renders a react leaflet map with a google tile layer if the google prop is included, the Property Map uses the google maps API to render a map in vanilla Javascript if the google prop is included, so each requires a different approach.

If a leaflet map is rendered you can simply pass a React component as the CustomPopup prop, similar to what is done in the Branches Map. The CustomPopup will receieve the property as a prop.

If a google map is rendered you will need to add a template script to the theme with an id of property-show-map-popup-template:

<script id="property-show-map-popup-template" type="text/template">
<div class="relative flex flex-col w-[179px] h-[292px]">
<a class="absolute -top-3.5 -left-[20.5px] w-[220px] h-[146px]" href="{{ property.property_url }}" target="_blank">
<img class="object-cover w-full h-full cursor-pointer" src="{{ property.main_photo | url_for_generic_image: '300x_' }}" alt="Property in {{ property.display_address }}" />
</a>
<div class="absolute top-0.5 -right-[4.5px] w-4 h-4">
<div class="js-save-property-heart-button" data-property-id="{{ property.property_id }}"></div>
</div>
<div class="mt-[132px] w-full h-[124px] text-center font-main-sans-light text-button-primary">
<h2 class="text-[11px] tracking-widest uppercase text-accent mt-2.5 mb-0 font-lemonmilk_medium">{{ property.status }}</h2>
<h2 class="mt-2 mb-0 text-base font-lemonmilk_medium">{{ property.road_name }}</h2>
<h3 class="text-sm mt-0.5 mb-0">{{ property.address_sans_road_name }}</h3>
<h4 class="mt-3 mb-0 text-xs lowercase">
<span class="uppercase font-lemonmilk_regular">{{ property.price_heading }}</span>
{{ property.currency }}{{ property.price_without_qualifier }}
</h4>
</div>
</div>
</script>

This can either be added directly to /views/properties/_show.liquid or can be added to its own liquid partial, which can then be included in /views/properties/_show.liquid. The innerHTML of this script will be passed to the google map and attached to the marker. Note that you will need to use liquid to generate dynamic property data.

PropertyStreetview

Renders a google streetview element for the property.

import { withHomeflowState } from 'homeflowjs';
import { PropertyStreetview } from 'homeflowjs/properties';
ReactDOM.render(
withHomeflowState(PropertyStreetview),
document.getElementById('property-streetview'),
);

BranchesMap

Renders a leaflet map of the agency's branch locations for the branches index page. Optionally pass a CustomPopup component as a prop to use this when a marker is clicked instead of the default. The CustomPopup will receive the branch as a prop.

import { BranchesMap } from 'homeflowjs/branches';
const MyCustomPopup = () => (
<div className="hfjs-branch-marker-popup">
<h2>{branch.name}</h2>
<p>{branch.address}</p>
{branch.sales_enabled && (
<a href={`${branch.branch_url}/sales`}>View all properties for sale &gt;</a>
)}
<br />
{branch.lettings_enabled && (
<a href={`${branch.branch_url}/lettings`}>View all properties to let &gt;</a>
)}
</div>
);
const MyBranchesMap = () => (
<BranchesMap CustomPopup={CustomPopup} />
);

You can override the default icon by passing an iconConfig prop. The shape of the object should match the example in the Leaflet docs: https://leafletjs.com/reference.html#icon

The default iconConfig looks like this:

{
iconRetinaUrl: '/assets/marker-icon.png',
iconUrl: '/assets/marker-icon.png',
shadowUrl: '/assets/marker-shadow.png',
}
PropTypeDescription
CustomPopupComponentComponent to render as a popup when markers are clicked
google BooleanUse a Google map layer on top of the Leaflet map (requires Google API key to be set)
iconConfig ObjectPass a custom object to be passed to Leaflet Icon

BranchMap

Render a map for a single Branch on the Branch show page.

By default it will render a Leaflet map. Pass the prop google to render a Google map instead (ensure the agent has a google_maps_api_key set in admin if you use this).

import { withHomeflowState } from 'homeflowjs';
import { BranchMap } from 'homeflowjs/branches';
ReactDOM.render(
withHomeflowState(BranchMap),
document.getElementById('branch-map'),
);

You can override the default icon by passing an iconConfig prop as described for the BranchesMap component above.

PropTypeDescription
google BooleanUse Google Maps instead of Leaflet to render the map.
customStringPass "simple_bw" to render a simplified grayscale google map.
iconConfig ObjectPass a custom object to be passed to Leaflet Icon
CustomPopup ComponentComponent to render as a popup when marker is clicked

Similar to the Property Map, the Branch Map uses the google maps Javascript API to render a google map, so rendering a popup will require different implementations depending on whether a leaflet or google map is displayed.

If a leaflet map is rendered you can simply pass a React component as the CustomPopup prop, similar to what is done in the Branches Map. The CustomPopup will receive the branch as a prop.

If a google map is rendered you will need to add a template script to the theme with an id of branch-map-popup-template:

<script id="branch-map-popup-template" type="text/template">
<div class="w-96 shadow-lg rounded-lg py-3 px-5 bg-white flex flex-col items-center justify-center p-2">
<h6 class="text-lg text-center uppercase font-lemonmilk_regular">
{{ branch.name }}
</h6>
<p class="text-base text-center">
{{ branch.address_with_commas | split: ',' | first }}
</p>
<a
class="text-base font-light text-primary"
href="tel:{{ branch.contact_number }}"
>
{{ branch.contact_number }}
</a>
<a
href="{{ branch.branch_url }}"
class="text-base underline text-primary"
>
View More
</a>
<div class="flex w-full mt-4 mb-1 justify-center">
<a class="mx-2 text-primary" href="{{ branch.branch_url }}/sales">View properties for sale</a>
<br />
<a class="mx-2 text-primary" href="{{ branch.branch_url }}/lettings">View properties to let</a>
</div>
</div>
</script>

This can either be added directly to /views/branches/_show.liquid or can be added to its own liquid partial, which can then be included in /views/branches/_show.liquid. The innerHTML of this script will be passed to the google map and attached to the marker. Note that you will need to use liquid to generate dynamic branch data.