# Subject chip

> A compact badge with a subject's type and title that links to its page.

Source: https://bettersupabase.com/docs/registry/ui-recipes/subject-chip

{/* Generated by scripts/build-recipes.ts from the example apps. Edit the examples or the script, then run `pnpm recipes`. */}

It calls `useSubject` from `better-supabase/blocks/subjects/react`; the [subjects block](https://bettersupabase.com/blocks/subjects) must be installed (`npx better-supabase add subjects`). Its page on bettersupabase.com is [/recipes/subject-chip](https://bettersupabase.com/recipes/subject-chip).

Web, with shadcn components:

```bash
npx shadcn add skeleton
```

```tsx title="apps/examples/nextjs/src/features/subjects/components/subject-chip.tsx"
"use client";

import type { SubjectRef } from "better-supabase/blocks/subjects";

import { useSubject } from "better-supabase/blocks/subjects/react";
import { useExtracted } from "next-intl";

import { Badge } from "@/components/reui/badge";
import { Skeleton } from "@/components/ui/skeleton";
import { Link } from "@/i18n/navigation";

/**
 * A compact badge for a subject: its type and title, linking to its page. Rows
 * that each render a chip share one `subject_titles` call.
 */
export function SubjectChip({ subject }: { subject: SubjectRef }) {
  const t = useExtracted("subjects");
  const { subject: resolved, error } = useSubject(subject);

  if (resolved === undefined && !error) {
    return <Skeleton className="h-5 w-24" />;
  }

  const label = resolved?.title ?? t("Unavailable");

  const content = (
    <>
      <span className="text-muted-foreground">{subject.type}</span>
      <span className="truncate">{label}</span>
    </>
  );

  return resolved?.url === undefined ? (
    <Badge variant="outline">{content}</Badge>
  ) : (
    <Badge
      variant="outline"
      className="transition-colors hover:bg-accent"
      render={<Link href={resolved.url} />}
    >
      {content}
    </Badge>
  );
}
```