How to import CSV files in WunderGraph

6 min read
Learn how to build a CSV import feature in WunderGraph. Step-by-step guide for developers integrating spreadsheet uploads in SaaS applications.

How to Import CSV Files in WunderGraph Using CSVBox

Integrating CSV import into your WunderGraph app simplifies onboarding bulk data from spreadsheets and improves operational workflows. This step-by-step guide shows a practical flow—file → map → validate → submit—so you can embed a production-ready CSV import experience using CSVBox and WunderGraph in 2026.

This guide covers:

  • Embedding CSVBox’s upload widget in a React/Next.js frontend
  • Validating and previewing CSV data in the browser
  • Sending the cleaned, validated payload to a WunderGraph mutation or webhook
  • Common troubleshooting tips for developer workflows

Who this guide is for

This article is intended for:

  • Full‑stack engineers building admin dashboards or SaaS features
  • Technical founders and product teams adding spreadsheet imports
  • Backend engineers wiring validated payloads into databases or downstream systems

If you’re asking questions like:

  • How do I allow users to upload CSVs in a WunderGraph app?
  • How can I validate and map spreadsheet columns before saving?
  • What’s the best flow to send sanitized CSV data to my backend?

You’ll find concrete, copy‑pasteable examples and best practices here.


Why add CSV upload to your WunderGraph app (and when to use CSVBox)

WunderGraph is great at composing secure APIs, but handling file uploads, column mapping, and inline spreadsheet validation is repetitive to build and maintain. CSVBox provides:

  • An embeddable upload widget with a spreadsheet-like preview and built-in validations
  • Column mapping and inline error display so users fix rows before submission
  • Scalable processing and options to deliver cleaned data to your backend (widget callback or webhooks)

Use CSVBox when you want to offload validation UX and large-file processing while keeping full developer control over how validated data is stored or processed.


What you’ll need

  • A working WunderGraph frontend/backend project
  • A CSVBox account and a configured import “box” (client_app_id + import_link_id)
  • React or Next.js for the frontend example

Sign up or view docs at https://help.csvbox.io/ if you need setup details.


Integration overview (high level)

  1. Configure an import box in CSVBox (define columns and validations).
  2. Embed CSVBox’s React widget in your frontend.
  3. Receive validated rows via the widget callback (onData) or via CSVBox webhooks.
  4. Call a WunderGraph mutation (or endpoint) to persist or process the data.

Step-by-step: embed CSV upload in WunderGraph

1. Create a WunderGraph app (if you don’t have one)

Run the starter commands to scaffold a local WunderGraph app:

npx create-wundergraph-app csv-import-demo
cd csv-import-demo
npm install
npm run dev

You should now have a local WunderGraph dev environment to iterate against.

2. Configure your import box in CSVBox

In the CSVBox dashboard:

  • Create a new import box.
  • Define expected columns (for example: name, email, age).
  • Add validations (required fields, email format, numeric checks).
  • Copy the client_app_id and import_link_id for that box.

These identifiers let the widget authenticate and load the exact mapping/validation rules you defined.

3. Install the CSVBox React widget

Install the official widget package in your frontend:

npm install @csvbox/react

4. Embed the CSVBox widget component

Create a component (e.g., CsvUploader.tsx) that renders CSVBox and receives validated data:

import { CSVBox } from '@csvbox/react';

export default function CsvUploader() {
  const onData = (data) => {
    console.log('Received validated data from CSVBox', data);
    // Forward to your WunderGraph mutation
  };

  return (
    <CSVBox
      client_app_id="your-client-app-id"
      import_link_id="your-import-box-id"
      user={{ id: '123', name: 'Project Admin' }}
      onData={onData}
    />
  );
}

Use this component inside a page or as a client-only component in Next.js.

Notes:

  • The widget presents a spreadsheet-like preview and will surface validation errors inline before calling onData.
  • You can pass a user object to provide context for audit trails or mapping rules.

5. Create a WunderGraph mutation to accept CSV data

Create an operation that accepts an array of validated rows. Example handler (uses zod for schema validation):

// ./wundergraph.operations/importUsers.ts

import { createOperation } from '@wundergraph/sdk/server';
import { z } from 'zod';

export default createOperation.mutation({
  input: z.object({
    users: z.array(
      z.object({
        name: z.string(),
        email: z.string().email(),
        age: z.number(),
      })
    ),
  }),
  handler: async ({ input }) => {
    for (const user of input.users) {
      console.log('Imported user:', user);
      // Insert into DB or trigger downstream logic
    }

    return {
      success: true,
      count: input.users.length,
    };
  },
});

Keep your schema in sync with the CSVBox import box so the frontend validation and backend types match.

6. Connect the widget to your WunderGraph mutation

Update the CsvUploader to call your operation after receiving validated rows:

import { CSVBox } from '@csvbox/react';
import { useMutation } from '@wundergraph/nextjs';

export default function CsvUploader() {
  const { mutate } = useMutation.importUsers();

  const onData = async (data) => {
    const response = await mutate({ users: data });
    alert(`Imported ${response.count} users!`);
  };

  return (
    <CSVBox
      client_app_id="your-client-app-id"
      import_link_id="your-import-box-id"
      user={{ id: 'admin', name: 'Admin User' }}
      onData={onData}
    />
  );
}

This flow keeps validation in the widget. The backend receives only cleaned rows and can focus on persistence and business logic.


Expected data shape

The widget returns an array of objects matching your mapping/validation rules. Example payload:

[
  { "name": "Alice", "email": "alice@example.com", "age": 30 },
  { "name": "Bob", "email": "bob@example.com", "age": 45 }
]

If rows fail validations defined in your import box, the widget shows inline errors and does not call onData until the data is fixed.


Alternatives: webhooks and server-side ingestion

If you prefer not to route data through the frontend, CSVBox supports delivering cleaned datasets to a webhook endpoint. This is useful for:

  • Large batch ingestion handled server-side
  • Offloading uploads from the client
  • Triggering async processing pipelines

See CSVBox webhook documentation for configuration and examples: https://help.csvbox.io/logging-and-callbacks/3.2-webhook-callbacks


Common problems and fixes

  • CSV data doesn’t reach your backend
    • Verify onData is implemented and that your mutation accepts the expected shape.
  • Widget doesn’t render
    • Confirm client_app_id and import_link_id are correct and that the widget is mounted client-side (use dynamic import if using SSR).
  • Typescript or zod validation errors
    • Ensure your zod schema mirrors the import box columns and types.
  • Large-file or performance issues
    • Consider using CSVBox’s server-side webhook delivery to avoid large client uploads.

Best practices and tips for 2026-ready integrations

  • Keep validation rules in CSVBox as the source of truth for user-facing checks; mirror the rules in your backend schema to prevent drift.
  • Prefer webhook delivery for very large datasets or when you need guaranteed server-side retries.
  • Use the user context passed to the widget for auditability and row-level metadata.
  • Wrap the CSVBox widget in a client-only component in Next.js to avoid SSR issues (dynamic import or useEffect).
  • Log import results and expose clear import summaries to users (rows processed, rows failed, actionable error messages).

Helpful resources


Wrapping up

Embedding CSVBox into your WunderGraph app gives you a robust file → map → validate → submit flow with minimal frontend and backend code. Whether you handle ingestion via the widget callback or CSVBox webhooks, you get a clearer UX, fewer import errors, and a predictable, type-safe payload for persistence.

Next steps:

  • Persist imported rows to your database
  • Add user-facing import summaries and error reporting
  • Consider webhooks for large-batch server-side ingestion

Start integrating CSVBox with WunderGraph today to add reliable, user-friendly spreadsheet imports to your app.

Related Posts