> ## Documentation Index
> Fetch the complete documentation index at: https://spreecommerce.org/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Slugs

> SEO-friendly URL identifiers for products, categories, and other resources

## Overview

Spree generates SEO-friendly URL slugs for resources like products, categories, and stores. Instead of accessing resources by ID, you can use clean, readable URLs based on resource names.

Both the Store API and Admin API accept slugs or IDs interchangeably for resource lookups.

<CodeGroup>
  ```typescript SDK theme={"theme":"night-owl"}
  // Both work — slug or ID
  const product = await client.products.get('spree-tote')
  const product = await client.products.get('prod_86Rf07xd4z')

  // Categories use permalink slugs
  const category = await client.categories.get('clothing/shirts')
  ```

  ```bash cURL theme={"theme":"night-owl"}
  # By slug
  curl 'https://api.mystore.com/api/v3/store/products/spree-tote' \
    -H 'Authorization: Bearer pk_xxx'

  # By ID
  curl 'https://api.mystore.com/api/v3/store/products/prod_86Rf07xd4z' \
    -H 'Authorization: Bearer pk_xxx'
  ```
</CodeGroup>

## Slug Generation

Slugs are automatically generated from resource names:

| Input                    | Generated Slug           |
| ------------------------ | ------------------------ |
| `Spree T-Shirt`          | `spree-t-shirt`          |
| `Café & Restaurant`      | `cafe-and-restaurant`    |
| `Summer Collection 2025` | `summer-collection-2025` |

If a slug already exists, Spree appends the SKU or a unique identifier to ensure uniqueness.

## Models with Slugs

| Resource | Slug Column | Translatable | Hierarchical |
| -------- | ----------- | :----------: | :----------: |
| Product  | `slug`      |      Yes     |      No      |
| Category | `permalink` |      Yes     |      Yes     |
| Store    | `code`      |      No      |      No      |
| Post     | `slug`      |      Yes     |      No      |

### Category Permalinks

Category slugs include the full parent path, making them hierarchical:

```
clothing                       → "clothing"
clothing/shirts                → "clothing/shirts"
clothing/shirts/t-shirts       → "clothing/shirts/t-shirts"
```

When a parent category is renamed, all child permalinks update automatically.

## Slug History

When a slug changes (e.g., a product is renamed), Spree preserves the old slug. Requests using old slugs still find the resource, enabling:

* **SEO continuity** — no broken links when names change
* **Bookmark compatibility** — saved URLs keep working
* **Graceful URL migration** — old links resolve automatically

## Internationalization

Products, categories, and posts support localized slugs — a different slug per locale:

<CodeGroup>
  ```typescript SDK theme={"theme":"night-owl"}
  // English
  const product = await client.products.get('red-shoes')

  // French (with locale header)
  const product = await client.products.get('chaussures-rouges', {
    locale: 'fr',
  })
  ```

  ```bash cURL theme={"theme":"night-owl"}
  # English
  curl 'https://api.mystore.com/api/v3/store/products/red-shoes' \
    -H 'Authorization: Bearer pk_xxx'

  # French
  curl 'https://api.mystore.com/api/v3/store/products/chaussures-rouges' \
    -H 'Authorization: Bearer pk_xxx' \
    -H 'X-Spree-Locale: fr'
  ```
</CodeGroup>

Slugs are unique within the same locale but can be duplicated across different locales.

## Reserved Words

Spree prevents certain words from being used as slugs to avoid route conflicts: `new`, `edit`, `index`, `login`, `logout`, `admin`, and others.

## Related Documentation

* [Products](/developer/core-concepts/products) — Product catalog
* [Translations](/developer/core-concepts/translations) — Multi-language content
* [Querying](/api-reference/store-api/querying) — API resource lookup
