# Reference Architecture: Multi-Brand and Multi-Site

> Source: https://agilitycms.com/docs/developers/reference-architecture-multi-brand

Use this architecture when one organization runs several websites: brands, product lines, regions or microsites. The sites usually share some things (a team, a design system, a content model, some content) and must keep others apart (domains, navigation, sometimes editors and approvals).

Agility supports two main shapes. Most organizations use one of them, or a mix: a shared instance for brands that work together, and separate instances where a brand needs its own team and rules. To choose between them, see [Choose Your Tenancy Model](/docs/developers/choose-your-tenancy-model).

## Shape A: one instance, one sitemap per site

Each site is a sitemap in the same instance. The sitemaps share page models, components and content models, and each one has its own pages, its own domains and its own preview URL. See [Using Agility for Multiple Sites](/docs/overview/using-agility-cms-for-multiple-sites).

### Components

| Component | Owned by | Role |
| --- | --- | --- |
| One Agility instance | Agility (you configure it) | Shared models and components, one sitemap per site, content in folders per site plus a shared folder |
| Content Fetch API | Agility | One set of API keys for the instance |
| One front-end codebase | You | Shared component library, with brand themes |
| One or more deployments | You | One deployment per site, or one deployment that picks the sitemap by domain |
| Revalidation endpoint | You | Receives the instance's webhooks and clears caches for every site that uses the changed content |

### Data flow

| Step | From | To | What happens |
| --- | --- | --- | --- |
| 1 | Browser | Your host | The request arrives on a brand's domain |
| 2 | Your app | Its configuration | Maps the domain to that site's sitemap (channel) name |
| 3 | Your app | Content Fetch API | Reads `sitemap/flat/{channel}` for that site, then the page and its content |
| 4 | Agility | Your webhook endpoint | One webhook per change, for the whole instance |
| 5 | Your endpoint | Each site's cache | Content items can be used by any site, so clear the item's tag in every site's cache. A page belongs to one sitemap |

### What to watch

- **Content lists are instance-wide.** Any site can use any content. Organize lists in folders per site and name site-specific components and models clearly (for example "Global Slider" and "Brand B Slider") so editors know what belongs where.
- **The API is not scoped per sitemap.** A fetch key can read all published content in the instance, for every site. If one brand's published content must not be readable with another brand's key, use separate instances.
- **Permissions are per page and per content list,** not per site. Users with access to an instance can see all of its content and pages listed, even where they can't open or edit them. See [Roles and Permissions Matrix](/docs/owners-admins/roles-and-permissions-matrix).

## Shape B: one instance per site, with an optional content hub

Each site gets its own instance, completely separate in content, assets, editor team, security and workflow. Shared content lives in one more instance, a content hub, that every site reads from. See [Building a Content Hub](/docs/overview/building-a-content-hub).

### Components

| Component | Owned by | Role |
| --- | --- | --- |
| One instance per site | Agility (you configure them) | That site's pages, content, users and workflow |
| Hub instance (optional) | Agility (you configure it) | Content shared by every site, for example products, locations, legal text |
| Content Fetch API, per instance | Agility | Separate keys per instance |
| Front-end codebases | You | A shared component library and a deployment per site |
| Revalidation endpoints | You | One webhook per instance, plus hub webhooks fanned out to every site |

### Data flow

| Step | From | To | What happens |
| --- | --- | --- | --- |
| 1 | Brand site | Its own instance | Pages and brand content, with that instance's fetch key |
| 2 | Brand site | Hub instance | Shared content, with the hub's fetch key |
| 3 | Hub | Every brand site's webhook endpoint | A change to shared content clears the matching tags on every site |
| 4 | CI pipeline | Brand instances | The [Agility CLI](/docs/developers/cli) syncs models and content from a source instance to targets, if you keep models in step that way |

### What to watch

- **Nothing links across instances.** A brand instance can't hold a linked-content field that points into the hub. Store the hub item's ID in a field and read the item from the hub at render time.
- **Keeping models in step is your job.** Models and components are defined per instance. The CLI `sync` command copies them, but synced items get new content IDs on the target, and a blank target is the reliable case. See [CLI - CI/CD Integration Guide](/docs/developers/cli-ci-cd-integration-guide).
- **Each instance is a subscription.** Separate instances, and additional sitemaps, affect licensing. Check the impact with Agility before you choose.

## Caching

Cache per site. Include the site (or sitemap channel) in every cache key and tag, so one site's sitemap or page entry can never be served on another site's domain. For content shared between sites, tag by content ID so one webhook clears it everywhere.

## Preview

Give each sitemap its own preview deployment in **Settings > Sitemaps**. Agility opens the preview URL of the sitemap the page belongs to. In Shape B, each instance has its own deployments and its own security key for validating preview requests.

## Failure modes

| What goes wrong | Effect | Design for it |
| --- | --- | --- |
| A cache key without the site in it | One brand's navigation or page shows on another brand's domain | Include the site or channel in every key and tag |
| A shared item changes but only one site is revalidated | Brands show different versions of the same content | Fan the webhook out to every site that can use the item |
| An editor uses another brand's content list | Off-brand content on a live page | Folders, naming, item-level permissions, and approvals for each site's lists |
| A burst of builds for many sites at once | `429` responses during builds | Stagger builds and limit concurrency. See [Handle Rate Limits and Outages Gracefully](/docs/developers/handle-rate-limits-and-outages) |
| Brand instances drift apart (Shape B) | A component works on one site and breaks on another | Treat one instance as the source of models and sync from it in CI |

## Related

- [Choose Your Tenancy Model](/docs/developers/choose-your-tenancy-model)
- [Using Agility for Multiple Sites](/docs/overview/using-agility-cms-for-multiple-sites)
- [Reusing Content across Multiple Web Properties](/docs/editors/reusing-content-across-multiple-web-properties)
- [Choosing a Localization Strategy](/docs/developers/choosing-a-localization-strategy)
- [Reference Architectures](/docs/developers/reference-architectures)
