@omnizoek/react
v0.1.5
Published
React hooks for the OmniZoek API — address enrichment, IBAN, vehicle, energy labels and more.
Maintainers
Readme
@omnizoek/react
React hooks for the OmniZoek API — Dutch government data (addresses, IBAN, VAT, geocoding, exchange rates, LEI lookup, vehicle history, energy labels and more) in one clean set of SWR-backed hooks.
Features
- 16 ready-made hooks — one per endpoint, typed in and out
- SWR-powered — automatic caching, deduplication, and background revalidation
- Skip requests cleanly — pass
nullas params to suspend a hook without conditionals enabledflag — opt-out of fetching without unmounting the hookrefetch()— trigger manual revalidation from anywhere- Full TypeScript support — every hook is fully typed via
@omnizoek/sdk - ESM + CJS dual output — works in Next.js, Vite, Remix, and plain CRA
Installation
npm install @omnizoek/react @omnizoek/sdk swr
# or
pnpm add @omnizoek/react @omnizoek/sdk swr
# or
yarn add @omnizoek/react @omnizoek/sdk swr
@omnizoek/sdk,react ≥ 17, andswr ≥ 2are peer dependencies — install them alongside this package.
Quick start
1. Wrap your app with <OmniProvider>
import { OmniProvider } from "@omnizoek/react";
function App() {
return (
<OmniProvider apiKey="omni_test_…">
<MyPage />
</OmniProvider>
);
}2. Use any hook inside the tree
import { useAddressEnrich } from "@omnizoek/react";
function AddressCard({ postcode, houseNumber }) {
const { data, loading, error } = useAddressEnrich(
postcode && houseNumber ? { postcode, houseNumber } : null
);
if (loading) return <p>Laden…</p>;
if (error) return <p>Fout: {error.message}</p>;
if (!data) return null;
return (
<p>
{data.street} {data.house_number}, {data.city}
</p>
);
}Next.js App Router example
// app/layout.tsx
"use client";
import { OmniProvider } from "@omnizoek/react";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="nl">
<body>
<OmniProvider apiKey={process.env.NEXT_PUBLIC_OMNI_API_KEY!}>
{children}
</OmniProvider>
</body>
</html>
);
}API key
Get a free sandbox key instantly — no sign-up required:
curl -X POST https://api.omnizoek.nl/v1/keys/testOr visit omnizoek.nl/playground to try every endpoint live.
Hooks reference
All hooks return an OmniHookResult<T> object.
Pass null (or undefined) as params to skip the request without a conditional hook call.
useAddressEnrich — Geographic enrichment
Enriches a Dutch address via the BAG (postcode + house number → street, city, coordinates, energy label).
import { useAddressEnrich } from "@omnizoek/react";
const { data, loading, error } = useAddressEnrich(
postcode ? { postcode, houseNumber } : null
);
// data.street, data.city, data.lat, data.lon, data.energy_label, …useIbanToBic — IBAN → BIC lookup
Resolves a Dutch or EU IBAN to its BIC/SWIFT code and bank name.
import { useIbanToBic } from "@omnizoek/react";
const { data } = useIbanToBic({ iban: "NL91ABNA0417164300" });
// data.bic, data.bank_name, data.country_codeuseVatVerify — EU VAT verification
Checks a VAT number via the EU VIES service.
import { useVatVerify } from "@omnizoek/react";
const { data } = useVatVerify({ countryCode: "NL", vatNumber: "123456782B01" });
// data.valid, data.company_name, data.address, data.checked_atuseValidateFinance — BSN / IBAN checksum validation
Validates the checksum of a BSN (11-proef) or IBAN (MOD-97).
import { useValidateFinance } from "@omnizoek/react";
const { data } = useValidateFinance({ type: "bsn", number: "123456782" });
// data.valid, data.type, data.algorithm, data.detailuseMinimumWage — Statutory minimum wage (WML)
Returns the applicable gross hourly, daily and monthly minimum wage for a given age and date.
import { useMinimumWage } from "@omnizoek/react";
const { data } = useMinimumWage({ age: 21, date: "2025-01-01" });
// data.hourly_eur, data.daily_eur, data.monthly_eur, data.law_referenceuseHolidaySurcharge — Holiday surcharge calculator
Returns whether a date is a public holiday and the applicable surcharge multiplier for a given industry.
import { useHolidaySurcharge } from "@omnizoek/react";
const { data } = useHolidaySurcharge({ date: "2025-12-25", industry: "retail" });
// data.is_holiday, data.holiday_name, data.surcharge_multiplieruseEnergyLabel — EP-Online energy label
Looks up the registered energy label for a Dutch address.
import { useEnergyLabel } from "@omnizoek/react";
const { data } = useEnergyLabel({ postcode: "1012LG", houseNumber: "1" });
// data.energy_label, data.label_class, data.registered_at, data.valid_untiluseEmissionZone — Zero-emission zone check
Checks whether a vehicle (by licence plate) is allowed in Dutch zero-emission zones.
import { useEmissionZone } from "@omnizoek/react";
const { data } = useEmissionZone({ kenteken: "AB123C" });
// data.ze_compliant, data.fuel_types, data.euro_standard, data.zones_checkeduseTransitDisruptions — NS train disruptions
Returns active and planned train disruptions for a given NS station code.
import { useTransitDisruptions } from "@omnizoek/react";
const { data } = useTransitDisruptions({ stationCode: "ASD" });
// data.disruptions: [{ type, title, cause, start, end }]useGridTrigger — ENTSO-E electricity price trigger
Returns the current day-ahead electricity price and whether it is negative (a grid overload trigger).
import { useGridTrigger } from "@omnizoek/react";
const { data } = useGridTrigger(); // no params required
if (data?.trigger) {
// ⚡ Negative price — good time for high-consumption processes
}
// data.negative_price, data.current_price_eur_mwh, data.period_startuseGeocode — Forward geocoding
Geocode a free-text query to Dutch coordinates via PDOK Locatieserver.
import { useGeocode } from "@omnizoek/react";
const { data } = useGeocode({ q: "Damrak 1, Amsterdam", rows: 5 });
// data.results: [{ display_name, lat, lon, postcode, city, street, … }]useReverseGeocode — Reverse geocoding
Resolve WGS84 coordinates to the nearest Dutch address.
import { useReverseGeocode } from "@omnizoek/react";
const { data } = useReverseGeocode({ lat: 52.3756, lon: 4.8951 });
// data.display_name, data.postcode, data.city, data.street, data.house_numberuseExchangeRates — ECB exchange rates
Returns the latest ECB daily euro foreign exchange reference rates.
import { useExchangeRates } from "@omnizoek/react";
const { data } = useExchangeRates();
// data.base ("EUR"), data.date, data.rates: { USD: 1.08, GBP: 0.85, … }useVatRates — VAT rates
Returns VAT rates for a given EU country, with detailed per-category breakdown for NL.
import { useVatRates } from "@omnizoek/react";
const { data } = useVatRates({ country: "NL" });
// data.standard_rate (21), data.reduced_rates ([9]), data.categories: […]useVehicleHistory — RDW vehicle history
Full vehicle registration record from RDW Open Data (specs, fuel, APK, recalls).
import { useVehicleHistory } from "@omnizoek/react";
const { data } = useVehicleHistory({ kenteken: "AB123C" });
// data.make, data.commercial_name, data.fuel_types, data.apk_expiry_date,
// data.open_recalls, data.open_recall_count, data.euro_standard, …useLeiLookup — GLEIF LEI lookup
Look up a legal entity by LEI code, or search by company name.
import { useLeiLookup } from "@omnizoek/react";
// Direct lookup by LEI code
const { data } = useLeiLookup({ lei: "5493001KJTIIGC8Y1R12" });
// Search by name
const { data } = useLeiLookup({ name: "ING", country: "NL" });
// data.legal_name, data.jurisdiction, data.status, data.registered_address, …OmniHookResult<T>
Every hook returns this shape:
interface OmniHookResult<T> {
/** Response data, or `undefined` while loading or on error */
data: T | undefined;
/** `true` on the initial load (no cached data yet) */
loading: boolean;
/** `true` whenever a background revalidation is in flight */
validating: boolean;
/** Typed error from the SDK, or `null` */
error: Error | null;
/** Manually trigger a refetch / revalidation */
refetch: () => Promise<T | undefined>;
}Hook options
All hooks accept an optional second argument:
interface UseOmniQueryOptions {
/**
* Set to `false` to skip the request without passing `null` as params.
* @default true
*/
enabled?: boolean;
}Example — skip fetching until a checkbox is checked:
const { data } = useEnergyLabel(
{ postcode, houseNumber },
{ enabled: showEnergyLabel }
);Error handling
All SDK errors extend OmniError and are available from @omnizoek/sdk:
import {
OmniAuthError,
OmniNotFoundError,
OmniRateLimitError,
} from "@omnizoek/sdk";
const { error } = useAddressEnrich({ postcode: "0000XX", houseNumber: "0" });
if (error instanceof OmniAuthError) { /* invalid API key */ }
if (error instanceof OmniNotFoundError) { /* address not found */ }
if (error instanceof OmniRateLimitError) { /* rate limited */ }OmniProvider props
| Prop | Type | Required | Description |
|---|---|---|---|
| apiKey | string | ✅ | Your OmniZoek API key (omni_live_… or omni_test_…) |
| baseUrl | string | — | Override the API base URL (useful for local mocks) |
| options | OmniClientOptions | — | Additional options forwarded to OmniClient (retries, timeout, …) |
| children | ReactNode | ✅ | Component subtree that can use OmniZoek hooks |
The underlying OmniClient is memoized and only recreated when apiKey or baseUrl changes.
Requirements
- React ≥ 17
- SWR ≥ 2
@omnizoek/sdk≥ 0.1.1- Node.js ≥ 18 (for SSR / server components)
Related packages
| Package | Description |
|---|---|
| @omnizoek/sdk | Framework-agnostic TypeScript SDK |
License
Proprietary — see LICENSE.
