Skip to main contentSkip to navigation

The screen an address gets when it named nothing — kept apart from a read that returned nothing.

An address can fail to name anything. A position id with no position behind it, a removal that never happened, a chain that was never migrated: the route matched the shape of the path, and the subject it was asked for does not exist. Nowhere is what that screen says.

Loading...

The failure it makes visible

Nowhere came out of the Lux exchange, where a screen is reached by a link that carries what to read — a position, a removal, a migration — and answers a family of paths rather than a single one. A path in the family that named nothing matched no page at all and left an empty <main>: a heading, a footer, and nothing between them. That reads as a venue with nothing in it rather than as a link that does not resolve.

A blank page is also the failure a sweep does not catch. An empty document reports the same width as a full one and raises no layout complaint, so every measurement passes on it. Saying so on screen is what turns it back into something a person and a test both notice.

It sits before the reading, not inside it

Table and Tally take a reading rather than a value, because a component that has flattened "there is nothing" and "we could not ask" into an empty list cannot tell them apart afterwards.

type Rows<R> =
  | { at: 'reading' }
  | { at: 'read'; rows: R[] }
  | { at: 'failed'; why: string }

Nowhere is neither branch. No read was attempted, because there was nothing to read about, and its note says exactly that: Nothing was read, so nothing here is a statement about a market.

That separates it from what a table says over the same blank space. Table writes those through Answer, which is exported for the case where a screen fails before there is a table to fail in:

ComponentThe statement it makes
NowhereThe address named no subject, so nothing was asked.
AnswerWe read, and the answer was nothing.
Answer with alertWe could not read. The reason is on screen, in the colour of a refusal.

Nowhere is the page. Answer is a card in the region that would have held the rows.

Installation

npm install @luxfi/ui @hanzo/gui @hanzo/ui @hanzo/design @tanstack/react-query
import '@luxfi/ui/tokens.css'
import '@hanzo/design/styles.css'
import { AppProvider } from '@luxfi/ui/provider'
import { Nowhere } from '@luxfi/ui/read'

AppProvider goes once at the root of the app and mounts the gui engine and a query client. The two sheets are where the names resolve: colour from @luxfi/ui/tokens.css, spacing, elevation and measure from @hanzo/design.

Usage

import { Nowhere } from '@luxfi/ui/read'
<Nowhere what="market" />

The route decides that the address named nothing. Nowhere states it.

export default function Market({ params }: { params: { id: string } }) {
  const market = markets.find((m) => m.id === params.id)
  if (!market) return <Nowhere what="market" />
  return <MarketDetail market={market} />
}

Anything offered to the reader — a correction, a way back — arrives as children, and lands in the note beside the sentence.

<Nowhere what="position">
  <a href="/positions">Open the positions list.</a>
</Nowhere>

Props

PropTypeRequired
whatstringyes
childrenReactNodeno

what is a singular noun in the reader's own words, and it is written into both sentences — This link names no {what} as the heading, …a statement about a {what} in the note. So it has to read after no and after a: market, position, migration, not markets and not Market ID.

The heading renders as <h1>, because Nowhere replaces the page rather than sitting in it. Both lines take their colour from paint — --color-text-primary for the heading, --color-text-secondary for the note — and the note is held to a 560-pixel measure, past which a line of this type stops being readable.

What it does not do

Nowhere is markup. It does not fetch, retry, redirect, or decide that the address named nothing; the route does that and renders this in place of the page. It sets no HTTP status; that belongs to whatever resolved the address, and a surface that owes a 404 has to say so there. It carries no illustration and no action of its own. The article in the note is fixed at a, which reads wrong in front of a vowel, so order wants rewording rather than passing straight through. And it says nothing about a read that happened: a query that came back empty, and one that came back refused, are Table's empty and Rows.failed, and drawing either of them as this link names nothing would be the same substitution in the other direction.