Skip to content
Kontosjekker
Esc
↑↓navigate↵open⌘Jpreview
On this page

React component

An account number input with formatting, validation and bank detection.

@kontosjekker/react ships an account input that formats as the user types, shows the owning bank’s logo and name, and reports MOD-11 validity. It is unstyled beyond layout — you pass class names, the way a shadcn/ui component works.

pnpm add @kontosjekker/react

Against the API

import { BankAccountInput, remoteSource } from "@kontosjekker/react"
import { useMemo, useState } from "react"

export function PayoutForm() {
  const [account, setAccount] = useState("")
  // Memoise: the source caches lookups per four digit prefix.
  const source = useMemo(
    () => remoteSource({ baseUrl: "https://api.kontosjekker.asamsig.com" }),
    [],
  )

  return (
    <BankAccountInput
      value={account}
      onChange={setAccount}
      source={source}
      classNames={{ input: "h-9 w-full rounded-md border px-3" }}
    />
  )
}

Offline, with the list bundled

No network at all — the register is compiled into your bundle. Good for forms that must work offline, at the cost of shipping ~120 kB and going stale between releases.

import { banks } from "@kontosjekker/data"
import { BankAccountInput, localSource } from "@kontosjekker/react"

const source = localSource({ banks, logoBaseUrl: "/bank-logos" })

Copy the logo files you need from @kontosjekker/data/logos into your public directory; logoBaseUrl is where you serve them from.

Just the logic

import { useBankAccount } from "@kontosjekker/react"

const { formatted, validation, bank, logoUrl, isLoadingBank } = useBankAccount({
  value,
  source,
})

validation stays null until 11 digits have been entered, so the user is not told they are wrong while still typing. Pass validateWhileTyping to change that.

Validation without React

@kontosjekker/core is dependency-free and runs anywhere:

import { validateBban, bbanToIban } from "@kontosjekker/core"

validateBban("8601 11 17947").valid // true
bbanToIban("86011117947") // "NO9386011117947"

Was this page helpful?