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

# Shopware

<div style={{ display: "flex", gap: "1.75rem", alignItems: "flex-start", marginTop: "0.5rem", marginBottom: "1.75rem" }}>
  <img src="https://mintcdn.com/frontic/zwqcoY8MRIYLLSYv/images/connectors/shopware.svg?fit=max&auto=format&n=zwqcoY8MRIYLLSYv&q=85&s=175106539b1abfb9d8b8623a87ea543f" alt="Shopware" style={{ height: "56px", width: "auto", flexShrink: 0, marginTop: "0.25rem" }} width="24" height="24" data-path="images/connectors/shopware.svg" />

  <div>
    The Shopware connector pairs your Shopware 6 store with Frontic via a **Frontic plugin you install in your Shopware admin**. The plugin handles the hand-off both ways: it pushes catalog and content changes to Frontic via webhooks, and at install time it calls back into Frontic to provision a project that mirrors your store's sales channels, currencies, and languages — feeds, storages, and syncs included.
  </div>
</div>

<div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: "0.75rem", marginBottom: "2rem" }}>
  <div style={{ padding: "0.75rem 1rem", border: "1px solid var(--card-border, rgba(0,0,0,0.08))", borderRadius: "0.625rem" }}>
    <div style={{ display: "flex", alignItems: "center", gap: "0.5rem", fontSize: "0.75rem", textTransform: "uppercase", letterSpacing: "0.04em", opacity: 0.6, marginBottom: "0.25rem" }}>
      <Icon icon="key" iconType="solid" /> Auth
    </div>

    <div style={{ fontSize: "0.875rem", fontWeight: 500 }}>API Key + Secret</div>
  </div>

  <div style={{ padding: "0.75rem 1rem", border: "1px solid var(--card-border, rgba(0,0,0,0.08))", borderRadius: "0.625rem" }}>
    <div style={{ display: "flex", alignItems: "center", gap: "0.5rem", fontSize: "0.75rem", textTransform: "uppercase", letterSpacing: "0.04em", opacity: 0.6, marginBottom: "0.25rem" }}>
      <Icon icon="arrows-rotate" iconType="solid" /> Update method
    </div>

    <div style={{ fontSize: "0.875rem", fontWeight: 500 }}>Trigger</div>
  </div>

  <div style={{ padding: "0.75rem 1rem", border: "1px solid var(--card-border, rgba(0,0,0,0.08))", borderRadius: "0.625rem" }}>
    <div style={{ display: "flex", alignItems: "center", gap: "0.5rem", fontSize: "0.75rem", textTransform: "uppercase", letterSpacing: "0.04em", opacity: 0.6, marginBottom: "0.25rem" }}>
      <Icon icon="boxes-stacked" iconType="solid" /> Resources
    </div>

    <div style={{ fontSize: "0.875rem", fontWeight: 500 }}>Products, Categories, CMS</div>
  </div>
</div>

## What you get

<CardGroup cols={3}>
  <Card title="Products" icon="boxes-stacked">
    Every variant as its own record, parent links preserved, prices resolved to the currency.
  </Card>

  <Card title="Categories" icon="folder-tree">
    Power category pages, attach category context to other records, drive navigation.
  </Card>

  <Card title="CMS Pages" icon="file-lines">
    Shopping Experiences and Landing Pages with their section/block/element structure intact.
  </Card>
</CardGroup>

The Shopware connector follows the standard integration model — see [how integrations work](/connectors/overview) for the shape of Connection, Channels, and Data Feeds. This page covers the Shopware-specific pieces: the plugin install, the onboarding hand-off, the channel and feed details, and the data shape after normalization.

## Install and setup

The plugin is the same either way — pick how you'd like to load it into Shopware, then run the onboarding to provision your Frontic project.

### Install the plugin

<Tabs>
  <Tab title="From the Shopware Store">
    <Steps>
      <Step title="Open the Store" icon="store">
        In Shopware admin, go to **Extensions → Store**. You'll need a Shopware Account connected — Shopware prompts you to connect one if you haven't.
      </Step>

      <Step title="Find the Frontic plugin" icon="magnifying-glass">
        Search for **Frontic** in the store and open the listing.
      </Step>

      <Step title="Install and activate" icon="toggle-on">
        Install and activate the plugin in Shopware's extension overview.
      </Step>
    </Steps>
  </Tab>

  <Tab title="Manual upload">
    <Steps>
      <Step title="Download the plugin" icon="download">
        Grab the latest release ZIP: [Frontic plugin for Shopware 6](https://github.com/frontic/shopware6-plugin/releases/latest).
      </Step>

      <Step title="Upload it to your Shopware admin" icon="upload">
        In Shopware admin, go to **Extensions → My extensions** and click **Upload extension**. Pick the ZIP you just downloaded.
      </Step>

      <Step title="Install the plugin" icon="toggle-on">
        Install and activate the plugin in Shopware's extension overview.
      </Step>
    </Steps>
  </Tab>
</Tabs>

### Run the onboarding

With the plugin active, you can start the onboarding wizard on the plugin's configuration page to provision your Frontic project end-to-end: it sets up the integration's connection settings, creates one **Channel** per Shopware sales channel (with the matching currencies and translations), creates Data Feeds for Products, Categories, and CMS Pages, and seeds matching Data Storages and Data Syncs. On the project side it also creates one **scope** per sales channel, one **region** per channel/currency pair, and one **locale** per channel language.

Before any of that runs, the wizard tests the Shopware connection from Frontic — if the keys are wrong or the host can't be reached, it stops on a **Connection-Test failed** screen instead of provisioning a broken setup. See [Troubleshooting the onboarding](#troubleshooting-the-onboarding) for the failure modes.

<Steps>
  <Step title="Open the onboarding" icon="rocket">
    In **Extensions → My extensions**, click the Frontic row's three-dot menu and choose **Configure**. Start the Onboarding wizard with the **Start Onboarding** button.
  </Step>

  <Step title="Sign in to Frontic" icon="user">
    The wizard opens a Frontic auth window. Sign in or create the account that should own the new project, then approve the plugin's permission request.
  </Step>

  <Step title="Confirm the project layout" icon="sitemap">
    Review the proposed scopes, regions, currencies, and locales mapped from your sales channels, then click **Create project**.
  </Step>

  <Step title="Done — the first sync starts" icon="check">
    The plugin creates Data Feeds for products, categories, and CMS pages and triggers an initial backfill. From here on, Shopware changes flow to Frontic on every entity write.
  </Step>
</Steps>

### Troubleshooting the onboarding

When the connection check fails, the wizard shows a **Connection-Test failed** screen with the message Shopware returned and a failure type. Match it against the table below to find the fix — once the test passes, the wizard continues to provisioning automatically.

| Failure                              | What it means                                                            | How to fix it                                                                                                                                |
| ------------------------------------ | ------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------- |
| `invalid_credentials` (401)          | Shopware rejected the keys the wizard generated.                         | Restart the wizard so it can issue fresh keys. If that still fails, fall back to the [manual Integration account](#without-the-plugin) flow. |
| `insufficient_permissions` (403)     | The Integration account exists but is missing read permissions.          | Open the Integration in Shopware and assign the role described in [Create an Integration account in Shopware](#without-the-plugin).          |
| `api_not_found` (404)                | The host URL doesn't point at the Shopware Admin API.                    | Use the Shopware admin URL (the one you use to log in), not a storefront URL or a custom subpath.                                            |
| `network_error`                      | Frontic couldn't reach the host from the public internet.                | Make the Shopware host publicly reachable. Local-only or IP-allowlisted instances can't be onboarded automatically.                          |
| `rate_limited` (429)                 | Shopware throttled the verification request.                             | Wait a moment and retry the wizard.                                                                                                          |
| `shopware_unavailable` (502/503/504) | Shopware returned a temporary error — often a deploy or upstream outage. | Wait until the instance is healthy, then retry.                                                                                              |

### Without the plugin

If you can't install the plugin in your Shopware environment — for example a managed setup where you can't load custom extensions — you can connect manually using a Shopware **Integration** account.

<Warning>
  Without the plugin, Frontic will not be notified of any data changes. You have to trigger updates manually.
</Warning>

<Accordion title="Create an Integration account in Shopware">
  <Steps>
    <Step title="Open Integrations" icon="list">
      In Shopware admin, go to **Settings → System → Integrations** and click **Add integration**.
    </Step>

    <Step title="Name the integration" icon="pen">
      Enter `frontic-sync` (or anything you'll recognize later).
    </Step>

    <Step title="Assign read permissions" icon="shield">
      Assign a role with **read** access on: Product, Category, Sales channel, Currency, Language, Media, Manufacturers, Properties, Shopping Experiences, Landing Pages, Delivery times, Essential Characteristics, Scale Units, Tags, Tax. Plus read on the `*_translation` detailed privileges for product, media, manufacturer, property group, property group option, unit, delivery time, cross-selling, and feature set.
    </Step>

    <Step title="Copy the access keys" icon="key">
      Save the integration, then copy the **Access Key ID** (`SWIAMG…`) and **Secret Access Key** (`dXhZQ2…`) — you'll paste them into Frontic next.
    </Step>
  </Steps>

  In Frontic admin, **Integrations → Add → Shopware** asks for the host URL plus those two keys. With manual setup, you also build out the project (scopes/regions/locales) yourself in Project Settings — see [Multi-Channel & Multi-Region](/commerce-concepts/multi-channel-region) — and create channels and feeds manually as covered below.
</Accordion>

## Connection settings

<ParamField path="Name" type="string" required>
  Display name for the integration in Frontic. Use something recognizable when you have multiple Shopware integrations (e.g. `Shopware Production`, `Shopware Staging`).
</ParamField>

<ParamField path="Host URL" type="string" required>
  The URL of your Shopware instance, e.g. `https://shopware.demo-shop.com`. The connector talks to the Admin API at this host.
</ParamField>

<ParamField path="API Key" type="string" required>
  The **Access Key ID** of a Shopware Integration account (`SWIAMG…`). Created automatically by the plugin onboarding, or manually via Shopware **Settings → System → Integrations**.
</ParamField>

<ParamField path="API Secret" type="string" required>
  The **Secret Access Key** paired with the API key (`dXhZQ2…`). Stored encrypted and redacted in logs.
</ParamField>

The settings panel shows a **Connection Status** indicator. When the connection is broken, it surfaces the reason returned by the Shopware API (with sensitive details redacted) — so you can tell whether credentials are missing, the host is unreachable, or the keys were rejected. Update credentials here and re-test after rotating keys in Shopware.

## Channels

A Shopware channel in Frontic maps a **Shopware sales channel** to the currencies and translations Frontic should pull from it. The plugin onboarding seeds one Frontic channel per sales channel; you can add more from **Channels → Add**.

<ParamField path="Channel Name" type="string" required>
  A label for the channel in Frontic (e.g. `Storefront`, `Headless`, `Wholesale`).
</ParamField>

<ParamField path="Available Translations" type="multiselect" required>
  Locale keys this channel covers. Validated against the languages the chosen Shopware sales channel actually serves; populated from the connector's reference data.
</ParamField>

<ParamField path="Fallback Translation" type="select" required>
  The locale used as fallback when a record is missing a value in another translation.
</ParamField>

<ParamField path="Sales Channel" type="select" required>
  Which Shopware sales channel this Frontic channel reads from. The dropdown is populated from your Shopware instance — hit **Refresh** if you've added a new sales channel since the integration last fetched.

  This selection also narrows product ingestion: a product needs a visibility entry for one of the sales channels selected across the integration's channels to be fetched. See [Product visibility](#product-visibility).
</ParamField>

<ParamField path="Currencies" type="multiselect" required>
  Currencies (from the chosen sales channel) the connector pulls in. Product prices are pre-filtered to these currencies before they reach the Data Sync.
</ParamField>

The **Refresh** button on the channel detail re-fetches sales channels, languages, and currencies from your Shopware instance — use it after you've added one of those on the Shopware side. For how channels become project scopes and locales at sync time, see [Data Sync mapping in the overview](/connectors/overview#data-syncs-mapping-integration-to-project).

## Data Feeds

The Shopware connector exposes three feed types:

| Feed           | What it pulls                                   | Webhook events                                                                         |
| -------------- | ----------------------------------------------- | -------------------------------------------------------------------------------------- |
| **Products**   | Catalog including all variants and their prices | `product.written`, `product.deleted`                                                   |
| **Categories** | The category tree, including SEO and assets     | `category.written`, `category.deleted`                                                 |
| **CMS Pages**  | Shopping Experiences and Landing Pages          | `cms_page.written`, `cms_page.deleted`, `landing_page.written`, `landing_page.deleted` |

The standard **Settings → Updates → Schema** setup wizard applies — see [Data Feeds in the overview](/connectors/overview#data-feeds). For Shopware specifically:

* **Updates step** — Shopware supports the **Trigger** update method (the plugin pushes webhooks). Scheduled polling and the Ingest API are not used; the plugin's webhook stream is the source of real-time updates.
* **Manual refresh** — every Shopware feed exposes a **Refresh** action that re-runs the feed against the source. Use it when something changed on the Shopware side that didn't reach Frontic, or to recover from a webhook gap. Configuration changes — Value Composer, storage schema, sync mappings — don't need a refresh; they revalidate automatically.

### Product visibility

The Shopware integration only ingests products with a visibility entry for at least one of the sales channels selected across its channels. Products with no visibility — or visible only in sales channels you haven't selected on any channel — won't reach Frontic.

The filter applies to every product read: full backfills, parent resolution for variants, and incremental batch fetches. A product that drops out of every selected sales channel in Shopware is reconciled away on the next feed run.

If a product is missing in Frontic, open it in Shopware admin and check the **Visibilities** tab — it needs an active entry for one of the sales channels selected on a channel in this integration.

## What the data looks like

### Associations pulled along

The connector fetches more than just the entity's own fields — it pre-loads the associations a typical storefront needs, so your Data Sync doesn't have to chase them.

<CardGroup cols={2}>
  <Card title="Product associations" icon="boxes-stacked">
    `categoriesRo`, `cover.media`, `crossSellings`, `crossSellingAssignedProducts`, `deliveryTime`, `featureSet`, `manufacturer.media`, `prices`, `media`, `options.group`, `properties.group`, `tags`, `unit`, `visibilities`.
  </Card>

  <Card title="Category associations" icon="folder-tree">
    `media`, `tags`.
  </Card>
</CardGroup>

Need an association that isn't on this list? [Get in touch](mailto:support@frontic.com).

### Variants

A product with options is denormalized: the parent record carries the shared fields, each variant is a separate record linked back via `parentId`. Either side can drive a [Detail Block](/api-builder/blocks) — product-level for grids, variant-level for cart and detail views. See [Product Models](/commerce-concepts/product-models) for the full picture.

### Currency-resolved prices

For products, the connector pre-filters the `prices` array to the currencies declared on the channel and stamps every price element with `currencyCode` and `currencyPrecision`. Map those into the [Price composite](/reference/storage-field-types#composites) and you're done — no per-region price-picking logic in your Value Composer needed.

### Translations

All translatable fields are resolved at the connector level for every locale on the channel. Use the **base field** in your Data Sync (`name`, `description`) — not `translated.name`. Frontic's Request Context picks the right localized value at response time. For categories, breadcrumb arrays are also de-indexed so the translated breadcrumb path is a clean list rather than a `0:..., 1:...` map.

### Auto-delete reconciliation

When a feed runs (refresh, full backfill), the connector diffs Shopware's current state against what Frontic has on the feed and emits **deletes** for products, categories, or CMS pages that have disappeared on the Shopware side. Your storage doesn't accumulate orphan records when items are removed in Shopware.

### Category relations

From the `categoriesRo` association, the connector also extracts a flat list of category IDs and stamps them onto the feed record under the reserved `$rel` namespace as `$rel.categoryIds`. Category-link blocks (or any sync that just needs the IDs without the full association payload) can map this directly in the Value Composer — no need to walk `categoriesRo` to pluck IDs out yourself.

## Good to know

* **Products are scoped by sales channel visibility.** Only products visible in one of the sales channels selected across the integration's channels are fetched — see [Product visibility](#product-visibility).
* **No scheduled polling.** Shopware sync relies entirely on plugin webhooks. If the plugin is disabled or your instance can't reach Frontic, changes won't be pushed — fix connectivity, then hit **Refresh** on each feed to backfill.
* **Webhook delivery retry is on the plugin side.** The Frontic plugin queues outbound webhooks in Shopware and retries delivery — events older than Shopware's retention can't be replayed and need a manual feed Refresh to reach Frontic.
* **Batch size.** Records are fetched in batches to keep Shopware's API response size small enough for catalogs with large associations.

## Related

<CardGroup cols={2}>
  <Card title="Product Models" icon="boxes-stacked" href="/commerce-concepts/product-models">
    How Shopware's parent products and variants compose at the API layer.
  </Card>

  <Card title="Shopify" icon="shopify" iconType="brands" href="/connectors/shopify">
    Shopify's commerce-platform connector — direct API, four resource types.
  </Card>
</CardGroup>
