Map
π How to embed, configure, and use the Mosaic Map component.
Overviewβ
Mosaic is a Salesforce-native geospatial mapping platform built around two Lightning Web Components:
c-mosaic_map(Mosaic: Map) β The map itself. Drop it on any App Page, Record Page, or Experience Cloud page and point it at a configured map.c-mosaic_mapPreviewer(Mosaic: Map Preview) β A dropdown selector that lists every map in your org and embedsc-mosaic_mapfor the chosen one. Useful for an "explore everything" landing page.
A "map" in Mosaic isn't built in code β it's assembled from records. You define layers (points or regions), populate them with bytes (individual features), and link them to a map via settings records. The component reads that configuration at runtime and renders the result. End users get search, filters, bookmarks, dark/light themes, and inline editing built in.
The component handles tile rendering, layer streaming, clustering, popover variants, runtime CSV/GeoJSON uploads, Google Places search, and Anthropic-powered address parsing β all out of the box.
Basic Usageβ
<c-mosaic_map
map-unique-name="customer-overview"
style-config='{"height": "80vh", "minHeight": "400px"}'>
</c-mosaic_map>
map-unique-name is the only required property. It must match a map you've configured in records (see Configuring a Map).
To let users pick which map to load, use the previewer instead:
<c-mosaic_mapPreviewer></c-mosaic_mapPreviewer>
Propertiesβ
c-mosaic_mapβ
| Property | Type | Default | Description |
|---|---|---|---|
map-unique-name | String | β | Required. Identifies which configured map to load. Must match a Map_Unique_Name__c value on your Mosaic_Setting__c rows. |
style-config | String (JSON) | β | Optional CSS sizing overrides as a JSON string. Supported keys: height, minHeight, maxHeight. |
The component is exposed in App Builder as Mosaic: Map with both properties surfaced as design fields. It supports App Pages, Record Pages, and Experience Cloud pages.
c-mosaic_mapPreviewerβ
The previewer takes no properties. It fetches every configured map at load time, renders a dropdown, and mounts c-mosaic_map for the user's selection. Available on App Pages only.
Style Configβ
The style-config property accepts a JSON string of CSS sizing overrides. Use it for flush embeds, fixed-height slots, or to enforce a minimum size on responsive pages.
| Key | Description | Example |
|---|---|---|
height | Outer container height | "80vh", "600px", "100%" |
minHeight | Minimum height | "400px" |
maxHeight | Maximum height | "900px" |
<c-mosaic_map
map-unique-name="customer-overview"
style-config='{"height": "100%", "minHeight": "600px"}'>
</c-mosaic_map>
Note: When omitted, the component fills its parent container. If the parent has no height, the map will collapse β always set a height somewhere up the tree.
Configuring a Mapβ
A map is a collection of layers grouped under a shared Map_Unique_Name__c. The setup is record-based β no code, no deployment.
1. Assign the permission setβ
Grant the Mosaic Admin permission set to anyone who needs to manage maps and layers. End users only need read access on the underlying data; they don't need this permission set to view a map.
2. Configure API keysβ
Open the FL Mosaic custom metadata type and create a record named global (or update the existing one) with:
| Field | Required for | Notes |
|---|---|---|
Mapbox API Key | Tile rendering | Must have access to the Mapbox styles you intend to use. |
Google Maps API Key | Google Places search; Save as Account | Enable the Places API in Google Cloud Console. |
Flourish API credentials (FL_API_*) | Reserved for future Flourish integrations | Optional. |
3. Create one or more layersβ
Open the Mosaic Layers tab and create a Mosaic_Layer__c record per layer.
4. Link layers to a mapβ
Open the Mosaic Settings tab. For each layer in the map, create a Mosaic_Setting__c:
| Field | Value |
|---|---|
Map Unique Name | Your chosen identifier (e.g. customer-overview). |
Type | Component |
Key | layer |
Layer | Lookup to the Mosaic_Layer__c to include. |
Optionally add a row with Type blank, Key = label, Value = the human-readable map name. The Map Previewer dropdown reads this.
That's it β drop c-mosaic_map on a page with map-unique-name="customer-overview" and the map renders.
Layersβ
Two axes drive a layer's behavior: what it renders (Geometry Type) and where its data comes from (Recall Type).
Geometry Typeβ
| Value | Renders as |
|---|---|
Point | Markers (clustered automatically at high zoom). |
Region | Polygon overlays from a GeoJSON file. |
Recall Typeβ
| Value | Best for | Trade-offs |
|---|---|---|
Bytes | Curated, relatively static data; large volumes | Faster; data lives in Mosaic_Byte__c records. Required if you want users to add points to the layer at runtime. |
Query | Live Salesforce records (Accounts, Contacts, Cases) | Always current; bound by SOQL row limits and query performance. Read-only from the UI. |
Layer fields referenceβ
| Field | Applies to | Description |
|---|---|---|
Name | All | Display name in the legend. |
Unique Name | All | Stable external key. Auto-generated for layers created from runtime uploads. |
Geometry Type | All | Point or Region. |
Recall Type | All | Bytes or Query. |
Point Icon URL | Point | Public URL to the marker icon (PNG or SVG). |
Point Popover Variant | Point | Fields, Chronicle, or Google Search. See Point Popovers. |
Point Popover Configs | Point | JSON. For Chronicle: {"templateId": "<id>"}. |
Point Configs | Point | JSON for advanced point options. |
Region GeoJSON URL | Region | Publicly accessible GeoJSON FeatureCollection. |
Region ID Property | Region | Property in the GeoJSON properties block that joins to Mosaic_Byte__c.Region_Id__c. |
Region ID Label / Region Value Label | Region | Friendly labels for the data tooltip. |
Region Color Map | Region | JSON object mapping Region_Value__c β hex color (choropleth). |
Query SObject Name | Query mode | e.g. Account, Contact. |
Query Where | Query mode | SOQL WHERE clause without the keyword: Type = 'Customer'. |
Query Lat / Query Lng | Query mode, points | API names of the lat/lng fields on the source sObject. |
Query Region Id / Query Region Value | Query mode, regions | API names of the region-id/value fields. |
Query Metadata Fields | Query mode | Comma-separated API names, OR * to expand to every accessible non-compound field. |
Note:
Query Metadata Fields = *is a quick way to surface "everything" in the popover without listing fields by hand. Address and Location compound fields, plusIdandCreatedDate, are filtered automatically.
Loading Dataβ
There are two ways to populate a Bytes-mode layer: bulk-load Mosaic_Byte__c records directly, or upload data at runtime through the map UI.
Mosaic_Byte__c fieldsβ
| Field | Required | Description |
|---|---|---|
Layer | Yes | Master-detail to the parent layer. |
Lat / Lng | Points | Coordinates. |
Region Id | Regions | Joins to a feature in the layer's GeoJSON. |
Region Value | Regions | Drives choropleth coloring through the layer's color map. |
Color | No | Hex color override for an individual feature. |
Label | No | Auto-generated if blank. Shown in the popover header and search results. |
UUID | No | Auto-generated by trigger. |
Metadata | No | JSON payload that drives the popover, search index, and filter property list. |
Metadata formatβ
The Metadata field accepts either format:
Object β keys become field names; the Fields popover auto-humanizes them for display (e.g. Billing_Street__c β "Billing Street").
{
"Name": "Acme Corp",
"Industry": "Tech",
"Billing_Street__c": "100 Main St"
}
Array β use this when you want explicit display labels or want to declare Apex data types so the popover picks the right input control.
[
{ "name": "Name", "label": "Company Name", "value": "Acme Corp" },
{ "name": "Website", "label": "Site", "value": "https://acme.com", "apexDataType": "URL" }
]
Runtime uploadsβ
The fastest way to bulk-load data is the upload modal. From the Regions & Points panel, click the upload icon next to Points or Regions.
Points require a CSV with Lat and Lng columns. Every other column becomes searchable/filterable metadata.
Regions require a GeoJSON FeatureCollection (.geojson or .json). Once loaded, pick the Region ID property that uniquely identifies each feature. Optionally provide a Region ID label for display ("Zip Code", "County Name").
Newly uploaded layers are marked Session β they live only in the browser. To persist, open the layer's action menu and choose Save to Salesforce.
Point Popoversβ
Clicking a point opens a details popover. The header shows a contextual action bar; the body renders one of three variants determined by the layer's Point Popover Variant field.
Action barβ
Buttons appear based on context:
| Button | Shown when |
|---|---|
| Go to Record | Metadata contains an Id field. Opens the underlying Salesforce record in a new tab. |
| Edit / Done | Variant is Fields. Toggles inline edit mode. |
| Save as Account | Variant is Google Search. Creates an Account from the place data. |
| Add to Layer | Variant is Google Search. Persists the place as a real point on a chosen Bytes-mode layer. |
| Google Maps | Variant is Google Search and a place_id is present. Opens the place on Google Maps. |
Variantsβ
| Variant | Use when | Notes |
|---|---|---|
Fields | Default β auto-renders metadata as a form | Field types are inferred from apexDataType first, then value heuristics (URLs become links, numbers right-align, booleans become toggles, long strings become full-width textareas). Click Edit to modify any field; saves persist back to Salesforce. |
Chronicle | You have a Chronicle form template to embed | Set {"templateId": "<id>"} in Point Popover Configs. Prefill is auto-derived from Query Metadata Fields β no formFieldMap required. |
Google Search | Surface external Google Places results | Reserved for points sourced from POI search. Displays Categories, Business Status, and "Open Now" when available. |
Note: A
Flowvariant is reserved but not currently rendered. Treat it as inactive until reinstated.
Inline editingβ
In the Fields variant, click Edit to flip every field into edit mode. Change values, then click Done β only changed fields are sent back to Salesforce. The change updates the byte's metadata, the search index, and the filter property cache automatically.
Searchβ
Mosaic offers two complementary search surfaces.
Top search barβ
Searches across:
- Your data β full-text match against label and metadata for every loaded layer.
- Google Places β included automatically when the "Always include Google Places" toggle is on; otherwise on demand by clicking the "Search Google Places forβ¦" link in the dropdown.
Clicking a result from your data flies the map to it and opens its popover. Clicking a Google result drops a yellow marker, flies to the location, and opens the Google Search popover β from there you can save it as an Account or add it to a layer.
Search panel (side nav)β
Three sub-features:
- Places of Interest β Type a keyword ("churches", "schools") and press Enter to query Google Places in the current map view. Results appear as a dismissible POI layer with yellow markers.
- Regions & Points β Pick a dataset, optionally scope to a single property, type a keyword, press Enter. Each search becomes a pill at the bottom; click between pills to switch.
- Search Settings β Toggle "Always include Google Places in search bar results."
Filtersβ
Each point layer with metadata properties exposes a filter funnel. Click it to open the filter panel for that layer.
A filter clause has three parts:
- Property β Any metadata field on the layer.
- Operator β Typed by property: text gets
equals/contains/starts with; numbers getgreater than/less than; dates getbefore/after; etc. - Value β Skipped entirely for value-less operators like
is blank.
Click Add Filter to apply. Filter pills appear below β click a pill to toggle it on/off without deleting; click the X to delete.
If other layers share the same properties, an Apply these filters to other layers section lets you check boxes and apply the active filter set to those layers in one click.
Bookmarksβ
Bookmarks let users collect points and regions across layers into named sets for later review.
- In the Bookmarks panel, type a name and click + to create a set. New sets start as Session (in-memory only).
- With the set focused, hold the B key and click points or regions on the map to add them. Click again to remove.
- Toggle Only show bookmarked items to hide everything else from the map view.
- Click Save Set to persist to Salesforce, or Delete Set to discard.
Bookmark sets are stored as JSON on a Mosaic_Setting__c record with Key = "bookmarks", scoped to the map's Map_Unique_Name__c. They survive across sessions once saved.
Note: The B-key shortcut requires a focused set. Open the Bookmarks panel and click a set first, otherwise B+click is a no-op.
Settingsβ
The Settings panel exposes user-adjustable preferences.
| Setting | Effect |
|---|---|
| Theme | Switches the basemap style (light, dark, satellite β depending on what's enabled in your Mapbox account). |
| Toggle Fullscreen | Expands the map to fill the browser viewport. |
In addition, the campaign-icon button on the map overlay saves the current center and zoom as the default starting view. Each user's pinned location is saved to their own Mosaic_Setting__c row, so different users can have different defaults for the same map.
Map Preferences (admin)β
User-facing preferences are stored as Mosaic_Setting__c rows with Type blank. Mosaic recognizes:
| Key | Value (JSON) | Effect |
|---|---|---|
label | "Customer Overview" | Display name in the previewer dropdown. |
mapTheme | "light", "dark", etc. | Default basemap style. |
defaultMapStart | {"lat": 29.76, "lng": -95.37, "zoom": 11} | Default center and zoom on load. |
bookmarks | (managed by the app) | User-saved bookmark sets. |
includeGoogleSearch | "true" / "false" | Whether top-bar searches always include Google Places. |
Most preferences are written automatically when users change settings or pin a default location. Manually edit them only when seeding initial state.
Time Seriesβ
When time-series datasets are configured for a map, a Time Series tab appears in the side nav. Users select an aggregation level (day/week/month) and an aggregation type, then click a dataset title to render a timeline along the bottom of the map. A play button steps through dates, animating the map as values change over time.
If no time-series datasets are configured for the map, the tab content shows a "no datasets available" message.
Embedding Examplesβ
On a record pageβ
Drop the component on a record page in App Builder. Set Map Unique Name to your configured map. Optionally set Style Configurations to a JSON string for sizing.
<c-mosaic_map
map-unique-name="account-territory"
style-config='{"height": "600px"}'>
</c-mosaic_map>
Full-height sidebar embedβ
Fill a sidebar panel flush with the surrounding chrome:
<c-mosaic_map
map-unique-name="customer-overview"
style-config='{"height": "100%", "minHeight": "500px"}'>
</c-mosaic_map>
Map picker landing pageβ
Surface every map in the org from a single page:
<c-mosaic_mapPreviewer></c-mosaic_mapPreviewer>
Experience Cloud (community) pageβ
Both components support lightningCommunity__Page. Confirm the API user (typically a guest user or community license) has the Mosaic Admin permission set or at minimum read access to Mosaic_Layer__c, Mosaic_Byte__c, and Mosaic_Setting__c.
External Integrationsβ
| Service | Used for | Configured at |
|---|---|---|
| Mapbox | Tile rendering | FL_Mosaic__mdt.Mapbox_API_Key__c |
| Google Places | POI search, search-bar Google results, Save as Account enrichment | FL_Mosaic__mdt.Google_Maps_API_Key__c |
| Anthropic | Address parsing in the legacy "Add Org" flow | Configured via FL Mosaic metadata / named credential |
All callouts go through Apex. No cross-origin requests are made directly from the browser.
Each external host is also declared in Remote Site Settings and CSP Trusted Sites β both are deployed with the package, but verify they're enabled if callouts fail.
Troubleshootingβ
The map renders but no layers appear.
Confirm at least one Mosaic_Setting__c exists with Type = "Component", Key = "layer", the matching Map_Unique_Name__c, and a Layer lookup to a published Mosaic_Layer__c.
A point's popover shows raw JSON.
Metadata is probably an unstructured string. Save it as a proper JSON object or array, or change the layer's Point Popover Variant to Fields so the auto-renderer can lay it out.
My runtime layer disappeared after I refreshed. Session layers (CSV/GeoJSON uploads) live only in the browser. Use the layer's action menu β Save to Salesforce to persist them.
The map won't load tiles.
Check the Mapbox API Key in FL Mosaic, and that api.mapbox.com is allowed in Remote Site Settings and CSP Trusted Sites.
Google Places search returns nothing. Confirm the Google Maps API Key in FL Mosaic, that the key has the Places API enabled in Google Cloud, and that the host is allowed in Remote Site Settings and CSP Trusted Sites. Mosaic surfaces Google's own error message in the toast β read it before assuming a configuration issue.
"Add to Layer" doesn't show my layer.
Only Bytes-mode point layers can accept new points from the Google Search popover. Query-mode layers are read-only β change the layer's Recall Type to Bytes, or pick a different target.
"Save as Account" failed. The acting user needs Create permission on the Account object. The Mosaic Admin permission set covers map configuration but not necessarily Account creation in your org.
Top-search-bar Google results have a different label than POI panel results. When you click a single result from the top dropdown, Mosaic uses that result's name as the layer label. When you run a multi-result POI search from the side panel, the layer is named after the query β because the result set may contain many places.
The B-key shortcut isn't adding bookmarks. Open the Bookmarks panel and click a set first to focus it. B+click only works against the focused set.
Keyboard Shortcutsβ
| Shortcut | Action |
|---|---|
| B + click | Add or remove a point/region from the focused bookmark set |