npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@liiift-studio/sanity-export-data

v2.0.1

Published

Flexible data export utility for Sanity Studio — export any document types to CSV or JSON with optional reference population

Downloads

214

Readme

@liiift-studio/sanity-export-data

Search your Sanity content by name and type, optionally populate references, and download it as CSV or JSON — straight from a Sanity Studio panel.

npm license Sanity

ExportData is a single React component for Sanity Studio. An editor types a name, picks a document type, ticks which referenced documents to expand, chooses CSV or JSON, and the matching documents download to their machine. No GROQ, no scripting, no API tokens to hand around — it runs inside Studio with the signed-in user's session.

Heads up — this is a focused, foundry-oriented tool. The document-type dropdown is a fixed list (typeface, collection, pair, font, license, order, account, cart, page, blogpost) and the result links assume a typeface-foundry desk structure. It is published for reuse across Liiift Studio foundry projects; adapt the type list (see Adapting it) if your schema differs.

How it works

  1. Search. As you type a name and pick a type, the component runs a title match "name*" GROQ query (drafts excluded), with an optional Excluding filter.
  2. Discover references. It scans the first level of each result for reference fields (_ref) and arrays of references (_ref[]), and offers a checkbox per field.
  3. Populate (optional). Tick references to re-fetch them dereferenced (field->{...}) so the export contains the full referenced documents, not just _ref pointers.
  4. Export. Choose CSV or JSON, then download. The filename is type-name-date.ext (the -name segment is dropped when the search box is empty, and date is the browser's en-US locale date, e.g. typeface-Freight-6/19/2026.csv).

Install

npm install @liiift-studio/sanity-export-data

The package ships an ESM bundle and declares these peer dependencies — install/keep them in your Studio:

| Peer dependency | Supported range | |---|---| | sanity | ^3.0.0 \|\| ^4.0.0 \|\| ^5.0.0 | | react | ^18.0.0 \|\| ^19.0.0 | | @sanity/ui | ^1.0.0 \|\| ^2.0.0 \|\| ^3.0.0 | | @sanity/icons | ^2.0.0 \|\| ^3.0.0 |

Quick start

ExportData is the default export. Give it a Sanity client and a displayName (and optionally an icon):

import ExportData from '@liiift-studio/sanity-export-data'
import { useClient } from 'sanity'
import { DownloadIcon } from '@sanity/icons'

function DataExporter() {
	const client = useClient({ apiVersion: '2023-01-01' })

	return (
		<ExportData
			client={client}
			displayName="Export Data"
			icon={DownloadIcon}
		/>
	)
}

As a Studio tool

Wrap it in a structure / dashboard / custom tool that can supply a client. A minimal custom tool:

// sanity.config.js
import { defineConfig } from 'sanity'
import { useClient } from 'sanity'
import { DownloadIcon } from '@sanity/icons'
import ExportData from '@liiift-studio/sanity-export-data'

function ExportDataTool() {
	const client = useClient({ apiVersion: '2023-01-01' })
	return <ExportData client={client} displayName="Export Data" icon={DownloadIcon} />
}

export default defineConfig({
	// ...projectId, dataset, plugins, schema
	tools: (prev) => [
		...prev,
		{
			name: 'export-data',
			title: 'Export Data',
			icon: DownloadIcon,
			component: ExportDataTool,
		},
	],
})

The component renders its own UI (search box, type dropdown, reference checkboxes, format radios, results list). It does not register itself as a tool — you mount it wherever a client is available.

Props

The shipped component accepts exactly three props:

| Prop | Type | Required | Description | |---|---|---|---| | client | SanityClient | yes | Sanity client used for all fetch calls. | | displayName | string | no | Heading shown above the panel. | | icon | React.ComponentType | no | Icon rendered beside the heading (e.g. a @sanity/icons icon). |

There are no format, documentTypes, includeReferences, maxDepth, onComplete, or onError props — the format, types, references, and filters are all chosen interactively in the panel.

What gets exported

JSON

The raw documents as fetched, pretty-printed:

[
	{
		"_id": "typeface-123",
		"_type": "typeface",
		"title": "Freight",
		"slug": { "current": "freight" }
	}
]

CSV

One row per document. The header is the union of all top-level keys across the result set; string and object/array values are wrapped in quotes (objects are JSON-stringified, embedded " doubled), while numbers and booleans are written raw:

_id,_type,title,slug
"typeface-123","typeface","Freight","{""current"":""freight""}"

Populated references

When you tick a reference field, that field is re-fetched dereferenced, so the export carries the full referenced document inline instead of a { _ref } pointer:

{
	"_id": "typeface-123",
	"_type": "typeface",
	"title": "Freight",
	"foundry": {
		"_id": "foundry-9",
		"title": "Darden Studio"
	}
}

Only first-level reference fields discovered in the search results are offered; reference expansion is one level deep.

Filtering

All filtering happens in the panel — there are no filter props:

  • Name — the title prefix to match (title match "name*").
  • Type — one document type from the dropdown.
  • Excluding (toggle) — adds && !(title match "*exclude*") to drop unwanted matches.
  • Drafts are always excluded (!(_id in path('drafts.**'))).

Use cases

  • Backups & archives — pull a typeface, collection, or order set to JSON.
  • Migration — export documents with references populated for re-import elsewhere.
  • Reporting — export orders/accounts to CSV for Excel or Google Sheets.
  • Content audits — list and export a type filtered by name.

Caveats & limits

  • Download size. Files are delivered via a data: URI and a synthetic <a download> click. Browsers cap data-URI length (often a few MB), so very large result sets can fail or truncate — narrow the search or export in batches.
  • Title-based search only. A document must match title match "name*" to appear; there is no full-dataset "export everything" button.
  • GROQ is built from input. The query interpolates the typed name, exclude value, and selected type directly into GROQ. It runs read-only fetches under the signed-in user's permissions, but treat it as an internal admin tool rather than untrusted input.
  • Foundry-specific defaults. The type list and result-link desk paths assume a typeface-foundry schema — see below to adapt.

Adapting it

The document-type list and the desk-link paths are defined inline in src/ExportData.jsx:

  • The <Select> <option> values are the available types.
  • The results list builds hrefs like /desk/<type>;<id> (with an orderable- prefix for typeface; the code also handles licenseGroup, which is not in the default dropdown).

Fork or vendor the file and edit those to match your schema and desk structure.

Compatibility

  • Sanity Studio v3, v4, or v5
  • React 18 or 19
  • @sanity/ui v1, v2, or v3, @sanity/icons v2 or v3

Diagram source

The data-flow diagram above is generated from a committed Mermaid source. To regenerate after a change:

npm run capture   # renders assets/*.mmd -> assets/*.svg via @mermaid-js/mermaid-cli

License

MIT © Quinn Keaveney / Liiift Studio. See the license field in package.json.

Contributing

Issues and pull requests welcome at Liiift-Studio/sanity-export-data.