# parse\_csv

Parses a CSV string into an array of objects. The first row is used as headers — each subsequent row becomes an object with header names as keys.

```liquid
{% assign rows = file.content | parse_csv %}
{% for row in rows %}
  {% log row.sku | append: ": " | append: row.title %}
{% endfor %}
```

#### Syntax

```liquid
{{ csv_string | parse_csv }}
```

| Parameter    | Description                            |
| ------------ | -------------------------------------- |
| `csv_string` | A string containing CSV-formatted data |

#### Return Value

Returns an array of objects. Each object represents a row, with keys taken from the header row.

#### Examples

**Parse a CSV file from file storage:**

```liquid
{% storage_read filename:"products.csv" as csv_content %}
{% assign rows = csv_content | parse_csv %}
{% log "Rows: " | append: rows.size %}
{% for row in rows %}
  {% log row %}
{% endfor %}
```

**Parse an uploaded input file:**

```liquid
{% assign rows = file.content | parse_csv %}
{% for row in rows %}
  {% log row.sku | append: " - " | append: row.price %}
{% endfor %}
```

**Parse CSV from an HTTP response:**

```liquid
{% http url:"https://example.com/export.csv" method:"GET" as response %}
{% assign rows = response.body | parse_csv %}
{% for row in rows %}
  {% log row %}
{% endfor %}
```

**Process CSV rows and update products:**

```liquid
{% assign rows = file.content | parse_csv %}
{% for row in rows %}
  {% if row.sku and row.price %}
    {% log "Updating " | append: row.sku | append: " to $" | append: row.price %}
    {% comment %} Update logic here {% endcomment %}
  {% endif %}
{% endfor %}
```

**Combine with left\_join to match import data:**

```liquid
{% assign import_rows = file.content | parse_csv %}
{% assign matched = import_rows | left_join: existing_variants, "sku = sku" %}
{% for row in matched %}
  {% if row.inventory_item_id %}
    {% log "Update: " | append: row.sku %}
  {% else %}
    {% log "Create: " | append: row.sku %}
  {% endif %}
{% endfor %}
```

#### Notes

* The first row is always treated as the header row
* Auto-detects the delimiter (comma, semicolon, tab, etc.)
* Returns an empty array if the input is empty or not a string
* Throws an error on malformed CSV data
* See also: `parse_json`, `parse_xml`
