Download the PHP package craftcms/shopify without Composer
On this page you can find all versions of the php package craftcms/shopify. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download craftcms/shopify
More information about craftcms/shopify
Files in craftcms/shopify
Package shopify
Short Description Shopify for Craft CMS
License MIT
Homepage https://github.com/craftcms/shopify
Informations about the package shopify
Shopify for Craft CMS
Build a content-driven storefront by synchronizing Shopify products into Craft CMS.
Topics
- :package: Installation: Set up the plugin and get connected to Shopify.
- :card_file_box: Working with Products: Learn what kind of data is available and how to access it.
- :bookmark_tabs: Templating: Tips and tricks for using products in Twig.
- :leaves: Upgrading: Take advantage of new features and performance improvements.
- :telescope: Advanced Features: Go further with your integration.
Installation
The Shopify plugin requires Craft CMS 5.0.0 or later.
To install the plugin, visit the Plugin Store from your Craft project, or follow these instructions.
-
Navigate to your Craft project in a new terminal:
-
Require the package with Composer:
- In the Control Panel, go to Settings → Plugins and click the “Install” button for Shopify, or run:
Create a Shopify App
The plugin works with Shopify’s Custom Apps system.
[!NOTE] If you are not the owner of the Shopify store, have the owner add you as a collaborator or staff member with the Develop Apps permission.
Follow Shopify’s directions for creating a private app (through the Get the API credentials for a custom app section), and take these actions when prompted:
- App Name: Choose something that identifies the integration, like “Craft CMS.”
-
Admin API access scopes: The following scopes are required for the plugin to function correctly:
read_products
read_product_listings
read_inventory
Additionally (at the bottom of this screen), the Webhook subscriptions → Event version should be
2023-10
. - Admin API access token: Reveal and copy this value into your
.env
file, asSHOPIFY_ADMIN_ACCESS_TOKEN
. - API key and secret key: Reveal and/or copy the API key and API secret key into your
.env
underSHOPIFY_API_KEY
andSHOPIFY_API_SECRET_KEY
, respectively.
Store Hostname
The last piece of info you’ll need on hand is your store’s hostname. This is usually what appears in the browser when using the Shopify admin—it’s also shown in the Settings screen of your store:
Save this value (without the leading http://
or https://
) in your .env
as SHOPIFY_HOSTNAME
. At this point, you should have four Shopify-specific values:
Connect Plugin
Now that you have credentials for your custom app, it’s time to add them to Craft.
- Visit the Shopify → Settings screen in your project’s control panel.
- Assign the four environment variables to the corresponding settings, using the special config syntax:
- API Key:
$SHOPIFY_API_KEY
- API Secret Key:
$SHOPIFY_API_SECRET_KEY
- Access Token:
$SHOPIFY_ACCESS_TOKEN
- Host Name:
$SHOPIFY_HOSTNAME
- API Key:
- Click Save.
[!NOTE] These settings are stored in Project Config, and will be automatically applied in other environments. Webhooks will still need to be configured for each environment!
Set up Webhooks
Once your credentials have been added to Craft, a new Webhooks tab will appear in the Shopify section of the control panel.
Click Create on the Webhooks screen to add the required webhooks to Shopify. The plugin will use the credentials you just configured to perform this operation—so this also serves as an initial communication test.
[!WARNING] You will need to add webhooks for each environment you deploy the plugin to, because each webhook is tied to a specific URL.
[!NOTE] If you need to test live synchronization in development, we recommend using ngrok to create a tunnel to your local environment. DDEV makes this simple, with the
ddev share
command. Keep in mind that your site’s primary/base URL is used when registering webhooks, so you may need to update it to match the ngrok tunnel, then recreate your webhooks.
Upgrading
Before upgrading ensure that the Admin API access scopes match the requirements below. This ensures that all the new features of the plugin will work correctly.
After upgrading, ensure that all required webhooks have been created by clicking the “Create” button on the Shopify → Webhooks screen in your project’s control panel page in the CP. If the “Create” button is not visible, all required webhooks have been created.
Product Element
Products from your Shopify store are represented in Craft as product elements, and can be found by going to Shopify → Products in the control panel.
Synchronization
Once the plugin has been configured, you can perform an initial synchronization of all products via the command line.
The webhooks.
Larger, more complex, stores may run into rate limiting issues during a full sync. In these cases, you can use the --throttle
option to slow down the synchronization process.
[!NOTE] Smaller stores with only a few products can perform synchronization via the Shopify Sync utility.
Native Attributes
In addition to the standard element attributes like id
, title
, and status
, each Shopify product element contains the following mappings to its canonical Shopify Product resource:
Attribute | Description | Type |
---|---|---|
shopifyId |
The unique product identifier in your Shopify store. | String |
shopifyStatus |
The status of the product in your Shopify store. Values can be active , draft , or archived . |
String |
handle |
The product’s “URL handle” in Shopify, equivalent to a “slug” in Craft. For existing products, this is visible under the Search engine listing section of the edit screen. | String |
productType |
The product type of the product in your Shopify store. | String |
bodyHtml |
Product description. Use the \|raw filter to output it in Twig—but only if the content is trusted. |
String |
publishedScope |
Published scope of the product in Shopify store. Common values are web (for web-only products) and global (for web and point-of-sale products). |
String |
tags |
Tags associated with the product in Shopify. | Array |
templateSuffix |
Liquid template suffix used for the product page in Shopify. | String |
vendor |
Vendor of the product. | String |
metaFields |
Metafields associated with the product. | Array |
images |
Images attached to the product in Shopify. The complete Product Image resources are stored in Craft. | Array |
options |
Product options, as configured in Shopify. Each option has a name , position , and an array of values . |
Array |
createdAt |
When the product was created in your Shopify store. | DateTime |
publishedAt |
When the product was published in your Shopify store. | DateTime |
updatedAt |
When the product was last updated in your Shopify store. | DateTime |
All of these properties are available when working with a product element in your templates.
[!NOTE]
See the Shopify documentation on the product resource for more information about what kinds of values to expect from these properties.
Methods
The product element has a few methods you might find useful in your templates.
Product::getVariants()
Returns the variants belonging to the product.
Product::getDefaultVariant()
Shortcut for getting the first/default variant belonging to the product.
Product::getCheapestVariant()
Shortcut for getting the lowest-priced variant belonging to the product.
Product::getShopifyUrl()
Product::getShopifyEditUrl()
For your administrators, you can even link directly to the Shopify admin:
Custom Fields
Products synchronized from Shopify have a dedicated field layout, which means they support Craft’s full array of content tools.
The product field layout can be edited by going to Shopify → Settings → Products, and scrolling down to Field Layout.
Routing
You can give synchronized products their own on-site URLs. To set up the URI format (and the template that will be loaded when a product URL is requested), go to Shopify → Settings → Products.
If you would prefer your customers to view individual products on Shopify, clear out the Product URI Format field on the settings page, and use product.shopifyUrl
instead of product.url
in your templates.
Product Status
A product’s status
in Craft is a combination of its shopifyStatus
attribute ('active', 'draft', or 'archived') and its enabled state. The former can only be changed from Shopify; the latter is set in the Craft control panel.
Note
Statuses in Craft are often a synthesis of multiple properties. For example, an entry with the Pending status just means it isenabled
and has apostDate
in the future.
In most cases, you’ll only need to display “Live” products, or those which are Active in Shopify and Enabled in Craft:
Status | Shopify | Craft |
---|---|---|
live |
Active | Enabled |
shopifyDraft |
Draft | Enabled |
shopifyArchived |
Archived | Enabled |
disabled |
Any | Disabled |
Querying Products
Products can be queried like any other element in the system.
A new query begins with the craft.shopifyProducts
factory function:
Query Parameters
The following element query parameters are supported, in addition to Craft’s standard set.
[!NOTE] Fields stored as JSON (like
options
andmetadata
) are only queryable as plain text. If you need to do advanced organization or filtering, we recommend using custom Category or Tag fields in your Product field layout.
shopifyId
Filter by Shopify product IDs.
shopifyStatus
Directly query against the product’s status in Shopify.
Use the regular .status()
param if you'd prefer to query against synthesized status values.
handle
Query by the product’s handle, in Shopify.
:rotating_light: This is not a reliable means to fetch a specific product, as the value may change during a synchronization. If you want a permanent reference to a product, consider using the Shopify product field.
productType
Find products by their “type” in Shopify.
publishedScope
Show only products that are published to a matching sales channel.
tags
Tags are stored as a comma-separated list. You may see better results using the .search()
param.
vendor
Filter by the vendor information from Shopify.
images
Images are stored as a blob of JSON, and only intended for use in a template in conjunction with a loaded product. Filtering directly by image resource values can be difficult and unpredictable—you may see better results using the .search()
param.
options
the .search()
param.
The above includes quote ("
) literals, because it’s attempting to locate a specific key in a JSON array, which will always be surrounded by double-quotes.
Templating
Product Data
Products behave just like any other element, in Twig. Once you’ve loaded a product via a custom field data.
[!NOTE] Some attributes are stored as JSON, which limits nested properties’s types. As a result, dates may be slightly more difficult to work with.
Variants and Pricing
Products don’t have a price, despite what the Shopify UI might imply—instead, every product has at least one Variant.
You can get an array of variant objects for a product by calling collect()
Twig function.
Unlike products, variants in Craft…
- …are represented as the API returns them;
- …the
metafields
property is accessible in addition to the API’s returned properties; - …use Shopify’s convention of underscores in property names instead of exposing camel-cased equivalents;
- …are plain associative arrays;
- …have no methods of their own;
Once you have a reference to a variant, you can output its properties:
[!NOTE] The built-in
currency
Twig filter is a great way to format money values.The
metafields
property will only be populated if thesyncVariantMetafields
setting is enabled.
Using Options
Options are Shopify’s way of distinguishing variants on multiple axes.
If you want to let customers pick from options instead of directly select variants, you will need to resolve which variant a given combination points to.
Form
Script
The code below can be added to a [`{% js %}` tag](https://craftcms.com/docs/5.x/reference/twig/tags.html#js), alongside the form code.Cart
Your customers can add products to their cart directly from your Craft site:
JS Buy SDK
Cart management and checkout are not currently supported in a native way.
However, Shopify maintains the Javascript Buy SDK as a means of interacting with their Storefront API to create completely custom shopping experiences.
[!NOTE] Use of the Storefront API requires a different access key, and assumes that you have published your products into the Storefront app’s sales channel.
Your public Storefront API token can be stored with your other credentials in
.env
and output in your front-end with the{{ getenv('...') }}
Twig helper—or just baked into a Javascript bundle. Keep your other secrets safe! This is the only one that can be disclosed.
The plugin makes no assumptions about how you use your product data in the front-end, but provides the tools necessary to connect it with the SDK. As an example, let’s look at how you might render a list of products in Twig, and hook up a custom client-side cart…
Shop Template: templates/shop.twig
Custom Script: assets/js/shop.js
Buy Button JS
The above example can be simplified with the Buy Button JS, which provides some ready-made UI components, like a fully-featured cart. The principles are the same:
- Make products available via the appropriate sales channels in Shopify;
- Output synchronized product data in your front-end;
- Initialize, attach, or trigger SDK functionality in response to events, using Shopify-specific identifiers from step #2;
Checkout
While solutions exist for creating a customized shopping experience, checkout will always happen on Shopify’s platform. This is not a technical limitation so much as it is a policy—Shopify’s checkout flow is fast, reliable, secure, and familiar to many shoppers.
If you want your customers’ entire journey to be kept on-site, we encourage you to try out our powerful ecommerce plugin, Commerce.
Helpers
In addition to product element methods, the plugin exposes its API to Twig via craft.shopify
.
API Service
[!WARNING] Use of API calls in Twig blocks rendering and—depending on traffic—may cause timeouts and/or failures due to
{% cache %}
tag with a key and specific expiry time to avoid making a request every time a template is rendered:
Issue requests to the Shopify Admin API via craft.shopify.api
:
The schema for each API resource will differ. Consult the Shopify API documentation for more information.
Store Service
A simple URL generator is available via craft.shopify.store
. You may have noticed it in the cart example, above—but it is a little more versatile than that!
The same params argument can be passed to a product element’s getShopifyUrl()
method:
Product Field
The plugin provides a Shopify Products field, which uses the familiar relational field UI to allow authors to select Product elements.
Relationships defined with the Shopify Products field use stable element IDs under the hood. When Shopify products are archived or deleted, the corresponding elements will also be updated in Craft, and naturally filtered out of your query results—including those explicitly attached via a Shopify Products field.
[!NOTE] Upgrading? Check out the migration notes for more info.
Going Further
Settings
The following settings can be controlled by creating a shopify.php
file in your config/
directory.
Setting | Type | Default | Description |
---|---|---|---|
apiKey |
string |
— | Shopify API key. |
apiSecretKey |
string |
— | Shopify API secret key. |
accessToken |
string |
— | Shopify API access token. |
hostName |
string |
— | Shopify host name. |
uriFormat |
string |
— | Product element URI format. |
template |
string |
— | Product element template path. |
syncProductMetafields |
bool |
true |
Whether product metafields should be included when syncing products. This adds an extra API request per product. |
syncVariantMetafields |
bool |
false |
Whether variant metafields should be included when syncing products. This adds an extra API request per variant. |
[!NOTE] Setting
apiKey
,apiSecretKey
,accessToken
, andhostName
viashopify.php
will override Project Config values set via the control panel during app setup. You can still reference environment values from the config file withcraft\helpers\App::env()
.
Events
craft\shopify\services\Products::EVENT_BEFORE_SYNCHRONIZE_PRODUCT
Emitted just prior to a product element being saved with new Shopify data. The craft\shopify\events\ShopifyProductSyncEvent
extends craft\events\CancelableEvent
, so setting $event->isValid
allows you to prevent the new data from being saved.
The event object has three properties:
element
: The product element being updated.source
: The Shopify product object that was applied.
[!WARNING] Do not manually save changes made in this event handler. The plugin will take care of this for you!
Element API
Your synchronized products can be published into an Element API endpoint, just like any other element type. This allows you to set up a local JSON feed of products, decorated with any content you’ve added in Craft:
Rate Limiting
The plugin makes its best effort to avoid Shopify’s strict API rate limiting rules by respecting headers in the replies (a feature of the first-party PHP SDK). This means that series of operations (like synchronization or custom API queries within loops) can take grow in a non-linear way.