Skip to content

Commerce Foundations is our pre-built Craft Commerce store. See what it includes

Craft CMS plugins

Product Feeds

Build auto-updating product feeds for shopping and social platforms from Craft Commerce variants, Craft entries, or custom sources.

Schema

The plugin installs one table, defined in src/migrations/Install.php.

The plugin stores feeds in the database, not project config. Uninstalling the plugin drops the table.

productfeeds_feeds#

One row per feed. A feed belongs to one site. The row stores only the last build; there is no history table.

Column Type Notes
id integer Primary key.
name string What the admin called the feed.
handle string Unique per site, so the same handle can repeat on each of a store’s sites. Appears in the feed URL.
platform string(16) google, klaviyo, meta, microsoft, pinterest, or tiktok.
source string variants, entries, or a custom source’s handle.
siteId integer Foreign key to sites.id, ON DELETE CASCADE. Indexed.
sourceIds text JSON. Product type IDs for a variant feed, sectionId:entryTypeId pairs for an entry feed. Empty means every product type or section with a public URL. Ignored on a custom source’s feed.
fieldMapping mediumtext JSON, keyed by attribute: {"source": "...", "default": "...", "twig": "..."}. A full mapping can exceed TEXT’s 64 KB.
filterCondition mediumtext JSON. A serialized ElementCondition config, applied to the source query. Always empty on a custom source’s feed.
imageEngine string none, craft, imagerx, or smallpics. Default: none.
imageTransform string Handle of a named Craft transform. Null for a custom size.
imageWidth smallint unsigned Null when a named transform sets the size.
imageHeight smallint unsigned Null when a named transform sets the size.
imageFit string crop or fit. Default: crop.
token string(32) Unique, indexed. The only credential on the public feed route, generated by Craft’s CSPRNG. Rotating it generates a new token and moves the artifact.
enabled boolean Default: true.
sortOrder smallint unsigned The order the feeds index lists them in.
lastBuildStatus string(16) pending, building, ok, or failed. Default: pending.
lastBuildStartedAt datetime UTC. A build stuck in building past the build timeout is treated as stalled and queued again.
lastBuildFinishedAt datetime UTC. What the build interval is measured from.
lastBuildItemCount integer Items the last build wrote to the feed.
lastBuildSkippedCount integer Items it excluded for a blank required attribute or a duplicate id.
lastBuildBytes bigint Size of the gzipped artifact. The compressed route returns 404 until a build sets this column.
lastBuildBytesUncompressed bigint What the uncompressed route serves. Read from the gzip trailer.
lastBuildError text The failure message, shown in the feeds index.
lastBuildDiagnostics text JSON. See below.
dateCreated datetime
dateUpdated datetime
uid uid

lastBuildDiagnostics#

What the last build recorded, and what the Mapping tab reads back. Shaped by BuildDiagnostics.

Key Type Notes
skippedByAttribute object Required attribute that was blank, or duplicateId, to the number of items it excluded.
blankByAttribute object Mapped attribute, to the number of items it was blank on.
twigErrorsByAttribute object Attribute, to the number of items its Twig value failed on.
sampleTwigErrors object Attribute, to the first Twig error message.
invalidByAttribute object Money attribute, to the number of items priced at zero or less. Those items stay in the feed.
relativeUrlByAttribute object URL or image attribute, to the number of items where the plugin discarded a value that isn’t an absolute http or https URL.
sampleSkipped array Up to 50 {"id": 0, "reason": "..."} entries, for the Excluded items panel. The reason is an attribute or duplicateId. The CSV report on the feed filesystem has the full set.
sampleRelativeUrls object URL or image attribute, to the first such value the plugin discarded.
urlCheck object {"status": 0, "contentType": "...", "error": null} from the HEAD request sent after a successful build. Advisory.

Artifacts#

Built feeds are not stored in the database. Each one is written to the plugin’s configured filesystem:

Path Contents
product-feeds/<token>.<extension>.gz The gzipped feed. Overwritten on each build rather than timestamped.
product-feeds/<token>-excluded.csv The full list of excluded items. Deleted after a build that excludes zero items.

Both files are named from the token. Rotating the token copies them to the new token’s paths and deletes the old ones once the feed saves with the new token. Switching a feed to or from Klaviyo changes the file extension. Saving deletes the old file, and the feed URL changes and returns 404 until the next build.

We can take it from here.

We take on the Craft and Craft Commerce sites you built, so you can get back to building. Introduce a client who signs a management contract and you get a $3,000 partnership fee.

How the Dev Partnership Program works
See if we’re a fit