# Knowledge base upload

> A form that adds a document to the knowledge base, which chunks and embeds it for search.

- Block: [knowledge](https://bettersupabase.com/blocks/knowledge.md)
- Kind: component
- Data: loaded on the server through the block's client
- Page: https://bettersupabase.com/recipes/knowledge-upload

## Install the block

```bash
npx better-supabase add knowledge
```

## Web (Next.js)

Add the shadcn components:

```bash
npx shadcn add button field input textarea
```

From `apps/examples/nextjs/src/features/knowledge/components/add-document-form.tsx` (https://github.com/ScaleDockHQ/better-supabase/blob/main/apps/examples/nextjs/src/features/knowledge/components/add-document-form.tsx):

```tsx
"use client";

import { useActionForm } from "better-supabase/react";
import { useExtracted } from "next-intl";
import { useId } from "react";

import { Button } from "@/components/ui/button";
import { Field, FieldError, FieldLabel } from "@/components/ui/field";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { useErrorMessage } from "@/lib/use-error-message";

import { addDocument } from "../knowledge-actions";

export function AddDocumentForm() {
  const t = useExtracted("knowledge");
  const fieldId = useId();
  const errorMessage = useErrorMessage();
  const form = useActionForm(addDocument);
  const error = form.error === undefined ? null : errorMessage(form.error);

  return (
    <form {...form.formProps} className="space-y-3">
      <Field>
        <FieldLabel htmlFor={`${fieldId}-title`}>{t("Title")}</FieldLabel>
        <Input id={`${fieldId}-title`} name="title" required maxLength={200} />
      </Field>
      <Field data-invalid={error ? true : undefined}>
        <FieldLabel htmlFor={`${fieldId}-text`}>{t("Text")}</FieldLabel>
        <Textarea
          id={`${fieldId}-text`}
          name="text"
          placeholder={t("Paste a policy, a guide or meeting notes")}
          required
          maxLength={100_000}
          rows={6}
        />
        {error ? <FieldError>{error}</FieldError> : null}
      </Field>
      <Button type="submit" size="sm" disabled={form.pending}>
        {t("Add document")}
      </Button>
    </form>
  );
}
```

## Prompt

Paste this into a coding agent to build the recipe in your app.

### Web

```text
Build "Knowledge base upload" in a React web app that uses shadcn/ui components. A form that adds a document to the knowledge base, which chunks and embeds it for search.

It uses the better-supabase `knowledge` block (Knowledge). It loads its data on the server through the block's client.

Steps:

1. If the app doesn't have the block yet, add the SQL with `npx better-supabase add knowledge` and apply the migration.
2. Add the shadcn components the recipe uses: `npx shadcn add button field input textarea`.
3. The recipe needs no glue: it calls the block's client on the server.
4. Write the component. Load the data on the server with the block's client, starting from the recipe's snippet (`apps/examples/nextjs/src/features/knowledge/components/add-document-form.tsx`). Adapt it to the app's existing components, styling and data loading instead of copying it as is.
5. Check the result against the recipe and the block's docs: it typechecks, it reads the same block data, and it handles the loading and empty states the snippet handles.

Read the full code first:

- Recipe: https://bettersupabase.com/recipes/knowledge-upload.md
- Block docs: https://bettersupabase.com/docs/blocks/knowledge
```
