Skip to main content
Version: next

Customize the CSV format

Front-Commerce exposes a single CSV codec — its configuration lives at `theme/modules/CsvEntries`, its mechanics at `@front-commerce/theme-chocolatine/csv` — shared by every feature that produces or consumes a CSV file (Quick Order upload, downloadable template, order detail CSV download, etc.). This guide explains how to override the codec configuration to change the file format from a single place.

Why a shared codec?

Several Front-Commerce features read or write CSV files, and they all need to agree on the same layout for a customer round-trip to be possible. For example, the order detail CSV download produces a file that the Quick Order page must be able to re-upload as-is to repeat the order.

Rather than duplicating the column declarations across each feature, the codec splits across two surfaces:

  • Configuration (theme/modules/CsvEntries/{csvEntriesConfig,useCsvEntriesConfig}) — the default columns, delimiter and React hook. This is the override surface extensions are expected to customize.
  • Mechanics (@front-commerce/theme-chocolatine/csv) — the parseCsv/generateCsv functions and codec types (CsvEntry, CsvColumn, CsvEntriesConfig, CsvUnparseOptions). Exposed as a public sub-export so any consumer (including non-theme code) can import them, but deliberately outside the theme override surface so the parse/serialise contract stays guaranteed.

Each feature that needs a CSV codec composes its own config from CsvEntriesConfig, so a single override propagates everywhere.

Override the codec

Override the useCsvEntriesConfig hook from your extension to change the columns, delimiter, or papaparse generation options.

my-extension/src/theme/modules/CsvEntries/useCsvEntriesConfig.ts
import type { CsvEntriesConfig } from "@front-commerce/theme-chocolatine/csv";
import myCsvEntriesConfig from "./myCsvEntriesConfig";

const useCsvEntriesConfig = (): CsvEntriesConfig => myCsvEntriesConfig;

export default useCsvEntriesConfig;

The CsvEntriesConfig type (from @front-commerce/theme-chocolatine/csv) exposes:

FieldRequiredPurpose
csvColumnsyesDeclares the CSV columns. Each column drives how a CSV cell is parsed into an entry (parse) and how an entry is serialised back to a cell (format). A column with required: false may be left empty on a row, or omitted entirely from the uploaded CSV.
csvDelimiteryesCharacter used to split / join CSV cells. Must match what your users export from their tooling.
csvUnparseOptionsnoExtra options forwarded to Papa.unparse when generating CSV files. Set { quotes: true } to force every cell to be wrapped in double quotes, for example.

Feature-specific concerns (sample rows for the Quick Order template, order-item mapping and filename pattern for the order CSV download, etc.) live in each feature's own config that composes CsvEntriesConfig — see the Quick Order guide for the upload page.

Example: add a non-blocking custom column

Adding a column is a codec change — every feature that composes CsvEntriesConfig picks it up automatically.

myCsvEntriesConfig.ts
import { defaultCsvEntriesConfig } from "theme/modules/CsvEntries";

const myCsvEntriesConfig = {
...defaultCsvEntriesConfig,
csvColumns: [
...defaultCsvEntriesConfig.csvColumns,
{
key: "note",
header: "note",
required: false,
parse: (value, entry) => ({ ...entry, note: value }),
format: (entry) => String(entry.note ?? ""),
},
],
};

export default myCsvEntriesConfig;

The Quick Order upload, the template download, and the order CSV download now all accept the new optional note column from a single declaration.

Example: change the delimiter and force quoting

myCsvEntriesConfig.ts
import { defaultCsvEntriesConfig } from "theme/modules/CsvEntries";

const myCsvEntriesConfig = {
...defaultCsvEntriesConfig,
csvDelimiter: ";",
csvUnparseOptions: { quotes: true },
};

export default myCsvEntriesConfig;

The generated CSV files now use ; as the cell separator and wrap every value in double quotes. The parser uses the same csvDelimiter, so an uploaded file produced with these settings round-trips through the codec.