Traceroute
A traceroute as a hop table and a dotted map; the packet waits at each hop for its share of the round-trip time, so slow hops are slow to watch.
Your data
Pass your trace as hops. Without it the component shows an invented 11-hop demo trace from a home router through Frankfurt, Marseille and Mumbai to Singapore, with documentation-range addresses. See Your data.
Playground
Change a prop and the component re-renders. Props marked remounts set an initial value, so the component starts over.
<GeoTraceroute
defaultPlaying
speed={1}
jumpMs={40}
probes={3}
target="app.example.com"
/>Installation
pnpm dlx shadcn@latest add @lumesec/geo-tracerouteFirst timeRegister the @lumesec registry once, or install by URL+
Adds @lumesec to your components.json:
pnpm dlx shadcn@latest registry add @lumesec=https://elements.lumesec.ai/r/{name}.jsonOr skip the setup and install by URL:
npx shadcn@latest add https://elements.lumesec.ai/r/geo-traceroute.jsonUsage
"use client";
import * as React from "react";
import { GeoTraceroute, type TraceHop } from "@/components/lumesec/geo-traceroute";
const hops: TraceHop[] = [
{ address: "192.168.1.1", name: "router.home.arpa", rtt: [0.6, 0.5, 0.7] },
{ address: "203.0.113.14", location: "Frankfurt", lat: 50.11, lon: 8.68, rtt: [8.4, 8.1, 9.0] },
{ address: "*", rtt: [] },
{ address: "192.0.2.33", location: "Mumbai", lat: 19.08, lon: 72.88, rtt: [110.4, 109.8, 111.2] },
{ address: "203.0.113.200", name: "app.example.com", location: "Singapore", lat: 1.35, lon: 103.82, rtt: [162.4, 161.9, 163.0] },
];
export function Example() {
const [hop, setHop] = React.useState<number | null>(null);
return <GeoTraceroute target="app.example.com" hops={hops} value={hop} onValueChange={setHop} />;
}Behaviour
A traceroute as a hop table and a map. The path draws hop by hop, and the packet waits at each hop for its share of the round-trip time, so slow hops are slow to watch.
Jumps of more than 40 ms are drawn as dashed long-haul segments with the added time beside them. Hops without a location, or that did not answer, stay in the table only. Selecting a row highlights its segment.
API reference
Props
Also accepts every prop of <div> (React.ComponentProps<"div">), spread onto the root element.
hopsTypereadonly TraceHop[]Default11 demo hopsThe hops in order: { address, name?, location?, lat?, lon?, rtt }. rtt holds one round-trip time in ms per probe; a non-finite entry is a probe that timed out and an empty array a hop that did not answer. Hops with lat and lon are drawn on the map; location is the place name in the table. An empty array shows an empty table and map.
targetTypestringDefaultlast hop's name or addressThe destination shown in the header. The demo shows app.example.com.
valueTypenumber | nullIndex of the selected hop in hops (controlled), or null for none. Use with onValueChange.
defaultValueTypenumber | nullDefaultnullSelected hop when uncontrolled.
onValueChangeType(value: number | null) => voidCalled with the hop index when a row or a map marker is selected, and with null when the selection is cleared.
playingTypebooleanWhether the playback runs (controlled). Use with onPlayingChange. Setting it to true after the end starts over from hop 1.
defaultPlayingTypebooleanDefaulttrueWhether the playback starts by itself when uncontrolled. It begins once the map is first on screen. With false the path is drawn complete.
onPlayingChangeType(playing: boolean) => voidCalled by Pause, Play and Replay, with false when the playback reaches the end, and with false when hops changes.
speedTypenumberDefault1Playback speed. At 1, each millisecond of round-trip time a hop adds is 10 ms of waiting at that hop.
jumpMsTypenumberDefault40Added round-trip time in ms above which a segment is drawn as a dashed long-haul jump with a chip such as +42 ms on it.
probesTypenumberDefault3Probes sent per hop: the number of marks in each row, 1 to 8. A row with more rtt entries shows one mark per entry.
onCompleteType() => voidCalled when the playback reaches the end of the trace.
Ref
ref points at the root HTMLDivElement.
Keyboard
| Keys | Action |
|---|---|
| Tab | Moves to Replay, to Pause or Play, then to the hop rows, which share one tab stop. |
| ArrowUp / ArrowDown | Moves focus to the previous or next hop. |
| Home / End | Moves focus to the first or last hop. |
| Enter / Space | Selects the focused hop, or clears the selection when it is already selected. |
| Escape | Clears the selection. |
Accessibility
- The hops are a native
tablewith a caption (Hops toplus the target) and column headers. - The first cell of each row holds a
buttonwitharia-pressed, named by the hop number, its name or address, where it is and its median round-trip time. The buttons form one roving tab stop. - The probe marks of each row are one image named, for example,
2 of 3 probes answered. - The map has
role="img"and anaria-labelsuch as7 located hops from Frankfurt to Singapore, 162 ms. 2 long-haul jumps.Its markers, labels and chips are hidden from assistive technology; the table carries the same data. - Replay and Pause or Play are native buttons named by their label, which stays in the accessible name when the narrow layout shows only the icon.
- A polite live region announces the end of the playback with the number of hops and the total round-trip time.
- The canvases are
aria-hidden. - Reduced motion: the whole path is drawn at once: there is no packet, dwell ring, ping or spark, the round-trip times show directly, the total and the Pause label swap without rolling, and selection changes apply at once.
Theming
Styled with Tailwind classes on your shadcn theme tokens, so light and dark follow your theme. The accent comes from --lumesec. See Theming.
This component reads --lumesec, --lumesec-shine, --lumesec-glint, --foreground, --muted-foreground, --muted, --card and --border.
Notes
- The playback walks the table row by row. Rows before the first located hop take a short turn each. The packet then appears at the first located hop and, for each segment, travels the curve in 0.35 s plus 0.25 s per 10,000 km, then waits at the next hop for the time that hop adds: its median minus the median of the located hop before it, 10 ms of animation per ms at
speed1, at least 0.18 s. Rows between two located hops take their turns while the packet travels. - While the packet waits it circles the hop once, and the lattice dots around the hop fill clockwise from the direction it arrived in, like a progress ring. The row is highlighted with an accent bar, its probe marks fill in turn and its round-trip time counts up from the hop above. Rows the playback has not reached show a dash.
- At the end two rings of land dots run out from the destination, sparks fly past the map's edge, the header total rolls in and
onCompletefires. - Medians use the answered probes only. A segment's added time never goes below 0, so a hop that answers faster than the hop before it waits the minimum.
- Addresses in private, shared (carrier-grade NAT), loopback or link-local ranges get a Private tag and never reach the map, even with coordinates. Hops without coordinates and hops that did not answer stay in the table only; selecting one dims the map and shows No location.
- Selecting a located hop redraws its incoming segment at full strength and 1.5 times the dot size, dims the other segments to a quarter, and lights the ring of dots around the hop.
- Pause holds the clock, so the packet and the ring stop where they are. Play resumes; Play after the end and Replay start over from hop 1. Changing
hopsstops the playback and shows the new path complete. - The map frames the located hops with a 25 % margin and at least 60° on each axis, on a zoomed Equal Earth projection that fills the box, so it has no curved edges. Segments that cross the 180th meridian continue from the other edge.
- Clicking a hop marker on the map selects that hop, like its row.
- The map's height follows its width. Below 480 px the Name column hides, the RTT unit moves into the column header and the header buttons show only their icons.
- The animation runs only while the map is on screen. Colours follow the theme and are re-read when it changes.
Related
Was this page helpful?