Building a nav from links
Building a nav from links
The builder runs as one five-step flow: website URL, buckets, link selection, preset, and command. The same builder also handles editing (chapter 4.9).
The flow, in order
The five steps
- Website URL — enter a site and press Detect Links, or skip straight to manual entry.
- Buckets — pick which set of links to build. Only Socials is currently selectable. Skipped entirely when no buckets are configured.
- Link selection — check which links to include, edit any URL, or add one by hand. Six at most.
- Preset — pick a preset and a colour, and check the exact finished message in a live preview.
- Command — set the trigger the nav fires on, and save.
Confirm on Link selection moves to Preset; Confirm on Preset freezes the rendered message and moves to Command. Command's primary button is what actually saves the nav.
Where you build one
Entry points into the builder
| Surface | Starts a new nav | Opens an existing nav |
|---|---|---|
| Dashboard → Beta tab → Hyperlink Nav panel | Yes | No |
| Commands tab (the bot's command table) | No — no "new nav" control exists there | Yes — click the nav's response cell |
The beta tab's panel is titled Hyperlink Nav, subtitled "Build a navigation command from your links — pick a preset, customize the look, and save it as a command." It lists nothing else — no existing navs, no history — and its one control is a button reading Add Hyperlink Command (a + icon, then "Add," then "Hyperlink Command"), which opens the builder on Step 1.
In the Commands tab, the table's own Add button opens the plain command modal, not the nav builder. The only way into the builder from the Commands tab is opening an existing nav for editing (chapter 4.9).
Step 1 — Website URL
Heading Build From Links, subheading "Enter your website and we'll find your links." One field, labelled Website URL, placeholder yourproject.com. It auto-focuses only on screens 1024px and wider, and pressing Enter in it is the same as pressing Detect Links.
Buttons
| Button | Behaviour |
|---|---|
| Detect Links (primary) | Starts detection. Reads "Scanning…" while busy. Disabled while busy, or while the field is empty. |
| Cancel (secondary) | Closes the builder. |
| "Skip, I'll enter links myself" (text link, under the buttons) | Bypasses detection entirely — see Manual entry, below. |
Client-side validation, before any request is sent
| Condition | Message |
|---|---|
| The field is empty | "Enter your website URL" |
| The text doesn't parse as a URL | "<what you typed>" is not a link |
Detecting links
Detect Links sends the typed URL to the dashboard's detection endpoint, which crawls the site and groups whatever it finds by platform. It requires being logged in — the only other gate is the rate limit below.
Rate limit
| Setting | Value |
|---|---|
| Limit | 12 scans per 60 seconds, per IP address. |
| Exemption | None. The limit is the same for every account, including paying accounts. |
| Over the limit | The request fails with HTTP 429, shown in the builder as "Too many scans — wait a minute." |
| Any other failure | Shows the server's own error message, or "Could not scan that site" if none was given. |
The crawler reads a site's robots.txt file, but only as a source of more URLs — never as an exclusion list. Sitemap: lines are followed, and both Allow: and Disallow: paths are added to the same queue of pages the crawler visits. A path a site's robots.txt marks Disallow: is fetched and parsed exactly like any other discovered page.
On success, the builder moves to the bucket step if any buckets are configured — currently six are — otherwise straight to link selection.
Step 2 — What Are You Building? (buckets)
Heading What Are You Building?. This step appears once detection has produced a result — including an empty one from Skip — and only when at least one bucket is configured.
Subheading "Found {N} links on {host} — pick a set and we'll pre-select the matches" after a scan that found something; "Pick a set, then add your links" after Skip. {N} is the total candidate count found across every platform; {host} is the site's post-redirect host.
One card per bucket, showing its icon, its label, a note line (the first few matched platform labels, or a fallback note when nothing matched), and a count pill.
The six configured buckets
| Bucket | Count pill | Selectable |
|---|---|---|
| Socials | {n} found, or 0 | Yes |
| Exchanges | Coming soon | No |
| Charts | Coming soon | No |
| On-ramps / DEX | Coming soon | No |
| Articles / Blogs | Coming soon | No |
| Documentation | Coming soon | No |
Picking Socials filters the link list to that bucket and advances to Step 3. The only button on this step is Back.
Step 3 — Link selection
The heading is the bucket's label when a bucket was picked (currently always Socials); otherwise Auto-Detected Links if detection found anything, or Your Links if it didn't.
Subheading, by situation
| Situation | Subheading |
|---|---|
| A bucket is active and matched something | "Found {n} for socials on {host} — check yours, edit any URL, or add your own" |
| A bucket is active and matched nothing | "Nothing for socials on {host} — add your links below, or open everything we found" |
| No bucket; detection found links | "Found {n} on {host} — check yours, edit any URL, or add your own" |
| No bucket; detection found nothing | "Nothing detected on {host} — enter your links below" |
| No detection has happened yet this session | "Enter your links below — one per platform" |
Steps 1 and 2 of the normal build-from-links flow always run first, so it does not occur there.
Each row is an edge-emoji preview, an editable URL field, and a checkbox. A caption with the platform's label prints above the first row of each platform run. Editing a row's URL re-classifies its platform live, unless the row is one of the fixed slots — the manual-entry rows (below) and the Website row when a bucket is active never change platform, whatever URL is typed into them. Typing into an empty row checks it automatically; clearing the field unchecks it.
Extra matches fold behind a reveal link: with a bucket active, everything outside it folds, always; without one, unmatched rows fold once there are more than four of them.
A trailing row, "Add another link," takes a free-form URL (placeholder https://…) with a + button; its icon previews the platform the typed URL would classify as.
Messages at this step
| Trigger | Message |
|---|---|
| A checkbox is toggled on at the cap | the checkbox itself is disabled instead |
| Pressing + at the cap | "Select up to 6 links. Uncheck one to add another." |
| Typed text that doesn't parse as a URL | "<text>" is not a link |
| Confirm with nothing checked | "Check at least one link" |
| Confirm with more than the cap checked | "Pick at most 6 links ({n} checked)" |
A status line, " of 6 selected," shows whenever there is no error to show instead. Buttons: Confirm (disabled with nothing selected) and Back. Enter in any URL field also confirms.
Step 4 — Preset
Heading Hyperlink Nav, no icon, a scrollable card.
- A Preset dropdown — one option per configured preset, showing its dropdown label.
- A Color dropdown — Main first, then every colour the selected preset actually defines a variant for, each swatched in its own colour.
- A live Telegram preview of the exact finished message, rendered between the dropdowns and the buttons.
- A Black logos / White logos toggle pair, shown only when the selected colour branch has a white-logo variant.
- An "Edit links ({n})" text link back to Step 3.
Buttons: Confirm (disabled with zero links selected) freezes the rendered HTML and settings and advances to Step 5; Back returns to Step 3. What a preset and a colour actually change is covered in chapter 4.9.
Step 5 — Command
Heading Command, subheading "What command would you like to trigger this in chats?"
One field, labelled Command, prefixed with a literal /, placeholder socials, capped at 32 characters. Typed text is sanitised live — leading slashes are stripped and anything outside letters, digits and underscores is removed.
Buttons
| Button | Behaviour |
|---|---|
| Primary | "Add Command" for a new nav, "Save Changes" when editing; reads "Saving…" while busy. Disabled while busy or while the field is empty. |
| Back (secondary) | Returns to Step 4. |
Validation on submit: the trigger is lower-cased and must match 1–32 lowercase letters, digits or underscores, else "Use 1–32 letters, numbers, or underscores." Enter in the field submits, the same as the primary button. Submitting here is what actually saves the nav — see chapter 4.9.
Back walks the steps in reverse — Command → Preset → Link selection → Buckets → Website URL — skipping the bucket hop when no bucket step was shown.
Manual entry — skipping detection
"Skip, I'll enter links myself," on Step 1, bypasses detection entirely: it aborts any scan already in flight, loads the preset pool without fetching the site at all, and builds an empty detection record from whatever was typed in the URL field (or a blank one if nothing was typed). On failure it shows "Could not load link options."
Skip still goes through the bucket step when buckets are configured — the "Coming soon" gate applies there too — before landing on Step 3.
With nothing detected, Step 3 shows one empty row per configured platform, in the configured order, all unchecked — effectively a manual per-platform form. Every one of these rows is fixed: editing its URL never changes its platform.
The manual-entry rows, currently, in order
| # | Platform | Label |
|---|---|---|
| 1 | x | Twitter (X) |
| 2 | telegram | Telegram |
| 3 | website | Website |
| 4 | youtube | YouTube |
| 5 | ||
| 6 | tiktok | TikTok |
| 7 | dexscreener | Dexscreener |
| 8 | coingecko | CoinGecko |
| 9 | cmc | CoinMarketCap |
| 10 | github | github |
| 11 | binance | binance |
An empty website field is accepted through to save — the resulting nav simply carries no scanned site.
What a hyperlink nav is
A hyperlink nav is a single Telegram text message built from premium (custom) emoji and centred hyperlinks. It carries no special message type — it is…
Presets, buckets and caps
A preset supplies a nav's banner, dividers, edge emoji and colour variants. Three are currently configured. Separate caps limit how many links a nav can…