---
title: Taxonomies in Optimizely Graph
slug: cms-saas/docs/taxonomies-in-optimizely-graph
docTags: 
createdAt: 2026-09-08T20:18:11.000Z
---

**Taxonomy** in Optimizely Content Management System (CMS) (SaaS) provides a structured system for organizing content. A taxonomy consists of terms that classify and categorize content. CMS (SaaS) supports hierarchical terms called **Categories**. Categories support parent-child relationships with multiple nesting levels, which enables taxonomic organization, browsable navigation paths, and logical grouping of related content.

Taxonomies are indexed in Optimizely Graph in two locations: as term references on content items (`_itemMetadata.categories`) and as standalone taxonomy term documents (the `_TaxonomyTerm` type). This supports taxonomy-based filtering and navigation in headless content delivery scenarios.

Content items store category assignments as URI references (`cms://taxonomy/categories/electronics`), and taxonomy terms are indexed as separate documents that contain localized metadata.

## Categories on content

The `_itemMetadata` contract includes a `categories` field that contains an array of taxonomy term reference URIs:

```graphql
query GetContentWithTaxonomy {
  _Content {
    items {
      _itemMetadata {
        key
        displayName
        categories
      }
    }
  }
}
```

Each reference is a URI string in the format `SCHEME://AUTHORITY/TAXONOMY_KEY/TERM_KEY`. Only CMS internal taxonomies are supported, which use the `cms://taxonomy/categories/*` format:

- `cms://taxonomy/categories/electronics`
- `cms://taxonomy/categories/laptops`

These references link content items to taxonomy terms. The term metadata (display name, description, and usage) is stored in separate `_TaxonomyTerm` documents. The `categories` field contains only these key URIs; it does not include display names. To retrieve localized display names or descriptions, query the `_TaxonomyTerm` documents by key.

:::hint{type="info"}
**Note**
Only categories with the **Visible** flag set to `true` are indexed on content. Categories that are not visible are excluded from Graph indexing.
:::

## `_TaxonomyTerm` type

`_TaxonomyTerm` is a standalone type in the Graph schema. Each category is indexed as its own `_TaxonomyTerm` document that you query directly. Content items reference terms by key through `_itemMetadata.categories`; the term details, including localized display names, are on `_TaxonomyTerm`, not on `_itemMetadata`. The `_TaxonomyTerm` type defines the following fields:

| Field         | Type   | Description                                                                                                                                         |
| ------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `key`         | String | The category's unique identifier used in APIs and code.                                                                                             |
| `displayName` | String | The localized display name shown in the UI.                                                                                                         |
| `description` | String | An optional localized description that explains the category's purpose.                                                                             |
| `usage`       | String | Metadata that indicates the intended scope: `Public` for general use, `Internal` for internal classification. Both types are indexed and queryable. |
| `taxonomy`    | String | The taxonomy identifier, typically `categories` for category terms.                                                                                 |

### Language fallback

`_TaxonomyTerm` display names and descriptions are localized. When you query a term, `displayName` and `description` return the value for the language context of the query. The `key`, `usage`, and `taxonomy` fields are language-independent and stay constant across all languages.

Optimizely Graph does not fall back to the master language for other languages:

- **Master (default) language** – If a term has no translation, `displayName` and `description` return the value stored when the category was created.
- **Other languages** – If a term has no translation in the queried language, `displayName` and `description` return a dash placeholder (`–`), not the master-language value.

This behavior is shared by Admin mode, the API, and Optimizely Graph. Because Graph does not fall back across languages, implement your own fallback if you need a non-empty label in every language. For example, query the master language for any term that returns `–`, or treat `–` as a missing translation in your application.

## Query taxonomy terms

Taxonomy terms are indexed as separate `_TaxonomyTerm` documents. Query these documents directly to retrieve term metadata or filter by usage:

```graphql
query PublicTermsQuery {
  _TaxonomyTerm(
    where: {
      _metadata: {
        usage: { eq: "Public" }
      }
    }
  ) {
    items {
      _metadata {
        key
        displayName
        usage
      }
    }
  }
}
```

:::hint{type="info"}
**Note**
The `usage` field on `_TaxonomyTerm` documents is metadata that indicates intended scope. It does not restrict which categories are indexed on content or limit access. Developers choose whether to filter by usage based on application requirements.
:::

## Query content by category

Filter content by category using the URI reference format in the `_itemMetadata.categories` field:

```graphql
query SingleCategoryQuery {
  _Content(
    where: {
      _itemMetadata: {
        categories: {
          eq: "cms://taxonomy/categories/electronics"
        }
      }
    }
  ) {
    items {
      _metadata {
        key
        displayName
      }
      _itemMetadata {
        categories
      }
    }
  }
}
```

### Multiple categories

Use the `in` operator to find content tagged with any of several categories:

```graphql
query MultipleCategoriesQuery {
  _Content(
    where: {
      _itemMetadata: {
        categories: {
          in: [
            "cms://taxonomy/categories/electronics",
            "cms://taxonomy/categories/laptops",
            "cms://taxonomy/categories/mobile"
          ]
        }
      }
    }
  ) {
    items {
      _metadata {
        key
        displayName
      }
      _itemMetadata {
        categories
      }
    }
  }
}
```

### Combine with content type

Combine category filtering with content type filtering using the `_and` operator:

```graphql
query CategoryAndTypeQuery {
  _Content(
    where: {
      _and: [
        {
          _metadata: {
            types: { eq: "ProductPage" }
          }
        }
        {
          _itemMetadata: {
            categories: {
              eq: "cms://taxonomy/categories/electronics"
            }
          }
        }
      ]
    }
  ) {
    items {
      _metadata {
        key
        displayName
      }
      _itemMetadata {
        categories
      }
    }
  }
}
```
