Skip to main content
Market page (hosted market kit). Nexus hosts a ready-made, configurable Cardano market page that you drop into your own site with two tags and one element. It renders a token screener with sparklines, a trending strip, market stats, a token page with a candlestick chart, recent trades, an order book, per-DEX markets and top traders, an ADA page and a live swaps feed. It also embeds the swap widget, so visitors can trade without leaving your page. The page is a custom element, <gero-market>, that authenticates with the same public partner key as the <gero-swap> widget. You describe the page in a JSON config, either by hand or in the Nexus console, which has a visual builder with a live preview and gives you the finished index.html.
The market data on the page is read through your key, so the Market Data add-on must be active on the plan of the account that owns the key, on its own or through the Data or Complete bundle. Without it the page shows a notice that market data is not available on this key (HTTP 402). Letting visitors build and submit a swap also needs the Transaction Builder add-on, as it does for the standalone widget.
Hosted at: https://nexus.gerowallet.io/market-kit/v1/ · Auth: a public partner key in the partner-key attribute (sent as X-Api-Key)

Who it is for

Anyone who wants a market data page on their own domain without building one: a wallet, a community or project site, a launchpad, a dashboard. You keep your own domain, branding, navigation and footer. Nexus keeps the page working: fixes and new features reach your visitors without a change on your side (see Versioning). If you want to build a page from scratch, or read this data from a server, use the Market Data endpoints with an ordinary API key instead. The market page is a front end over those same reads.

Before you start

Partner keys are public by design: anyone can read the key out of your page source. The registered origins are what stops it being used from any other site. See Which key to use.

Build one in the console

The console has a builder for the page at /dashboard/market-page. It is switched on per account; if you do not see it, you can still write the config by hand with the reference below, or start from one of the recipes.
1

Choose a key

Pick the partner key the page will use. The console saves the page per key, so reopening the builder restores it.
2

Design the page

Work through the builder’s tabs, listed below. A live preview updates as you change settings.
3

Copy or download the page

The builder generates a complete index.html containing the two tags, the element and your config. Copy it or download it.
4

Host it

Upload the file to any static host, as described next.
What each tab of the builder holds:

Host the page

The generated index.html is a plain static page. Put it on any static host (your own server, an object store with a CDN, a pages service) or paste the two tags and the element into a page you already have.
  • The page must be served from an origin you registered on the key. A different domain, a preview URL, http instead of https, or a different port is a different origin and gets a 403.
  • Opening the file from disk (file://) does not work, because the browser does not send a usable origin.
  • Nothing else is required: no build step and no server of your own. The kit loads the swap widget bundle itself, from the same Nexus host.
To embed the market page inside a larger page, put the element where you want it and set routing to "none". The kit then never touches your page’s URL and reports navigation through an event instead (see Routes and Events).

The element

  • A JavaScript property wins over its attribute.
  • Config sources, highest priority first: the config property, the config attribute, then a <script type="application/json"> child, which is read once when the element connects. With no config at all, the default page renders.
  • Assigning a new object, or changing the attribute, re-renders in place. Mutating the same object does nothing.
  • Invalid JSON, or JSON that is not an object, renders an inline error and fires gero-market:error. Fields that are wrong inside a valid object are repaired to their defaults and listed in one console.warn. The element never throws.
To mount a page from script instead of markup:

Config reference

The config is a JSON document, schema version 1. The element accepts a partial config and fills in the defaults below for anything you leave out. A config saved from the console is checked strictly instead: the original sections are present (header and chart may be left out, and so may every field added after the first release), unknown keys are refused at every level, enums are exact, and the whole document is at most 65,536 bytes. Names are case-sensitive.

Top level

branding

Settings for the page header. The header belongs to the chrome block, so they have no effect when that block is left out.

layout

The three presets arrange the token page differently. terminal puts the chart beside a rail with trades and the order book, with markets and top traders below. dashboard shows the header and the chart at full width, then the other cards in a two-column grid. minimal is a single column of whatever is enabled. Block ids: A block you leave out of blocks does not render.

theme

data

Column ids: name, price, priceChange1h, priceChange24h, priceChange7d, priceChange30d, spark, volume24h, volume7d, txnCount24h, makerCount24h, tvl, marketCap, totalSupply, risk. Tab ids: all, trending, gainers, losers, volume, new, watchlist. Currency codes: ADA, USD, EUR, GBP, JPY, BTC. allow, deny and featured each take at most 500 entries. An entry is a lowercase hex asset id (the policy id followed by the asset name) or a bare 56-character policy id, which covers every asset under that policy. Tickers are not accepted, because any token can claim any ticker.

chart

The chart on the token page.

swap

A complete example

Recipes

Three configs for common pages. Each is a partial config you can paste into the config attribute: the page fills in the defaults for everything left out. In the console, the same settings are in the tabs listed under Build one in the console.

A project’s own token page

The page opens on your token, pins it to the top of the screener, and keeps the screener to two tabs for visitors who go looking for other tokens. Replace both asset ids with your token’s policy id followed by its asset name in hex.

A clean screener only

A single home page: the token table with the trending strip and market stats, capped at 100 rows and offering two currencies. No token, ADA or live pages, and no sync indicator.

Dark terminal with indicators

The terminal layout in its dark preset, with a tall chart that starts with a moving average and Bollinger bands on hourly candles, and every screener tab.

Theming

The page is themed with CSS variables on the <gero-market> element. Set them from your own stylesheet, or on any ancestor, and they override the config’s colors and fonts:
The presets are starting points for the colors: The kit’s stylesheet is scoped to the <gero-market> element and its popovers, and never restyles the rest of your page. A plain class selector in your own CSS can override any of it. The swap panel follows the page’s theme unless swap.theme says otherwise.

Routes

With routing set to "hash" (the default) the page navigates with the URL fragment, so every view has a link you can share and the browser’s back button works. Links in your branding.nav can point at these fragments, for example { "label": "Live", "href": "#/live" }. Opening view. The page opens on home unless the config says otherwise. Set layout.startView to "token", "ada" or "live" to open on another view when there is no route to open: no fragment under hash routing, no route attribute under none. With "token", layout.startAssetId names the token, and without it the page opens the token with the highest volume. A link that carries its own route, such as #/live, opens that view instead, and a later navigation to #/ still shows home. If the chosen view’s block is turned off, or no token can be shown, the page opens on home. With routing set to "none", the page does not read or write your URL. Start it on a view with the route attribute (for example route="/live"), move it with the element’s navigate(path) method, and listen for gero-market:navigate to keep your own URL in step.

Events

The element dispatches these events. All of them bubble and cross shadow roots, so you can listen on the element or any ancestor.

Requests and quota

Every request a visitor’s browser makes counts against the key owner’s monthly quota and per-second rate limit, exactly like a call made from a server. A page with many visitors is many callers on one key, so the refresh cadence is worth a thought. See Rate limits. What the page does by default:
  • It refreshes prices and the RSI indicator every 60 seconds (two requests per refresh), the sync status once a minute (or as often as pollMs when that is slower), and the sparklines and currency rates every 5 minutes. Set header.syncStatus to false and the sync status request is not made.
  • It pauses when the browser tab is hidden and resumes when the visitor comes back.
  • Live swap flashes are off by default. A token page loads its chart, trades, order book, markets and top traders when it opens and does not poll them.
  • When a request is answered 429, it waits for the Retry-After the response carries before trying again, and shows a notice. After a 402 it stops polling until the visitor presses the retry button.
Approximate steady-state cost of one open, visible tab on the home page: At the defaults that is about 120 requests for the token list (60 refreshes of two requests each), 60 for the sync status, 12 for currency rates and 12 for sparklines. These are estimates, and opening a page or a token adds a handful of requests. Multiply by your concurrent visitors to size the quota. The data settings that move the number most are: If you read these endpoints with your own code from a registered origin, a browser can read these response headers, which the partner gateway exposes to your page: Retry-After, X-Candles-Truncated (a candles range was cut to the per-response limit), X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset and X-Request-Id. Quote X-Request-Id when you contact support.

What the key can read

The page uses only read-only endpoints that a partner key may call from a registered origin: /api/prices/**, /api/market/**, /api/dex/swaps/**, /api/dex/pools/token/**, /api/dex/orderbook/**, /api/dex/tokens/{policyId}/{assetName}/top-traders, /api/sync/status and the swap aggregator for the swap panel. The full list is under Which key to use. Pool lists, orders by token or DEX, quotes, NFT, leaderboard, wallet and blueprint routes stay off a partner key. Two of the price endpoints exist for the page and are described in Market Data: sparkline series and currency rates.

Troubleshooting

The key was refused. The usual cause is that the origin serving the page is not registered on the key. The origin is the scheme, host and port, so https://www.example.com, https://example.com and http://example.com are three different origins. Register the exact one in the Nexus dashboard. If you set base-url to a proxy of your own, the proxy must forward the browser’s Origin header unchanged.To see what is wrong, call the self-check with the same key and origin. It names an unregistered or missing origin, an out-of-date endpoint allowlist (SCOPE_INCOMPLETE), and a revoked or expired key. It reports the Transaction Builder add-on, not Market Data, so a missing Market Data add-on shows up as a 402 instead.
The account that owns the key does not have the Market Data add-on. The response body names it: "addon": "marketData". Activate Market Data, or a bundle that includes it, on the owner’s plan; see Add-ons. The Starter plan covers the core API only, so it cannot carry the add-on. The page stops polling after a 402; once the add-on is active, reload the page or press the retry button.
Either the owner’s monthly quota is used up or the per-second rate limit was exceeded by the combined traffic on the key. The page waits for the Retry-After it is given and tries again. To use less quota, raise data.pollMs, leave data.swapFlashMs at null, and turn data.sparklines and header.syncStatus off if you do not need them; see Requests and quota. To raise the limits, change the plan; see Rate limits.
Check the browser console. Invalid JSON, or JSON that is not an object, shows an inline error and fires gero-market:error with INVALID_CONFIG. A field that is wrong inside a valid object is replaced by its default, and every repair is listed in a single console.warn. Common causes are a misspelled key (unknown keys are ignored), an enum in the wrong case, a number outside its range, or a color that is not #rgb or #rrggbb.
The panel is missing when swap.placement is "off". If it opens but cannot build or submit a swap, check that the key’s owner has the Transaction Builder add-on; see DEX Aggregator.
The preview is the kit’s own preview.html, shown in a frame inside the console. Reload the builder and try again. If the frame stays blank, disable browser extensions that block frames or scripts for nexus.gerowallet.io and check the browser console for blocked requests. If the preview shows a notice about market data instead of the page, that is the 402 or 403 above, not a loading problem.
A 5xx from the data service shows “delayed” and keeps the last data it received while it retries with a growing delay. One block failing does not take down the rest of the page: it shows an inline error and fires gero-market:error with RENDER_ERROR. Quote the reference shown on the page, or the requestId in the event, when you contact support.

Versioning

The kit lives at https://nexus.gerowallet.io/market-kit/v1/ and is replaced in place on every deploy. You keep one snippet and get fixes and new features without touching your page. Two consequences:
  • Do not pin Subresource Integrity (integrity="sha384-...") on the kit’s files. The hash changes with every deploy, so a pinned page would stop loading after the next one. This differs from the swap widget bundle, which is version-pinned and has published hashes.
  • The files are served so that browsers revalidate them on every load, which is cheap when nothing changed.
Changes that add something stay in v1/. A breaking change, such as a removed or renamed config field, ships under a new path, v2/, with its own schemaVersion; you opt in by changing the snippet. window.GeroMarket.version and the version in the gero-market:ready event tell you which build a page is running.

DEX Aggregator

The partner key, registered origins, the self-check and the swap endpoints behind the swap panel.

Market Data

The endpoints the page reads, for when you want the data without the page.