> For AI agents: the complete Sanity documentation index is available at [https://www.sanity.io/docs/llms.txt](https://www.sanity.io/docs/llms.txt).

# Archive documents without deleting them

Compare ways to take content off your site but keep it: unpublish, an archived field, delete and restore, or unpublish in a release.

Sanity has no built-in archived state for documents. When you want to take content off your website but keep it, such as a former partner, a retired product, or a past event, you choose between mechanisms that already exist: unpublishing the document, marking it with an archived field you add to your schema, deleting it with the option to restore it later, or unpublishing it as part of a content release. They differ in what your queries return, what editors see in Studio, and how you bring the content back.

This guide compares the approaches and shows how to set up the archived field pattern, including Structure tool lists that keep archived documents apart from active ones.

## Compare the approaches

The approaches differ in what your website shows, what editors see in Studio, and how you bring content back:

| Approach | On your website | In Studio | To bring it back |
| --- | --- | --- | --- |
| Unpublish | Removed. Queries using the published perspective no longer return it. | Shows as a draft, like any document that was never published. | Publish the draft. |
| Archived field | Still published. Every query must filter it out. | Stays published and editable. You can list it separately with Structure Builder. | Clear the field and publish. |
| Delete | Removed. | Removed. | Restore it from history, within your plan's history retention period. |
| Unpublish in a content release | Removed when the release publishes. | Shows as a draft after the release publishes. | Publish the draft. |

## Choose an approach

- **Unpublish** when you want the content off your website and don't need to tell it apart from work in progress. It takes no setup.
- **Add an archived field** when editors need to find archived content as archived, or when some queries still need it, such as an archive page on your site. This is the only approach that keeps archived documents separate from in-progress drafts, which makes it the best fit for most "hide it, but keep it" cases. Archived documents stay published, so anyone can query them if your dataset is public.
- **Delete** when you don't expect to need the content again. Deleting is not an archive: the restore window ends when your plan's history retention period ends.
- **Unpublish in a content release** when retiring content needs to happen at a set time, or together with other changes.

## Unpublish a document

Unpublishing removes the published document and keeps its content as a draft. Queries that use the published perspective, which is what production front ends typically use, no longer return it. Queries that use the drafts perspective still do. For how the two perspectives differ, see [Perspectives for Content Lake](https://www.sanity.io/docs/content-lake/perspectives).

To unpublish a document in Studio, select the **Published** perspective, either at the Studio level or in the document header, then select **Unpublish** from the document actions menu. The action isn't available in the drafts perspective, or for document types that have `liveEdit` enabled.

Keep these behaviors in mind:

- If the document already has a draft with unpublished changes, Studio keeps that draft, and the published content is discarded.
- Content Lake doesn't let you remove a published document that other documents hold a strong reference to. Studio lists the referring documents before you confirm. Remove those references, or make them weak, first. See [Reference](https://www.sanity.io/docs/studio/reference-type).
- Nothing marks an unpublished document as archived. In Studio, it looks the same as a new document that hasn't been published yet.
- The draft still counts toward your project's document quota. See [Plans and payments](https://www.sanity.io/docs/platform-management/plans-and-payments).

## Mark documents as archived with a field

With this pattern, archived documents stay published. You add a field that marks them, filter them out of your website's queries, and give editors separate lists in Studio. The examples use a `partner` document type; replace it with your own.

> [!WARNING]
> Archived documents are still queryable in public datasets
> Anyone can query published documents in a public dataset without a token. Archived documents may not appear on your website, but they aren't private.

### Add the field to your schema

Add a boolean field to each document type you want to archive:

**schemaTypes/partner.ts**

```typescript
import {defineField, defineType} from 'sanity'

export const partnerType = defineType({
  name: 'partner',
  title: 'Partner',
  type: 'document',
  fields: [
    defineField({name: 'name', type: 'string'}),
    defineField({
      name: 'archived',
      title: 'Archived',
      type: 'boolean',
      description: 'Archived partners stay in the dataset but are hidden from the website.',
      initialValue: false,
    }),
  ],
})
```

Archiving is a content change like any other. Toggling the field creates a draft, and queries using the published perspective return the document until someone publishes that change.

### Filter archived documents out of your queries

Exclude archived documents in every query your website runs:

**GROQ**

```groq
*[_type == "partner" && archived != true]{_id, name}
```

**Result**

```json
[
  {
    "_id": "partner-acme",
    "name": "Acme Logistics"
  },
  {
    "_id": "partner-northwind",
    "name": "Northwind Foods"
  }
]
```

> [!WARNING]
> Use archived != true, not !archived
> Documents created before you added the field have no `archived` value. The filter `!archived` excludes them, because negating a missing value doesn't return `true`. The filter `archived != true` matches both documents with `archived` set to `false` and documents that don't have the field.

Filtering a document type doesn't filter references to it. When a document references archived documents, filter the dereferenced documents in the projection:

**GROQ**

```groq
*[_type == "page"]{
  title,
  "partners": partners[@->archived != true]->{_id, name}
}
```

**Result**

```json
[
  {
    "title": "Home",
    "partners": [
      {
        "_id": "partner-acme",
        "name": "Acme Logistics"
      },
      {
        "_id": "partner-northwind",
        "name": "Northwind Foods"
      }
    ]
  }
]
```

### Separate active and archived documents in Studio

Use Structure Builder to replace the default list for the document type with two filtered lists: one for active documents and one for archived documents. A document list with a filter needs an `apiVersion`.

**structure.ts**

```typescript
import type {StructureResolver} from 'sanity/structure'

export const structure: StructureResolver = (S) =>
  S.list()
    .title('Content')
    .items([
      S.listItem()
        .title('Partners')
        .schemaType('partner')
        .child(
          S.documentList()
            .title('Partners')
            .schemaType('partner')
            .apiVersion('2026-10-01')
            .filter('_type == "partner" && archived != true'),
        ),
      S.listItem()
        .title('Archived partners')
        .schemaType('partner')
        .child(
          S.documentList()
            .title('Archived partners')
            .schemaType('partner')
            .apiVersion('2026-10-01')
            .filter('_type == "partner" && archived == true'),
        ),
      S.divider(),
      ...S.documentTypeListItems().filter((listItem) => listItem.getId() !== 'partner'),
    ])
```

**sanity.config.ts**

```typescript
import {defineConfig} from 'sanity'
import {structureTool} from 'sanity/structure'

import {pageType} from './schemaTypes/page'
import {partnerType} from './schemaTypes/partner'
import {structure} from './structure'

export default defineConfig({
  projectId: 'YOUR_PROJECT_ID',
  dataset: 'production',
  plugins: [structureTool({structure})],
  schema: {types: [partnerType, pageType]},
})
```

The structure only changes the lists. Studio's global search still returns archived documents. For more list patterns, see the [Structure Builder cheat sheet](https://www.sanity.io/docs/studio/structure-builder-cheat-sheet).

### Keep archived documents out of reference inputs

To stop editors from picking archived documents in reference fields, add a filter to the reference options:

**schemaTypes/page.ts**

```typescript
import {defineArrayMember, defineField, defineType} from 'sanity'

export const pageType = defineType({
  name: 'page',
  title: 'Page',
  type: 'document',
  fields: [
    defineField({name: 'title', type: 'string'}),
    defineField({
      name: 'partners',
      type: 'array',
      of: [
        defineArrayMember({
          type: 'reference',
          to: [{type: 'partner'}],
          options: {filter: 'archived != true'},
        }),
      ],
    }),
  ],
})
```

The filter only applies when editors search for a document to reference. References that already point to an archived document stay in place, so filter them in your queries as well.

## Delete a document and restore it if needed

Deleting removes the document from your dataset, and it stops counting toward your document quota. As with unpublishing, Content Lake doesn't let you delete a document that other documents hold a strong reference to.

You can restore a deleted document from its history. For how to find deleted documents and restore them, see [Find and restore deleted documents](https://www.sanity.io/docs/developer-guides/find-and-restore-deleted-documents). Restoring is only possible within your plan's history retention period: 3 days on the Free plan, 90 days on the Growth plan, and 365 days on the Enterprise plan, or a custom period. After that, the document's history is removed and you can no longer restore it. See [History experience](https://www.sanity.io/docs/user-guides/history-experience).

The [recycling bin guide](https://www.sanity.io/docs/developer-guides/bin-for-restoring-deleted-documents) builds a list of deleted documents in Studio with Sanity Functions, so editors can restore them without looking up IDs. It restores documents from history, so the same retention period applies.

## Unpublish documents in a content release

If you use Content Releases (Sanity Studio v3.77.0 or later), a release can unpublish a document when it publishes. Add the document to the release and select **Unpublish when releasing**. When the release publishes, the result is the same as unpublishing in Studio: the content becomes a draft. If a draft already exists, it remains, and the unpublished content is lost. Strong references to the document become weak references, and they become strong again if you publish the draft. See [Content Releases user guide](https://www.sanity.io/docs/user-guides/content-releases).

Archiving a release doesn't archive its documents. It takes a release that hasn't published out of the active list, without changing any documents. Published and archived releases are removed automatically after your plan's retention window.

