Framework guide

CSV and Excel importer for Vite + React

Vite apps usually separate a React SPA from a backend API. Bootstrapware Importer fits that shape: the component runs entirely in the browser; your API accepts JSON rows from onComplete. Spreadsheet contents stay on the client and are not sent to Bootstrapware.

Install

pnpm add @bootstrapware/importer

Import CSS from your entry module or the page that mounts the importer:

// main.tsx or ImportPage.tsx
import "@bootstrapware/importer/styles.css";

Local schema in the SPA

import { Importer } from "@bootstrapware/importer";
import "@bootstrapware/importer/styles.css";

export function CatalogImport({ sessionToken }: { sessionToken: string }) {
  return (
    <Importer
      fields={[
        { key: "sku", label: "SKU", type: "string", required: true },
        { key: "price", label: "Price", type: "number", required: true },
        { key: "name", label: "Name", type: "string", required: true },
      ]}
      duplicateKey="sku"
      onComplete={async (rows, meta) => {
        const res = await fetch(`${import.meta.env.VITE_API_URL}/imports`, {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
            Authorization: `Bearer ${sessionToken}`,
          },
          body: JSON.stringify({ rows, meta }),
        });
        if (!res.ok) throw new Error("Import failed");
      }}
    />
  );
}

Use your normal SPA auth: cookie credentials, bearer token, or whatever your API already expects. The importer does not manage auth for you.

Hosted keys with Vite env

Prefix browser-exposed vars with VITE_. Only publishable keys belong there.

#.env.local
VITE_API_URL=http://localhost:3001
VITE_IMPORTER_ID=imp_...
VITE_BSW_PUBLISHABLE_KEY=bsw_test_pub_...
<Importer
  importerId={import.meta.env.VITE_IMPORTER_ID}
  publishableKey={import.meta.env.VITE_BSW_PUBLISHABLE_KEY}
  onComplete={async (rows) => {
    await fetch(`${import.meta.env.VITE_API_URL}/imports`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ rows }),
    });
  }}
/>

If the browser calls the Bootstrapware API from localhost (hosted config fetch), register that origin. See origins. Your own API still needs CORS (or same-origin proxy) for the onComplete POST.

API expectations

Accept JSON, not multipart spreadsheet uploads to Bootstrapware. Re-validate on the server, then insert. Example body shape:

{
  "rows": [
    { "sku": "A-100", "price": 19.5, "name": "Widget" }
  ],
  "meta": { /* counts, file type, duration */ }
}

More on the callback: onComplete. Database-oriented guides: Postgres, Supabase.

Pitfalls

  • Forgetting styles.css
  • Using a non-VITE_ prefix and wondering why env is undefined in the browser
  • Exposing secret keys as VITE_ vars
  • CORS blocking either your API or the hosted config fetch

Related: React guide · API keys · Origins · Live demo