Skip to Content
Attributes

Attributes

<mapvx-website> takes 11 inputs. Each one is available as an HTML attribute (kebab-case) and as a JavaScript property (camelCase) on the element.

<mapvx-website api-key="YOUR_API_KEY" institution-id="YOUR_INSTITUTION_ID" default-to-map="true" show-city-filter="false" rows-per-page="3" ></mapvx-website>

All attributes

AttributePropertyTypeDefaultDescription
api-keyapiKeystring''MapVX API key. Required for data from MapVX, the map, search and routes. Read once.
institution-idinstitutionIdstring''Institution the directory shows: categories, city and search scope.
initial-datainitialDatastring (JSON)''Data prepared on your server with prepareInitialData.
show-category-filtersshowCategoryFiltersbooleantrueCategory tabs and category filtering.
show-city-filtershowCityFilterbooleantrueCity picker and city scoping of the list.
show-view-toggleshowViewTogglebooleantrueThe Grid View / Map View toggle.
show-search-barshowSearchBarbooleantrueThe search bar in the header.
show-drop-pinshowDropPinbooleanfalseThe map button that drops a pin to route from.
zoomzoomnumberconfiguredThe zoom level the map opens at.
centercenterstringconfiguredWhere the map is centred, as lat,lng.
selected-categoriesselectedCategoriesstring (comma-separated)''Categories to filter by, for a host driving the filter itself.
search-termsearchTermstring''The term to search for, for a host driving the search itself.
full-width-mapfullWidthMapbooleanfalseIn map view, let the map fill the width and hide the card list beside it.
hide-unselected-markershideUnselectedMarkersbooleanfalseWhile a place profile is open, leave only that place’s marker on the map.
default-to-mapdefaultToMapbooleanfalseOpen in map view instead of grid view.
inherit-font-familyinheritFontFamilybooleanfalseUse your page’s font family instead of Open Sans.
hide-dealshideDealsbooleanfalseHide deals and events on place profiles and cards.
show-deal-labelsshowDealLabelsbooleanfalseShow a “Deals + Events” label on cards.
card-widthcardWidthnumberunset (237 px)Minimum width of a card column, in pixels.
rows-per-pagerowsPerPagenumber2Rows of cards per page, from 1 to 10.
  • Write attribute names in kebab-case. HTML lowercases attribute names, so defaultToMap="true" becomes defaulttomap and is ignored. The camelCase names only work as JavaScript properties.
  • In HTML every value is a string. Booleans and numbers are parsed as described in Boolean attributes and Numeric attributes.
  • There are no other inputs. The interface text is English only, the map’s initial position and zoom come from your MapVX configuration, and colors are set with CSS variables.

A boolean attribute is on only with the exact value "true". A bare attribute such as <mapvx-website show-category-filters> has the value "", which reads as false, so it turns the category tabs off.

api-key

Your MapVX API key. The component loads places, configuration and institutions with it, and the map, search, place details and routes all depend on it.

  • Read once. The first non-empty value, with surrounding whitespace trimmed, initializes the MapVX SDK and starts loading data. Later changes are ignored until the page reloads: nothing is re-initialized or fetched again. A key that arrives late still works, for example when the attribute starts empty and your code sets it afterwards.
  • Shared by the page. The SDK is shared by the whole page, so the first key used wins. Removing the element and adding it again does not switch to a new key. Use a single <mapvx-website> per page: several elements share one application and interfere with each other (Troubleshooting).
  • Not validated. Without a key, or with a wrong one, nothing loads from MapVX: the search box and the Grid View / Map View buttons appear, but the list stays empty (apart from places passed in initial-data), the map stays blank, and the component shows no error message (Troubleshooting).
  • Public. Anyone can read the key in your page’s HTML or scripts. Security and privacy describes what the component sends to MapVX and to third parties.

institution-id

The id of the institution (a mall, a campus, a hub…) the directory shows. The component works without it, but several features depend on it, so set it.

What it controls:

  • Category tabs: they come from the categories of the institution whose id matches exactly.
  • City scope: the city option whose institution id matches is selected (or, if none does, the one whose filter id matches), and the grid and search are scoped to it.
  • City picker: when the institution belongs to a city (a hub or a mall inside a city), only that city is offered, and a picker with a single city is hidden.
  • ?destination= deep links: the route screen pre-fills the destination only with a place that belongs to the current institution (Events).

When it is empty or matches nothing, no error or warning is shown, and:

  • The city falls back to the first city option in your configuration.
  • No category tabs appear until the visitor picks a city or opens a place.
  • A ?destination= deep link opens the route screen with an empty destination.

Pass the id exactly as MapVX gave it: same case, no surrounding spaces. It is trimmed only when matching city options: the institution lookup compares the raw value, so an id with a leading space selects its city but shows no category tabs.

You can change it at any time: the category tabs, the city scope and the map’s building follow. A city the visitor picked by hand is replaced when the attribute changes, and an id that matches no loaded institution keeps the previous category tabs. Do not remove the attribute; set it to '' instead (Removing attributes).

initial-data

A JSON string with data your server fetched in advance, so that place cards can appear before the component’s own requests finish. Generate it with prepareInitialData from @mapvx/web-components-ssr-helpers and pass the returned string unchanged (SSR and initial data).

  • Shape: the JSON of { availablePlaces, institutions } (InitialData type). Other keys are ignored.
  • A string, not an object: as a property, pass the JSON string. An object throws a TypeError inside the component.
  • Invalid JSON is ignored without any console output, and the component loads from the API as usual.
  • It does not replace the API: with api-key set, the component still requests places, configuration and institutions from MapVX. api-key is still required, because the map, search, place details and routes need it.
  • Parsed again on change: every new non-empty value is parsed. Places are added to the list, not replaced; institutions replace the previous list. The institution whose id equals institution-id exactly becomes the current one.

In 1.6.1, using initial-data together with api-key lists every place twice, and each later change of initial-data or institution-id adds the places again. See the known issue.

default-to-map

"true" opens the directory in map view; any other value opens the grid. It only decides the first view for visitors who have not picked one yet.

Remembered view

Since 1.6.0, when a visitor clicks Grid View or Map View, the choice is saved in localStorage under the key mapvx:active-view, with the value grid or map. From then on:

  • The saved view wins over default-to-map on every later load, and changing default-to-map at runtime has no visible effect.
  • The key belongs to your origin, not to a page or an institution: every page and every <mapvx-website> on the same origin shares it.
  • If storage is unavailable (private browsing, blocked site data), the choice is not remembered and default-to-map applies on each load.

To check default-to-map while testing, delete the key in your browser’s developer tools, or run localStorage.removeItem('mapvx:active-view') and reload. To make default-to-map always win, remove the key before the element is created. This discards the visitor’s choice on every load:

<script> try { localStorage.removeItem('mapvx:active-view') } catch {} </script> <link rel="stylesheet" href="https://unpkg.com/@mapvx/web-components-ssr@1.6.1/dist/browser/styles.css" /> <script type="module" src="https://unpkg.com/@mapvx/web-components-ssr@1.6.1/dist/browser/main.js" ></script> <mapvx-website api-key="YOUR_API_KEY" institution-id="YOUR_INSTITUTION_ID" default-to-map="true" ></mapvx-website>

Security and privacy lists everything the component stores in the browser.

show-category-filters

Default true. Shows the category row above the grid and filters the list by the categories turned on.

  • Each category is a button that turns on and off on its own, and several can be on at once. A place in any of the chosen categories is listed — they union, they do not narrow each other.
  • Nothing is on at the start, which means no category filtering: the list shows every place in the current city scope. All is on offer as a way to clear the rest, not as a category to keep.
  • The categories are those of the current institution, which starts as the one matched by institution-id. Without a matching institution there is nothing to show.
  • Categories with no place to show are left out, and the row is hidden when only All is left, since there would be nothing to tick. A category that stops being on offer also stops being selected.
  • A ?tab= query parameter turns specific categories on, several separated by commas (Events).
  • "false" hides the row and turns category filtering off. To keep the filtering but draw the control yourself, hide the row and drive it with selected-categories.

show-city-filter

Default true. Shows the city picker in the header (a filter icon in narrow layouts) and scopes the grid and the map to the selected city.

  • The picker appears only when at least two cities are available. With a single city it is hidden, but the list is still scoped to that city.
  • "false" hides the picker but keeps the scope: the grid and the map stay on the city in scope, which with nothing picked is the first one configured. Hiding a control does not widen what an embed lists. Search stays scoped to the same city.
  • To move the scope from a control of your own, listen to citiesChange and write the id it hands you into institution-id.

show-view-toggle

Default true. Shows the Grid View / Map View toggle on the right of the header.

  • "false" hides the toggle. The view then follows default-to-map, and a remembered view is ignored, so the view stays the one you asked for instead of whatever the visitor last picked.
  • Pair it with default-to-map="true" to pin the component to the map, or leave default-to-map unset to pin it to the grid.

Default true. Shows the search bar on the left of the header.

  • "false" hides the bar and leaves search unreachable, so a ?search= query parameter is ignored as well. The other deep links still work.
  • The header row disappears entirely when the search bar, the city picker and the view toggle are all hidden, so no empty bar is left above the content.

show-drop-pin

Default false. "true" shows the button that arms the map to drop an origin pin, at the top of the map’s button column on the directory and place-profile maps.

  • Off by default, unlike the other show-* attributes: the button is new, so an embed gets it only once the page asks for it.
  • Tapping the button arms the map, and it stays armed: the first tap on the map drops the pin and every tap after that moves it, so a visitor corrects it by tapping somewhere else as readily as by dragging it. Pressing the button again is what disarms the map and hands it back to opening places.
  • The pin is used as the origin when a route is opened.
  • Turning it back off takes the button only. A pin already dropped stays where it is, and the route screen keeps letting a visitor pick an origin by tapping its own map.
  • The button is deliberately not on the route screen’s map, which already takes any tap as the origin.

zoom

Default: the zoom configured for the place. The zoom level the map opens at.

  • For a host that embeds the same venue at more than one scale: an overview on a landing page, a close-up beside a single place.
  • Set it after load and the map moves to it, so a host can drive the camera from controls of its own.
  • The zoom limits configured for the place still apply.
  • A value that is not a number is ignored, leaving the configured zoom in charge.
  • To follow the zoom rather than set it — a pinch, the built-in buttons, the fit on a city’s places — listen to zoomChange. Writing what it reports back into this attribute moves nothing, so a control of your own can be a readout as well as an input.

center

Default: the centre configured for the place. Where the map is centred, as lat,lng.

<mapvx-website api-key="YOUR_KEY" zoom="17" center="42.3314,-83.0458"></mapvx-website>
  • A { lat, lng } object works too, for a host that sets the property rather than the attribute: el.center = { lat: 42.3314, lng: -83.0458 }.
  • Both halves have to be readable. A lone 42.3314 is ignored rather than taken as a latitude, since a coordinate missing half of itself points nowhere near the venue.
  • The centre-map button returns here rather than to the configured centre, so it takes the visitor back to the view the embed opened on.
  • To keep the map on the pin the visitor drops, listen to droppedPinChange and write the coordinate it carries back into this attribute.
  • To put the pin on the coordinate the map opens on, set dropped-pin to it as well. Centring alone leaves the map empty.

dropped-pin

Default: none, and the pin stays the visitor’s to place. Where the pin sits, as lat,lng.

<mapvx-website api-key="YOUR_KEY" center="42.3314,-83.0458" dropped-pin="42.3314,-83.0458" ></mapvx-website>
  • The setting half of droppedPinChange, for a pin the visitor never tapped: a coordinate typed into a field of your own, a result picked out of your own search, a place carried in from another page.
  • A { lat, lng } object works too, for a host that sets the property rather than the attribute: el.droppedPin = { lat: 42.3314, lng: -83.0458 }.
  • Both halves have to be readable, the same as center. An empty or unreadable value leaves whatever is already on the map alone, so an embed that never sets this behaves exactly as before.
  • Writing what droppedPinChange reports straight back into it is safe. A pin already on that coordinate is not a move, so the attribute and the map cannot chase each other.
  • It places the pin without moving the camera. To open on the pin as well, give center the same coordinate.
  • The pin does not need show-drop-pin. That attribute shows the button the visitor drops a pin with; this one places the pin itself.

selected-categories

Default empty. The categories the directory is filtered by, as a comma-separated list of their names.

For a host that draws its own category control — checkboxes of its own, say — instead of the built-in row. Hide that row with show-category-filters="false", listen to categoriesChange for the names to offer, and write the chosen ones back here.

<mapvx-website api-key="YOUR_KEY" show-category-filters="false" selected-categories="Shopping,Hotels" ></mapvx-website>
  • Several categories union: a place in any of them is listed.
  • Empty means no category filtering, and so does All — it is the entry that stands for “no filter”, not a category of its own.
  • Names that are not on offer are dropped rather than emptying the directory. Spacing around the commas is ignored.
  • It sets the filter; it does not freeze it. If the built-in row is left visible, a visitor can still change the selection from there, and select-filter reports it.

search-term

Default empty. Runs a search for this term, for a host that puts its own search box outside the component.

<mapvx-website api-key="YOUR_KEY" show-search-bar="false" search-term="coffee"></mapvx-website>
  • Setting it opens the search view with the term; emptying it clears the search and returns to the directory.
  • Unlike the ?search= deep link, it works with show-search-bar="false" — a host hiding the built-in bar to put its own in its place still has to be able to run a search.
  • It does not fight the built-in bar. A visitor typing there changes the search without this attribute changing, and the component follows the visitor.

full-width-map

Default false. Only affects the map view.

  • "true" hides the card list beside the map and lets the map fill the width of the component.
  • The grid view is unchanged: there the card list is the view itself, so it is never hidden.
  • For a map-only embed, combine it with default-to-map="true" and show-view-toggle="false".

hide-unselected-markers

Default false. Only affects the map while a place profile is open.

  • "true" leaves the open place’s marker alone on the map and hides every other one, so the visitor sees where that place is without its neighbours around it.
  • The other markers are hidden, not removed, so returning to the list brings them all back with nothing to reload.
  • Changing it while a profile is already open takes effect on that profile straight away, in both directions.

hide-deals and show-deal-labels

Places can carry banners tagged as deals or events.

  • hide-deals (default false): "true" hides the Deals + Events section of place profiles and the label on cards. It takes precedence over show-deal-labels.
  • show-deal-labels (default false): "true" shows a Deals + Events label over the card image of places that have such a banner, once the image has loaded. It has no effect while hide-deals is "true".

With both defaults, place profiles show the deals section and cards show no label.

inherit-font-family

Default false: text uses 'Open Sans', sans-serif, except inside some buttons, as explained below. The package does not load Open Sans, so unless your page loads it or the visitor has it installed, the browser’s default sans-serif font is used (Styling).

"true" switches the component to font-family: inherit, so it uses the font family that <mapvx-website> inherits from your page (or that you set on it). Only the family changes: font sizes and weights stay the component’s own. Map labels are drawn by the map and do not change.

With either value, the text inside many of the component’s buttons (for example place card titles and addresses, the Back labels, the selected city in the city picker, the Pedestrian-friendly directions and Start Route buttons, and the route controls) uses the browser’s default button font, because the component sets no font family on those buttons. Unless your CSS already sets font-family: inherit on buttons, as many CSS resets do, add this rule so that text follows the component’s font too (Fonts):

mapvx-website button { font-family: inherit; }

card-width

The minimum width of a card column in the grid, in pixels, written without a unit. Cards stretch to fill each row, so they are usually wider than this value.

  • Unset: 237 px, or 170 px when the component itself is 640 px wide or narrower. The breakpoint is the component’s width, not the viewport’s (Styling).
  • A custom value replaces both defaults, so the narrow layout uses it too.
  • It also decides how many cards fit in a row, and therefore how many cards a page holds.
  • 0, negative and non-numeric values use the default (Numeric attributes).

rows-per-page

Rows of cards per page. The default is 2 and the value is clamped to the range 1 to 10. It applies to the grid, the card list in map view and search results.

Cards per page = cards that fit in one row × rows-per-page. A page shows fewer rows when there are not enough places.

The page size is measured from the component’s width when the list renders and is not recalculated when the window is resized. It updates when the visitor switches between grid and map, when the list is shown again, or when card-width or rows-per-page changes.

Boolean attributes

Eleven attributes are booleans: show-category-filters, show-city-filter, show-view-toggle, show-search-bar, show-drop-pin, full-width-map, hide-unselected-markers, default-to-map, inherit-font-family, hide-deals and show-deal-labels. A string value is true only when it is exactly "true":

MarkupResult
default-to-map="true"true
default-to-map="false"false
default-to-map (no value)false
default-to-map="TRUE", "1" or "yes"false
Attribute never setThe attribute’s default
Attribute removed after being setTreated as false (Removing attributes)

A bare attribute is the most common mistake. show-category-filters and show-city-filter default to true, so <mapvx-website show-city-filter> turns the city filter off. Always write the value.

As JavaScript properties, real booleans are used as they are (el.showCityFilter = false) and strings are parsed like attributes. Other values are not converted (for example, 1 counts as true), so pass booleans.

Framework bindings

Frameworks turn boolean values into attributes in different ways. The strings "true" and "false" work in all of them.

<!-- Correct --> <mapvx-website default-to-map="true" show-city-filter="false"></mapvx-website> <!-- Wrong: both attributes are "", which reads as false --> <mapvx-website default-to-map show-category-filters></mapvx-website>

With any other framework, inspect the rendered element in the browser’s developer tools and check that each boolean attribute holds the string "true" or "false".

Numeric attributes

card-width and rows-per-page parse strings with parseInt: the value is read up to the first character that is not a digit, and decimals are truncated.

Casecard-widthrows-per-page
Whole number"280" gives 280"3" gives 3
Trailing text"280px" gives 280"3 rows" gives 3
Decimal"250.7" gives 250"3.7" gives 3
Above the maximumNo maximum"15" gives 10
Zero or negativeDefault2
Empty or not a numberDefault2
Attribute removedDefault2

As JavaScript properties, numbers are not rounded. cardWidth keeps decimals, and rowsPerPage is clamped to 1 to 10 but not rounded, so pass whole numbers. Zero and negative numbers fall back to the defaults, as with strings.

Your own controls

The search box and the category row can be replaced with controls of your own — to match your site’s design, to put them somewhere else on the page, or to combine them with filters the component knows nothing about. Hide the built-in ones and drive the component through its public API.

Three pieces do it:

PieceDirectionWhat it is for
categoriesChangecomponent → youWhich categories exist, so you know what to draw.
selected-categoriesyou → componentWhich ones are on.
search-termyou → componentWhat to search for.
<input id="q" type="search" placeholder="Search places…" /> <div id="categories"></div> <mapvx-website id="directory" api-key="YOUR_API_KEY" institution-id="YOUR_INSTITUTION_ID" show-search-bar="false" show-category-filters="false" ></mapvx-website>
const directory = document.querySelector('#directory') const selected = new Set() // 1. Draw a checkbox per category, from the list the component resolves. directory.addEventListener('categoriesChange', (event) => { const categories = event.detail.filter((category) => category.name !== 'All') // A category that is no longer offered must stop being selected. for (const name of selected) { if (!categories.some((category) => category.name === name)) selected.delete(name) } document.querySelector('#categories').replaceChildren( ...categories.map((category) => { const label = document.createElement('label') const box = document.createElement('input') box.type = 'checkbox' box.checked = selected.has(category.name) box.addEventListener('change', () => { box.checked ? selected.add(category.name) : selected.delete(category.name) // 2. Hand the whole selection back. directory.setAttribute('selected-categories', [...selected].join(',')) }) label.append(box, category.name) return label }), ) }) // 3. Search. document.querySelector('#q').addEventListener('input', (event) => { directory.setAttribute('search-term', event.target.value) })
  • Let the component resolve the categories. categoriesChange reports the list it actually offers: categories whose places this API key never returns are already dropped, and All is already added. Deriving that yourself from initial-data means reproducing rules that can change.
  • All is not a checkbox. Clearing the selection means the same thing, so a “clear” button is usually the better control. If you do draw it, tick it when nothing else is on.
  • Both controls can coexist. Leaving the built-in row visible is fine: a visitor changing it fires select-filter with filters, which you can use to keep your checkboxes in step.
  • Clearing. An empty selected-categories means no category filter; an empty search-term clears the search and returns to the directory.

JavaScript properties

Every attribute has a camelCase property on the element (see the table). Properties are convenient when the values come from code; attributes cover every option too.

const el = document.createElement('mapvx-website') el.apiKey = 'YOUR_API_KEY' // string; only the first non-empty value is used el.institutionId = 'YOUR_INSTITUTION_ID' // string el.defaultToMap = true // booleans are used as they are el.showCityFilter = false el.cardWidth = 280 // minimum column width in px el.rowsPerPage = 3 // clamped to 1–10 // el.initialData = initialDataJson // JSON string from prepareInitialData, not an object document.querySelector('#directory').append(el)
  • Types: apiKey, institutionId and initialData must be strings: a number or an object throws a TypeError inside the component. The booleans take true or false, and cardWidth and rowsPerPage take numbers or numeric strings.
  • Before the element is defined: you can set properties before main.js has registered <mapvx-website>, on an element already in the page or on one you created. The values are applied when the element is upgraded. To run code after registration, see Installation.
  • Reading: once the element is in the page and running, a property returns the parsed value (for example, rowsPerPage returns 10 after you set '15'). Before that, it returns the value you set.
  • No attribute reflection: setting a property does not change the attribute, so getAttribute() keeps returning the old value. Set each input one way, either as an attribute or as a property.
  • TypeScript: the package ships no type for the element. Declare one as shown in TypeScript types.
  • React 19: a camelCase prop such as apiKey is set as a property only if the element is already defined when React renders. Otherwise React writes a lowercase attribute (apikey), which the component ignores. Use kebab-case attributes in JSX.

Changes after initialization

Attribute and property changes are picked up without any extra call. Some inputs only matter at start-up:

InputChange after the component has loaded
api-keyIgnored once a key has been used. Reload the page to use another key.
institution-idApplied: category tabs, city scope and the map’s building follow. Replaces a city the visitor picked.
initial-dataParsed again on each non-empty change. Places are added to the list, not replaced.
show-category-filters, show-city-filterApplied.
show-view-toggle, show-search-bar, full-width-mapApplied.
show-drop-pinApplied. A pin already dropped stays on the map.
zoom, centerApplied: the map moves to the camera you set.
hide-unselected-markersApplied, including to a profile that is already open.
hide-deals, show-deal-labelsApplied.
inherit-font-familyApplied.
card-width, rows-per-pageApplied; the page size is recalculated.
default-to-mapApplied only until the visitor picks a view, and never while a remembered view exists.

Removing attributes

Removing an attribute does not restore its default: the component receives null.

Attribute removedResult
institution-idA TypeError is thrown inside the component and logged to the console.
show-category-filters, show-city-filter, show-view-toggle, show-search-barTreated as false: the feature is hidden instead of going back to its default true.
default-to-map, full-width-map, hide-unselected-markers, inherit-font-family, hide-deals, show-deal-labels, show-drop-pinTreated as false, which matches their default.
zoom, centerThe override is dropped. The map stays where it is, and one built afterwards opens on the camera configured for the place.
card-widthDefault width.
rows-per-page2, the default.
api-key, initial-dataIgnored; the key and the data already loaded stay.

Framework bindings remove attributes too: React, Vue and Angular [attr.*] bindings remove an attribute when its bound value becomes null or undefined (React 19 also removes it for false). Keep bound values defined.

const el = document.querySelector('mapvx-website') // Avoid: throws a TypeError inside the component el.removeAttribute('institution-id') // Instead el.setAttribute('institution-id', '') // the city falls back to the first option el.setAttribute('show-city-filter', 'true') // back to the default

With institution-id set to '', the city scope falls back to the first city option and the category tabs of the previous institution stay. See also Troubleshooting.

Full example

Every attribute except initial-data (usually rendered by your server), including the ones left at their defaults, with the same configuration as properties:

<link rel="stylesheet" href="https://unpkg.com/@mapvx/web-components-ssr@1.6.1/dist/browser/styles.css" /> <script type="module" src="https://unpkg.com/@mapvx/web-components-ssr@1.6.1/dist/browser/main.js" ></script> <style> mapvx-website { display: block; width: 100%; } </style> <mapvx-website api-key="YOUR_API_KEY" institution-id="YOUR_INSTITUTION_ID" show-category-filters="true" show-city-filter="false" show-view-toggle="true" show-search-bar="true" show-drop-pin="true" selected-categories="" search-term="" full-width-map="false" hide-unselected-markers="false" default-to-map="false" inherit-font-family="true" hide-deals="false" show-deal-labels="true" card-width="260" rows-per-page="3" ></mapvx-website>

Pin the exact version you tested (here 1.6.1) in the URLs. To react to what visitors do, see Events; to load the data on your server, see SSR and initial data.

Last updated on