# Namespaces

Group keys into namespaces for code-splitting, organization and ownership: how they map to CDN files, how to create them, and how to move keys.

Canonical: https://comvi.io/docs/platform/namespaces

A namespace is a group of keys inside a project. Every key belongs to exactly one, every
`(language, namespace)` pair becomes one JSON file on the CDN, and every project starts with
a `default` namespace.

```text
https://cdn.comvi.io/<project-token>/fr.json             # default namespace
https://cdn.comvi.io/<project-token>/checkout/fr.json    # checkout namespace
```

## When to split

| Problem | How a namespace fixes it |
|---|---|
| Every page loads every translation | Load only the namespaces the current screen needs |
| Unrelated areas are edited by different people | Give each area its own namespace so filters and hand-offs stay clean |
| Keys from different surfaces clash or make search noisy | Split by surface (`marketing`, `app`, `emails`) |

Stay on `default` until one of these pinches. Aim for a handful of namespaces, not hundreds,
and keep a `common` one for strings every page loads.

## How they behave

- Keys are unique **within a namespace**. `nav.home` in `common` and `nav.home` in `emails`
are two different keys.
- Imports, exports and Content Deploy each let you pick a subset of namespaces.
- Permissions are project-scoped, not namespace-scoped. A member who can see a project sees
all of its namespaces; for strict editorial boundaries, use separate projects.
- Lookups do not cross namespaces at runtime: a key is found in the namespace you asked for,
or in the same namespace under a fallback locale, and nowhere else.

## Common layouts

```text
common     shared UI (Save, Cancel, error banners)
auth       login, signup, password reset
dashboard  the main product surface
billing    plans, invoices, checkout
emails     transactional email templates
```

One namespace per top-level feature or route group fits SPAs that already code-split routes.
One per consumer (`marketing`, `app`, `mobile`, `emails`) fits a project that spans very
different surfaces. One per owning team (`core-product`, `legal`, `marketing`) makes the
hand-off obvious even though roles cannot enforce it.
[Monorepo with shared namespaces](/docs/platform/recipes/monorepo-namespaces) works one
layout through in detail.

## Create a namespace

1. Open the namespace selector on the **Translations** page.
2. Choose **Create new namespace...** at the bottom of the list.
3. Name it in the **Add Namespace** dialog: lowercase, short, hyphenated if it needs two
   words (`user-settings`, not `UserSettings`).

The name lands in CDN URLs and build pipelines. The dashboard cannot rename or delete a
namespace; the REST API can. `PATCH` renames one, and a name already in use returns
`NAMESPACE_ALREADY_EXISTS`. `DELETE` removes an empty one; a namespace that still holds keys
returns `NAMESPACE_NOT_EMPTY`, and `default` returns `CANNOT_DELETE_DEFAULT`. Deleting a
namespace never deletes keys. Without the API, move the keys to a new namespace and stop
using the old one.

## Move keys between namespaces

Select keys on the Translations page, open **More** in the selection bar, and choose
**Change Namespace**. Values, history and comments move with the keys. Keys whose name
already exists in the target namespace are skipped, and the toast reports how many hit a
conflict; rename those and move them again.

> **Consumers pin the old namespace**
>
> An app that hard-coded the old namespace stops finding the moved keys. Update loader
> configs and build-time pulls before the next deploy.

## Next steps

- [Translations](/docs/platform/translations): Edit keys and values inside a namespace.
- [Content Deploy / CDN](/docs/platform/cdn): How namespaces map to CDN URLs.
- [Import & export](/docs/platform/import-export): Import or export one namespace at a time.
- [Consume translations](/docs/platform/consume-translations): Load only the namespaces a screen needs.
