Skip to navigation

Invoices renders the signed-in company’s invoice history: a dated link to each hosted invoice with its amount beside it. Credit notes appear in parentheses. The card loads from the company billing API, so it needs a session on the provider as described in the Drop-in components overview.

Invoices

Usage

import { SchematicProvider } from "@schematichq/schematic-react";
import {
Invoices,
SchematicStyles,
} from "@schematichq/schematic-components/elements";
<SchematicProvider publishableKey={publishableKey} session={session}>
<SchematicStyles />
<Invoices limit={5} />
</SchematicProvider>;

Props

PropDefaultEffect
limit10Rows shown before “See more”. Also sizes the loading skeleton, up to four rows.
collapsibletrueCollapse to limit rows behind “See more”.
showHeadertrueThe “Invoices” heading.
showDate, showAmounttrueThe date and the amount on each row.
headingLevel2The heading’s level, 1 through 6, so the card fits your page’s outline.
queryWhich rows the server returns. { includePending: true } includes unpaid invoices that are not yet due.
classNameAdded to the root alongside schematic-element schematic-card schematic-invoices.
localeBCP 47 tag for date and currency formatting. Falls back to the provider’s locale, then the viewer’s language.
stringsCopy for this card by key. Wins over the provider’s strings and translate.

Each distinct query is its own list with its own paging, and the component keys by value, so an inline object literal is fine.

Each row with a hosted invoice links its date to it and opens it in a new tab; a row without an http or https URL shows the date as plain text. The date is the due date, or the created date when the billing provider set none, formatted in the locale’s long form such as “March 1, 2026”. Every amount carries a tooltip saying whether it was a charge or a credit.

Paging

The card collapses to limit rows and offers “See more”. Once every loaded row is showing and the server holds more, “Load more” appears and fetches the next page. The button disables while a page is on the wire, and a page that fails is reported under the list with the rows already fetched left on screen.

Errors

A failure with nothing to show replaces the card’s content with a short message and a “Try again” button. A 404 reads “Invoices are not available for this account.”, because that status means the account is not enabled for the company billing endpoints. Every other failure, and a 404 under rows already loaded, reads “There was a problem retrieving your invoices.” A refetch that fails with rows on screen is reported under them rather than replacing them.

Neither message is the error’s own text. In development the component logs the underlying error to the console beside the copy, so a missing provider or a refused request is diagnosable from the page. In production, read the error from useInvoices if you need it.

Strings

Every word the card renders resolves through strings on the component, then on the provider, then the provider’s translate, then English. See Localization for how the chain works. These are the keys:

KeyDefault
invoicesHeaderInvoices
invoicesLoadingLoading invoices, read by assistive technology while the skeleton shows
invoicesEmptyNo invoices created yet
invoicesErrorThere was a problem retrieving your invoices.
invoicesUnavailableInvoices are not available for this account.
invoicesSeeMore, invoicesSeeLess, invoicesLoadMoreSee more, See less, Load more
invoicesChargeTooltip, invoicesCreditTooltipThe tooltip on a charge’s amount and on a credit note’s
invoicesUndatedView invoice, the link text for an invoice with no usable date
retryTry again
<Invoices strings={{ invoicesHeader: "Receipts", invoicesEmpty: "Nothing billed yet" }} />

Markup

This is what the component renders, for a host styling it without SchematicStyles. The root’s class list is the same in every state, and data-state tells them apart. Styling and theming lists the shared classes.

<div class="schematic-element schematic-card schematic-invoices" data-state="ready">
<div class="schematic-header">
<h2 class="schematic-header__title" id="…">Invoices</h2>
</div>
<!-- with no rows, in place of the list -->
<p class="schematic-muted schematic-invoices__empty">No invoices created yet</p>
<ul class="schematic-invoices__list" aria-labelledby="…">
<li class="schematic-invoices__row">
<span class="schematic-invoices__date">
<!-- .schematic-invoices__date-text when the invoice has no URL -->
<a class="schematic-invoices__link" href="…" target="_blank" rel="noreferrer">
March 1, 2026
</a>
</span>
<!-- title carries the charge or credit tooltip; a credit note adds
.schematic-invoices__credit and renders in parentheses -->
<span class="schematic-invoices__amount" title="Charge — you were billed this amount">$68.00</span>
</li>
</ul>
<div class="schematic-invoices__actions">
<button class="schematic-link-button schematic-invoices__see-more" aria-expanded="false">
<i class="schematic-icon schematic-icon--chevron-down schematic-chevron schematic-invoices__chevron" aria-hidden="true"></i>
<span class="schematic-link-button__label">See more</span>
</button>
<!-- once every loaded row is showing and the server has more -->
<button class="schematic-link-button schematic-invoices__load-more">Load more</button>
</div>
<!-- a failure with rows still on screen -->
<p class="schematic-status-note schematic-error" role="alert">…</p>
</div>

While loading, the root carries data-state="pending" and aria-busy="true". It holds a visually hidden schematic-hidden span with the loading label and a schematic-skeleton shaped like the loaded card: a schematic-skeleton__heading bar when showHeader is set, and one schematic-skeleton__cell per rendered column on each schematic-skeleton__row. Each cell names its column on data-column, either date or amount. Rows match limit, capped at four.

On a failure with nothing to show, the root carries data-state="error" and holds a schematic-status row with the message in schematic-status__message and a “Try again” button in schematic-status__retry.

Build it yourself

The same data is one hook away. useInvoices returns the page and loadMore, and deriveInvoiceList turns it into rows with formatted text beside every raw value.