CSV Export

Export Prisma data as downloadable CSV files. No dependencies — pure TypeScript utilities.

Export any data to CSV with a type-safe buildCSV utility and downloadCSV browser helper. No external dependencies required.

What's Included

FilePurpose
lib/features/export.tsbuildCSV(headers, rows) and downloadCSV(filename, csv) utilities

Usage

Client-Side Export

"use client"

import { buildCSV, downloadCSV } from "@/lib/features/export"
import { Button } from "@/components/ui/button"
import { Download } from "lucide-react"

export function ExportUsersButton({ users }: { users: Array<{ name: string; email: string; plan: string }> }) {
  const handleExport = () => {
    const headers = ["Name", "Email", "Plan"]
    const rows = users.map((u) => [u.name, u.email, u.plan])
    const csv = buildCSV(headers, rows)
    downloadCSV("users-export.csv", csv)
  }

  return (
    <Button onClick={handleExport} variant="outline" size="sm">
      <Download className="mr-2 h-4 w-4" />
      Export CSV
    </Button>
  )
}

Server-Side API Route

Create app/api/export/users/route.ts for admin CSV exports:

import { NextResponse } from "next/server"
import { getAdminSession } from "@/lib/auth-utils"
import { db } from "@/lib/db"
import { buildCSV } from "@/lib/features/export"

export async function GET() {
  await getAdminSession()

  const users = await db.user.findMany({
    select: { name: true, email: true, role: true, plan: true, createdAt: true },
    orderBy: { createdAt: "desc" },
  })

  const headers = ["Name", "Email", "Role", "Plan", "Joined"]
  const rows = users.map((u) => [
    u.name ?? "",
    u.email ?? "",
    u.role,
    u.plan ?? "FREE",
    u.createdAt.toISOString().split("T")[0],
  ])

  return new NextResponse(buildCSV(headers, rows), {
    headers: {
      "Content-Type": "text/csv; charset=utf-8",
      "Content-Disposition": `attachment; filename="users-${new Date().toISOString().split("T")[0]}.csv"`,
    },
  })
}

API Reference

buildCSV(headers, rows)

buildCSV(headers: string[], rows: string[][]): string
  • Wraps fields with commas/quotes/newlines in double-quotes
  • Escapes embedded double-quotes by doubling them
  • Joins rows with \r\n (RFC 4180 compliant)
  • Adds a UTF-8 BOM for Excel compatibility

downloadCSV(filename, csv)

downloadCSV(filename: string, csv: string): void

Creates a text/csv Blob, generates a temporary Object URL, and programmatically clicks a hidden <a> tag to trigger the browser download. Cleans up the URL after download.

Environment Variables

None required.

Verification

  1. Import buildCSV and downloadCSV in a client component
  2. Pass sample data and trigger the export
  3. Open the downloaded file in Excel or Google Sheets
  4. Confirm: headers on row 1, fields with commas properly quoted, UTF-8 encoding correct

Demo Mode — Explore freely. Some actions are restricted. demo@launchfst.dev / demo1234

Get LaunchFst →