store-locator.js), which shows the locations of a single
organization; the other two get a section each for what differs.
- The brand product locator (
brand-locator.js) shows which nearby stores carry a given brand’s products. It behaves identically to the store locator on every question here, calling a different set of Closient endpoints. - The product information panel
(
pip-panel.js) renders compliance data for one GTIN on a retailer’s product detail page. It is materially narrower than the two locators: one request, one host, no location, no visitor input, no cookies.
This page describes system behaviour, not legal terms. Closient’s own privacy
policy and terms are published separately at
closient.com and govern our side of the
relationship.
Requests the widget makes
Everything the widget loads or calls, in the order a visitor triggers it.
Closient is the only party that receives visitor data, with one exception:
map tiles — and that exception is one you can switch off, with
data-map="off".
Tile images are fetched by the visitor’s browser directly from
OpenStreetMap, so while the map is on, the
OpenStreetMap Foundation sees the visitor’s IP address and which map area they
are looking at. Under their
tile usage policy they
also publish anonymised, aggregated usage data that includes which websites use
the service. No other third party is contacted — the map library is bundled
into the widget script, and both location lookups run on Closient’s servers
rather than in the visitor’s browser.
Why Closient does not proxy tiles for you. We proxy the geocoder, so the
obvious question is why not the map as well. The OpenStreetMap tile usage
policy forbids it: §3.4 rules out “tunnel[ling] all clients behind a single,
anonymous identity”, which is precisely the property that would make a proxy
private, and §5 says the Foundation “generally do[es] not recommend” a caching
proxy in front of their tiles. A proxy that satisfied the policy would still
disclose your visitors; one that protected them would breach it. The honest
options are therefore a tile source you hold your own agreement with, or no
map — both below.
How location is determined
The widget tries three sources, in order, and stops at the first that works.1
Browser geolocation
The browser’s own location prompt. Precise, and shown to the visitor as an
explicit permission request by their browser. Closient receives the
resulting coordinates but never the underlying device signals.
2
Network-level approximation
If the visitor denies or ignores the prompt, the widget asks Closient for
the approximate location our edge network already derives from the
connection. This is city-level at best and often less. It happens
server-side: no third-party geolocation service is involved, and the
visitor’s IP address is not stored or returned.
3
Address search
If neither is available, the visitor types a place. The text is sent to
Closient, which resolves it to coordinates server-side and caches the
result. The visitor’s browser never contacts the geocoding provider, so
the provider sees Closient’s servers rather than your visitors.
Cookies and storage
The widget sets no cookies and writes nothing tolocalStorage,
sessionStorage, or IndexedDB. It holds state in memory for the life of
the page only. Analytics events are attributed to your publishable key, not
to a visitor identifier — there is no cross-site or cross-session tracking,
and consequently nothing for a cookie banner to gate.
Coordinates from the browser’s location prompt are used for the search that
requested them and are not persisted.
What Closient retains
Reducing third-party exposure to zero
If your privacy posture rules out any third-party request, the map is the only thing standing in the way — anddata-map="off" removes it:
Keeping a map, on your own terms
If you already hold an agreement with a tile provider — MapTiler, Stadia Maps, your own tile server — point the widget at it withdata-tile-url and give the
provider’s required attribution in data-tile-attribution:
data-tile-attribution is required whenever data-tile-url is set: rather than
guess an attribution or quietly fall back to OpenStreetMap — the host you were
configuring your way off — the widget switches the map off and logs the reason
to the browser console. Both attributes are script-embed only; the iframe embed
accepts map=off but not a custom tile URL.
Configuration reference
The embed accepts these attributes. Onlydata-map and data-tile-url change
what data is processed, and both only by removing or redirecting the map tile
request.
Brand product locator
brand-locator.js answers a different question — which shops near me stock
this brand — and is embedded by the brand, or by a merchant on their own
storefront, rather than by the organization that owns the stores:
data-map="off" and data-tile-url. Three
things differ.
It carries no API key. The brand id in the embed is the whole identity, and
it is already public — the same id appears in Closient’s own public brand
pages. The endpoints it calls take no authentication at all, so there is no
credential to leak from a page you do not control.
It calls the brand endpoints, not the store-locator ones. Same origin, same
processor, different paths:
It asks nothing of the visitor when there is nothing to show. The catalog
call above runs first, before the browser’s location prompt, precisely so the
widget can find out whether the brand is stocked anywhere at all. If it is not,
the widget renders nothing and never requests a location — a permission prompt
whose answer could not be used is not one worth showing.
Configuration reference
Identical to the table above, except thatdata-api-key is replaced by:
Product information panel
pip-panel.js is the third embed and the only one that is not a locator. It
renders recall status, allergens, certifications and the printed ingredient
label for a single GTIN, and it is embedded by a retailer or marketplace on
their own product detail pages:
The product image is worth calling out because it is the one request that does
not go to
www.closient.com. Closient serves product media from a separate
storage domain, so a visitor’s browser contacts that host too. It is still
Closient — not a third party, not an image host the brand chose — but it is a
second origin, which matters if you are writing a Content Security Policy. The
exact hostname is whatever comes back in the image_url field of the response
above; read it once for a product you carry and put that origin in your
img-src.
Beyond those three, nothing. No map, so no tiles and no data-map to switch
off; no location, so no geolocation prompt, no IP geolocation call and no
geocoder; no visitor input of any kind, so nothing a visitor types is ever
transmitted.
It sends no cookies and sets none. The fetch is made with
credentials: 'omit', and the endpoint behind it is anonymous by construction
— it reads no session, and a response that varied by visitor could not be
cached the way this one is. Closient cannot recognise a visitor across your
pages, or between your site and anyone else’s.
It fires no analytics from the browser. Unlike the two locators, the panel
posts no widget-event. Closient counts panel renders server-side from the
request it already receives, in aggregate and tagged distinctly from real QR
scans, so nothing about an individual visitor is recorded and a brand’s scan
numbers are not inflated by embed traffic.
It stores nothing on the device. No cookie, no localStorage, no
sessionStorage, no IndexedDB.