Components
Switch / Match

Switch / Match

Switch renders the first truthy Match, otherwise it renders fallback.

  • Works in React Server Components (RSC)
  • Works in Client Components
  • No hooks
  • No state
  • No "use client" directive required

API

Switch

PropTypeRequiredDescription
childrenReactNodeYesOne or more <Match /> elements
fallbackReactNodeNoRendered when no match succeeds

Match

PropTypeRequiredDescription
whenT | (() => T)YesValue or function that is evaluated for matching
childrenReactNode | ((value: Exclude<T, false | 0 | '' | null | undefined>) => ReactNode)YesUI or render function called with matched value

Behavior

  1. Switch scans children from top to bottom.
  2. It renders only the first <Match> whose when value is truthy.
  3. If nothing matches, it renders fallback.
  4. If no fallback is provided, it renders null.
  5. Switch throws if a direct child is not a <Match> component.

Basic Usage

import { Switch, Match } from "use-kit";
 
function StatusView({ isLoading, error, data }) {
  return (
    <Switch fallback={<div>No result</div>}>
      <Match when={isLoading}>
        <div>Loading...</div>
      </Match>
 
      <Match when={error}>{(message) => <div>Error: {message}</div>}</Match>
 
      <Match when={data}>{(result) => <div>{result.title}</div>}</Match>
    </Switch>
  );
}

Function when

import { Switch, Match } from "use-kit";
 
<Switch fallback={<div>Not authorized</div>}>
  <Match when={() => user?.role === "admin"}>
    <div>Admin panel</div>
  </Match>
</Switch>;

Function-as-Children

When children is a function, it receives the matched truthy value from when.

import { Switch, Match } from "use-kit";
 
<Switch fallback={<div>Please sign in</div>}>
  <Match when={user}>{(u) => <div>Welcome, {u.name}</div>}</Match>
</Switch>;

Next.js App Router Examples

Server Component (RSC)

// app/page.tsx
import { Switch, Match } from "use-kit";
 
async function getUser() {
  return { name: "John", role: "admin" } as {
    name: string;
    role: string;
  } | null;
}
 
export default async function Page() {
  const user = await getUser();
 
  return (
    <Switch fallback={<div>Fallback</div>}>
      <Match when={!user}>
        <div>Please sign in</div>
      </Match>
 
      <Match when={user}>{(u) => <div>Welcome, {u.name}</div>}</Match>
 
      <Match when={() => user?.role === "admin"}>
        <div>Admin tools</div>
      </Match>
    </Switch>
  );
}

Client Component

// app/example/client-switch.tsx
"use client";
 
import { Switch, Match } from "use-kit";
 
export default function ClientSwitch({
  isLoading,
  error,
  data,
}: {
  isLoading: boolean;
  error: string | null;
  data: { title: string } | null;
}) {
  return (
    <Switch fallback={<div>No data</div>}>
      <Match when={isLoading}>
        <div>Loading...</div>
      </Match>
 
      <Match when={error}>{(message) => <div>Error: {message}</div>}</Match>
 
      <Match when={data}>{(value) => <h2>{value.title}</h2>}</Match>
    </Switch>
  );
}
Last updated on March 2, 2026