PIM for Shopware 6 — Manual
This page bundles all functions of the PIM plugin for Shopware 6 at a glance. It serves as a compact reference — for detailed step-by-step guides with screenshots, please use the dedicated documentation pages for each area.
The PIM plugin is compatible with Shopware 6.5, 6.6 and 6.7.
System requirements
- Shopware: 6.5, 6.6 or 6.7
- PHP: 8.2 or newer
- Database: MySQL 8 or MariaDB 10.11
- Memory: Shopware's standard recommendation (256 MB+)
- Permissions: Shopware admin access as administrator role
Installation
Installation via Shopware Store or manual upload.
Via Shopware Store
- In Shopware admin, go to Extensions → Store and search for "PIM for Shopware"
- Load the plugin — it then appears under Extensions → My extensions
- Click Install, then Activate
Activate plugin
Activation registers ACL permissions, menu items in the sidebar, and builds the initial config matrix with defaults.
Open PIM
After activation the PIM menu item appears in the Shopware admin sidebar.
Config matrix
The config matrix is the central control element under Settings → System → PIM configuration. It controls:
- Visible fields in listing
- Editable fields in bulk-edit
- Active languages
- Default patterns for variant generator
- AI provider configuration
- Export settings for CSV
- Visible fields in the Quickview modal
Section order via drag-and-drop
The order of sections in the product detail view (master data, prices, media, SEO, properties, cross-selling, …) can be freely set via drag-and-drop. The same applies to the sections in the variant detail modal — both are configured in their own tabs of the config matrix.
Sections without active fields are automatically hidden — no empty accordion headers.
Gross/net toggles for all price types
All four price types can be shown/hidden independently for gross and net in the config matrix — both for master articles and variants:
- Sales price gross / net
- Purchase price gross / net
- List price / RRP gross / net
- Lowest 30-day price (Omnibus) gross / net
This allows pure gross maintenance, pure net maintenance, or mixed display — matching the shop's default tax logic or the maintainer's preference. Existing user configurations with the old single toggles remain valid via fallback logic — no migration required.
SEO URL system — two generators with a custom field as bridge
The SEO URL system works in two clearly separated steps that interact via a canonical custom field. The advantage: the final URLs come from Shopware's own SEO template and survive every reindex — even if Shopware fully reindexes the catalogue, your URLs stay intact.
Step 1 — "Generate URL in custom field" (token → field)
A token pattern (e.g. {mainCategoryPath}/{name}) is resolved variant- and language-accurately and written to the per-shop custom field staw_pim_canonical_<shop>. Available in two ways:
- Bulk run: button in the SEO tab opens the modal with channel/language selection (grouped by shop, accordions, "select/deselect all" per group) and progress display
- Per product: "Generate from pattern" button directly in master data and variants — fills the input field, then save normally
Available tokens as clickable chips: {name}, {productNumber}, {manufacturer}, {category}, {categoryPath}, {mainCategory}, {mainCategoryPath}, {options}, {properties}, {tags}, {ean} plus custom field tokens. The "field pattern" is its own input, separate from the step-2 Twig URL pattern.
Step 2 — "Generate SEO URLs" (Twig → database)
A Twig pattern reads the custom fields and is set as Shopware's native SEO URL template (seo_url_template) per sales channel. Reindexing runs through Shopware's own SeoUrlGenerator — Shopware generates the URLs itself from the custom field. Typical pattern for migrations:
{% if staw_url_product_detail %}{{ staw_url_product_detail|raw }}{% else %}{{ product.customFields.staw_pim_canonical_shop|raw }}{% endif %}
Migrated products keep their existing URL, new products use the field filled by step 1. Changed paths remain as 301 redirects — no SEO loss, no 404 for existing links.
Pattern editor with textarea, pencil and Twig syntax check
The pattern input is a textarea with auto-height — for long patterns with {% if %} conditions, the entire logic is visible. Per pattern:
- Pencil icon to edit — opens a large editor with variable chips
- Context-aware variable chips: token chips for step 1, official Shopware SEO Twig variables (product detail page) for step 2. Fields are inserted with
|rawdirectly - Live Twig syntax check: invalid Twig is flagged in red, save is blocked
- Mix warning: when
{tokens}and Twig ({% %}/{{ }}) appear in the same pattern, the editor warns — it doesn't work because Shopware slugifies the Twig output and strips token braces. Recommendation: pure Twig or pure token pattern
Custom pattern per shop — for both generators
The per-sales-channel pattern editor is available for both generators: step 1 can get its own token pattern per channel, step 2 its own Twig pattern. Shop patterns are a list: each shop with its own pattern shows name + pattern — editable via pencil or removable via trash. "Add pattern for shop" opens the editor modal with channel selection. Shops without their own pattern use the default pattern.
The generation modal
Both generators open a guided modal (in PIM CI with indigo accents):
- Pick sales channel + languages — all active channels, grouped by shop as cards with language accordions below (initially collapsed, nothing preselected). Per group "select/deselect all" with counter, plus a global "select all" button. Per channel badges: product count (only products actually visible in the channel, incl. variants) and missing-URL count.
- Options:
- "Keep old URLs as 301" — changed paths remain as redirects
- "Only generate missing SEO URLs" — existing/migrated URLs stay untouched
- "Remove all product URLs (reset)" — deletes all SEO URLs of the selected channels/languages (incl. Shopware's global detail URLs of that language) and rebuilds fresh. The other options visibly switch to OFF
- Preview — picks sample products that are visible in the channel and whose pattern resolves; up to three real example URLs, long URLs wrap, box is scrollable.
- Dry-run or generation — the dry-run shows the complete run without writing. Result cards colour-coded: new = green, change = blue, skipped = grey, warning = amber, error = red.
The progress bar shows a percentage with indigo gradient. Generation runs chunked — even tens of thousands of products without timeout.
Result report and conflicts
- Written / skipped / redirects as counters
- "N without rendered path" — products whose pattern outputs nothing (e.g. migration field and canonical field both empty). Makes it immediately clear why nothing was written
- Conflicts with product numbers instead of internal IDs. Paths already taken by another route (e.g. a category with the same slug) are cleanly skipped and reported as "path already taken elsewhere" — no duplicate-key abort
{mainCategoryPath}/{name}-{options}.Slug handling: umlauts, slashes, dots
- Umlauts and special characters (also in static pattern text like a literal "für/") are converted: ä→ae, ö→oe, ü→ue, ß→ss; "&" and spaces become the separator
- Slashes and dots are preserved — category names with "/" and article numbers/names with "." (e.g.
.htmlsuffixes) pass through unchanged - Twig
|rawautomatic: Shopware's SEO environment slugifies every Twig output (incl. slashes → "-"). Bare outputs of path fields automatically get|rawinjected in all generation paths - Preview and server generation behave identically — what the preview shows is what gets written
- Safety net: empty canonical field → fallback to the product name instead of an empty path
Language fallback for multi-language shops
Generation consistently uses the channel-/language-specific values (name, manufacturer, category, variant options). Fallback chain: requested language → parent language → system; empty or inherited translations are skipped. Applies to token and Twig generation — no accidental default language in foreign-language URLs.
Variants: unique URLs
Both generators process parent and variants. Inherited fields are resolved from the parent (incl. translated customFields with inheritance). The tokens {options}, {properties} and {tags} deliver language-translated values — a pattern like {mainCategoryPath}/{name}-{options} produces a unique URL per variant and language, no duplicate paths between variants of the same parent.
Deterministic category path
{mainCategoryPath}/{categoryPath} use the main category of the respective sales channel. If none is set, the fallback prefers the deepest assigned category (longest path) — deterministic instead of arbitrary. With an empty category.path column (indexer backlog after imports), the ancestor chain is reconstructed via parent_id.
…/config/seourl reopens the SEO tab.Default tax rate for new products
When creating a new product, the first tax rate from the Shopware system is automatically preselected (sorted by position ASC). Both taxId and taxRate are set.
Validation modal with scroll-to-section
Clicking Save while required fields are empty: instead of a wall of warning banners, a modal opens listing all errors. Clicking an error jumps directly to the relevant section.
Permissions (ACL)
The plugin registers a dedicated permission group "StawPim (products)" in the Shopware ACL system. Found under:
Settings → Users & Permissions → Roles → pick or create a role → group "Catalogues" → "StawPim (products)"
Four roles per user role
staw_pim.viewer— View: open the PIM area, list products, see the configuration matrix. Required for all other roles.staw_pim.editor— Edit: inline edit, bulk-edit, Quickview modal, AI text generation. Requires viewer.staw_pim.creator— Create: create new products, CSV import, variant generator. Requires viewer + editor.staw_pim.deleter— Delete: delete products. Requires viewer.
Role-based menu visibility
Without the "StawPim: View" permission, the menu items are not visible — dashboard, products and configuration matrix don't appear for unauthorised users at all. The automatic redirect from the Shopware default product list to the PIM list also respects the permission.
Feed Generator separately releasable
In the superadmin area "Features for normal users" there's a dedicated "Feed Generator" toggle — the Feed Generator button (in the product list) can be enabled/disabled for non-superadmin users independently of CSV import/export. Default: active. Superadmins always see the button.
product.viewer etc.) — now it's explicit. Admin roles continue to see everything.product.viewer, custom_field_set:read, sales_channel:read, language:read, product_stream:read, tag:read, delivery_time:read, unit:read, tax:read. editor grants product.editor, creator grants product.creator, deleter grants product.deleter — all via the official Shopware Privilege API.CSV import tab
Languages
PIM supports all languages configured in Shopware. Languages become visible/editable when marked as active in the config matrix.
Listing structure
The central product listing with filter bar, sortable column headers, data rows with variant expansion, footer toolbar and bottom save bar.
Filters with AND/OR
- 9 comparison modes: contains, does not contain, equals, not equal, starts with, ends with, is empty, is not empty, in list
- AND/OR logic — also nested
- Variant-aware — considers parent and variants
Configure columns
Visible columns are configurable per user — add via plus icon, reorder by drag-and-drop, resize by dragging the column edge.
Filter and column presets
Personal, shared and system presets. Activate via click, search via keyboard shortcut.
Inline editing
Fields can be edited directly in the listing by clicking. Stock, price, EAN, manufacturer number and weight inline editable — also for variants. After save the value is verified (read-back). If Shopware discards the value, a warning appears instead of falsely reporting success.
Keyboard shortcuts: Enter confirms, Esc cancels, Tab jumps to the next field.
Quickview modal
Directly from the listing, a Quickview modal can be opened per product — via the Quickview icon in the row. It shows the most important master data compactly for direct editing, without switching to the full detail view.
- Master data: SKU, name, EAN, MPN, active status
- Prices: gross/net, purchase price (gross + net), omnibus price
- Stock & shipping: stock, restock time, closeout, free shipping
- Order quantities: min/max/step
- Description as textarea
- SEO: meta title, meta description, keywords
Header layout
The modal header shows the variant name in front (large and dark), the SKU as secondary info behind it (small, grey) — same as the master variant view. This makes it immediately clear which variant is being edited during variant maintenance.
Uniform input fields
All input fields in Quickview follow the same structure: label on top, input below (42 px height) — consistent with the rest of the plugin. This applies to text fields, number fields, selects and toggles.
Expand all / collapse all
The modal header has an Expand all / Collapse all button — same as in the master data detail view. This opens or closes all accordions in one step.
Which fields are visible is controlled in the config matrix under "Quickview". Sections without active fields are hidden automatically.
Variant display
Variant products appear in the listing as a parent row. Click the plus icon to expand variants inline.
Image upload via drag & drop
In master data and in the variant view, the "Images/Media" section has a drag-&-drop zone (below the images). Drop files or click to open the file dialog — both work, with progress display.
- Uploads go to the Shopware media library (product folder) and are immediately assigned to the product
- The first image automatically becomes the cover if none is set yet
- Variants: an uploaded image becomes the variant's own image and overrides the inherited one. Removing the own image restores inheritance from the main product — both stay possible at any time
Approval workflow — "In progress" status
In addition to approve/reject/submit, there's the "In progress" status that editors can set themselves on a product — signalling to the team that someone's working on it. The status is reflected everywhere:
- Detail view: status badge + button to set it
- Product list: filter and status indicator (indigo)
- Settings: approval statistics count "In progress" too
Category assignment with chips
Assigned categories are listed as removable chips below the category tree (small × to remove). Instantly visible which categories are selected — without searching the tree.
Bulk-edit — overview
Allows changing fields on any number of selected products in a single operation. The operation runs in two phases (Snapshot + Apply) with live-progress indicator (counter, phase, ETA) — cancellable at any time.
Editable fields
Master data
- Name, description (per language)
- Meta title, meta description, keywords
- Manufacturer, EAN, SKU
- Product unit (piece, litre, kilogramm, metre, …) — dedicated bulk action
Prices and base price
- List price and RRP, tier prices
- Purchase price gross + net as two separate actions — the other value is automatically calculated via the product's tax class
- List price/RRP, lowest 30-day price (Omnibus)
- Base price (dedicated bulk action): content quantity + base unit
- Re-assign tax rate (gross stays, net is recalculated)
Stock and shipping
- Stock, delivery time, free shipping flag, weight, height, width, length
Sales channels and categories
- Sales channel visibility, main category, additional categories, cross-selling
Properties and custom fields
- Properties (assign and remove), custom fields of all types, tags
Complete filter display before every operation
Before every bulk-edit, the PIM shows all active filters from the selected preset as readable chips: manufacturer, categories, tags, properties, stock range, price range, weight range, date ranges, visibility, tax class, delivery time, dynamic product groups, sales channel, EAN status, closeout, free shipping and SEO meta status. IDs are resolved to readable clear names (e.g. sales channel name instead of UUID). "No filters active" is marked with red border — an intentional warning against accidental bulk operations.
Language selection for translatable fields
Translatable bulk fields show a language dropdown as soon as a value is entered. The value is set in the default language and additionally written to every selected language — one action, multiple languages.
Fields with language selection:
- SEO tab: meta title, meta description, SEO URL
- Custom fields: all custom fields marked as translatable in Shopware
- Shipping tab: packaging unit (singular/plural) — the only translatable field in the shipping section
Fields deliberately without language selection:
- Product unit / unit of measure: it's only a reference to a unit (piece, litre, kg) — the translation lives on the unit itself, not on the product
- Language-independent fields: price, stock, EAN, weight, manufacturer, active status, dimensions, delivery time — these exist only once per product
Data inheritance parent → variants
A dedicated bulk action transfers fields from the parent product to all its variants:
- Description and meta texts
- Apply tier prices to all variants
- Transfer cross-selling streams
- Pass images and media gallery to variants
- Take over SEO fields (title, description, keywords)
Snapshot & revert
Every bulk-edit stores a snapshot of the previous values automatically. Kept for 30 days. Overview under PIM → Snapshots.
Live preview
Before saving, a table shows current value, new value, diff marker and notes for non-editable fields.
CSV export
- Columns freely selectable
- Separator: comma, semicolon, tab
- Decimal separator: dot or comma
- Encoding: UTF-8 (with BOM option)
- Variant export per profile or globally
- Preset profiles: master data, SEO, images, prices & stock, properties & custom fields, cross-selling, translations
"Unit (name)" column
In addition to the unit ID (UUID), the product unit is exported as a readable name (e.g. "Litre", "Kilogramm", "Piece").
CSV import
Reads a file and creates new products or updates existing ones. Match by SKU, ID or EAN.
"Unit" auto-detection
The importer recognises both "Unit (name)" and "Produkteinheit" as column headers automatically.
Automatic lookups
Missing entities are created automatically. For variants, parent IDs can also be resolved via SKU or EAN.
Data type detection
- Boolean: 1/0, true/false, yes/no, active/inactive
- Date: ISO notation and German notation
- Number: comma or dot as decimal separator
- Array: pipe separator for multi-select
- JSON: for complex fields
Importable and exportable fields
Master data
productNumber— SKU (match key)name,description— per languageean,manufacturerNumber,manufacturertaxRate,active,markAsTopseller,isCloseout,shippingFree
Prices
price,price_net,listPrice,purchasePricetier_*,purchaseUnit,referenceUnitunitId/Unit (name)/Produkteinheit
Stock and shipping
stock,minPurchase,maxPurchase,purchaseStepsdeliveryTime,restockTimeweight,width,height,length
SEO, categories, variants, properties, custom fields, images, cross-selling, tags
metaTitle,metaDescription,keywordscategories,visibilitiesparentId,mainVariantId,optionsproperties,cf_*,cover,images,crossSellings,tags
Export only
createdAt,updatedAt, variant count,sales,ratingAverage,availableStock
Feed Generator — automatic URL feeds
Via the Feeds tab you provide automatically updated URL feeds — e.g. for Google Shopping, price comparison portals or ERP connections. A feed delivers product data under a unique URL with token authentication.
Create feed from template or profile
At the top of the Feeds tab there's the "Create feed from template / profile" selector. With this you activate a new feed in one click:
- Pick a built-in template — master data, prices & stock, SEO, images, variants, full export: A saved export profile with the matching field selection is created automatically, the feed activated, a token generated. The profile created from the template is named e.g. "Master data (Feed)".
- Pick an existing profile — Your own export profiles (saved in the export tab) can be activated directly as a feed.
Accordion list with status, chips and actions
All feeds and all custom export profiles appear as a compact list. Per row, you see:
- Name · renamable
- Status pill · "feed active" (green) or "no feed" (grey)
- Feed URL preview · the tokenised URL for active feeds
- Filter template chip · the chosen filter template or "no filter"
- Product count chip · determined live from the catalogue
- Pencil icon on the right (opens/closes the editor) and trash icon (deletes with confirmation)
Clicking the row reliably opens and closes the editor — a chevron on the right shows the state and rotates on opening. The trash button reacts separately (preventing accidental open/close).
Editor with renaming, mode, filter template
The expanded editor offers all configuration options per feed:
- Name field — rename the feed (must be unique; collision is rejected)
- Activate toggle — turn feed online/offline
- Mode — XML, CSV, TSV or JSON
- Filter template — selection from saved filter templates
- Feed URL — ready to copy
- Token — show or regenerate
Filter templates — what's applied, what's deliberately not
Instead of simple filter checkboxes, you pick a saved filter template in the feed — the same one you use in the listing or for bulk-edit.
Applied in the feed (reliably mappable server-side): active status, stock (min/max), manufacturer, category, sales channel.
Deliberately NOT applied in the feed: quality and completeness criteria (e.g. "missing images", "incomplete meta data", "no description", "SEO score < X"). These evaluations are calculated live in the listing and cannot be reliably mapped server-side in the feed context.
Migration of old feeds
Token and URL format
Each feed gets a unique token. The URL has the format:
https://your-shop.com/staw-pim/feed/{token}.xmlhttps://your-shop.com/staw-pim/feed/{token}.csvhttps://your-shop.com/staw-pim/feed/{token}.json
The regenerate token button creates a new token — the old URL becomes invalid. Useful when a feed link has been leaked publicly.
Backend & streaming performance
The FeedExportService is built for large catalogues. Four performance layers work together:
- DBAL streaming in 2,000-batches — data is emitted in chunks via PHP generator (
yield) instead of kept entirely in memory. Memory usage is independent of catalogue size. - Keyset pagination on
product_number(unique, indexed column) instead ofLIMIT/OFFSET— output time stays linear, even for very large catalogues. - gzip compression server-side via
gzencode(), when the client sendsAccept-Encoding: gzip. Feed CSVs compress ~80–90 % — drastically shorter transfer. - File mode for the largest catalogues: a scheduled task (every 15 min) atomically writes the file to
var/staw-pim-feeds/via Flysystem. On request, the pre-generated file is served — no DB load on every poll.
Additionally: @ini_set('memory_limit', '1024M') defensively in the endpoint — wide column selections with dozens of custom fields generate cleanly. Filter criteria (manufacturer, category, stock range) are applied server-side in SQL (incl. variant inheritance to the main article) — no data roundtrip into the Vue layer.
Variant generator — property selection
Creates variants from property combinations automatically. Visual selection of all properties with grouped values. Live preview of combinations.
Unified search
One single search at the top filters properties and options simultaneously. Type "red" and all property groups with the option "red" stay visible while matches on the right are highlighted.
Patterns for SKU and name & pattern accordions
Available variables
{base},{property:Colour},{counter},{counter:03}
Pattern accordions
Instead of raw inputs side by side: two dedicated accordions — one for the SKU, one for the variant name. Collapsed they show the current pattern as a code chip; expanded the input appears with clickable variable chips.
Variant matrix · Bulk prices and stock
The variant matrix lays all variants in a stacked table. Each cell offers price and stock for direct editing.
- Inline edit for price, stock, EAN, MPN
- Property sorting via drag-and-drop
- Optional: apply parent values to empty cells
Safe deletion
Checks for open orders.
- Mode "Safe" (recommended): Variants with open orders are not deleted, only deactivated
- Mode "Complete": All variants deleted
AI text generation — providers and models
- Anthropic Claude: Haiku 4.5, Sonnet 4.6, Opus 4.6 / 4.7
- OpenAI ChatGPT: GPT-4o Mini, GPT-4o, GPT-4.1 Mini, GPT-4.1
Set up API key
- Create API key at console.anthropic.com or platform.openai.com
- Enter in Config matrix → Translations
- "Test connection" button to verify
- Pick model and tone
- "Enable bulk" to activate in bulk-edit
What can be generated
- Description (HTML), meta title, meta description, keywords
Style templates
5 predefined: Professional, casual-modern, premium/luxury, technical, emotional.
Performance
- Browser-native virtualisation via
content-visibility: auto - Server-side filtering, lazy loading
- Bulk operations in batches with progress
- Minified bundle — ~23% smaller
Bulk edit & import: async indexing
- Queue indexing instead of sync: bulk-edit product writes default to Shopware's async queue indexing (header
use-queue-indexing) instead of synchronous in-request indexing. The write batch size is 25 (previously 10) — large bulk runs complete several times faster. Configurable viabulkIndexingBehavior:use-queue-indexing|disable-indexing|sync. - CSV import without full reindex: imports also use queue indexing — only the imported products are reindexed asynchronously. The previous full-catalogue reindex after every import is gone (only runs with
importIndexingMode = 'disable'). Modes:queue|disable|sync. - Batched requests: audit-log writes are saved as one batch every 600 ms (plus on page leave); bulk approvals run through a batch endpoint (one request per 200 products); bulk translations and approval/audit writes use
INSERT … ON DUPLICATE KEY UPDATE. - Batched variant deletion: one IN delete instead of one statement per variant, with per-ID error feedback and automatic single-delete fallback for e.g. foreign-key locks.
- Lazy snapshots: bulk-edit snapshots and undo data (potentially several MB) are loaded only once per session.
- Stale-response guard: rapid filter/page changes can no longer overwrite newer results with older ones.
Diagnostics & stability
- Session error log: the last 50 errors are kept in
window._stawPimErrLog— previously silent error paths (audit flush, batch approvals, snapshot loading) now log failures, so problems are diagnosable via the browser console even without server log access. - Internal test suite: lightweight test runner (no PHPUnit needed) checks SEO fallback logic, snippet consistency de-DE ↔ en-GB and version consistency on every release.
Troubleshooting
Listing does not load
Clear cache, check browser console, check PHP memory limit (512 MB recommended).
CSV import fails
Check encoding (UTF-8), separator, PHP limits.
AI generation fails
Test API key. Anthropic: top up credit. OpenAI: check billing status.
Contact & support
- Feature request: via the form
- Frequent questions: FAQ
- Email support: pim@stoneandwater.online
- Vendor: Stone & Water — Schöppingen, Germany