Skip to main content

Customize theme components

This guide shows you how to customize the Shopify plugin components to match your theme's design. You'll learn to override the default components by creating custom PHP files in your theme directory.


You need:

  • Write access to your WordPress theme files and directories
  • Understanding of WordPress theme structure
  • Basic knowledge of PHP and HTML

Anchor to Customize Product Card componentsCustomize Product Card components

The Product Card Component appears in product listings and collection pages, showing key product information like image, title, and price.

Anchor to Step 1: Create the override fileStep 1: Create the override file

Create a file named product-card.php in a Shopify folder within your theme directory:

.
├── wp-content
│ └── themes
│ └── theme_dir
│ ├── assets
│ ├── functions.php
│ ├── parts
│ ├── patterns
│ ├── shopify # Shopify plugin customization
│ │ └── product-card.php # Component customization override file
│ ├── styles
│ ├── templates
│ └── theme.json
│ ...

Anchor to Step 2: Copy the default codeStep 2: Copy the default code

Add this default code to your product-card.php file:

{theme_dir}/shopify/product-card.php

<?php
if (!defined('ABSPATH')) {
exit;
}

if (!function_exists('render_product_card_client')) {
function render_product_card_client($product_handle, $has_context = true, $card_behavior = 'both') {
// Check if product handle is provided
if (empty($product_handle) && $has_context === false) {
echo '<div class="product-card product-card--error">';
echo '<p class="product-card__error-message">You must add a product.</p>';
echo '</div>';
return;
}

if ($has_context === false) { ?>
<shopify-context type="product" handle="<?php echo esc_attr($product_handle); ?>">
<template>
<?php } ?>

<div shopify-attr--disabled="!product.availableForSale" class="product-card">
<div class="product-card__image-container">
<?php if ($card_behavior === 'both' || $card_behavior === 'quick-shop-only') { ?>
<button
shopify-attr--disabled="!product.availableForSale"
shopify-attr--test="!product.availableForSale"
class="product-card__hover-button"
onclick="getElementById('product-modal').showModal(); getElementById('product-modal-context').update(event);"
>
<span class="product-card__hover-button__button__text">Quick Shop</span>
</button>
<?php } ?>

<?php if ($card_behavior === 'quick-shop-only') { ?>
<a
shopify-attr--disabled="!product.availableForSale"
class="product__link"
onclick="getElementById('product-modal').showModal(); getElementById('product-modal-context').update(event);"
><shopify-media
max-images="1"
query="product.selectedOrFirstAvailableVariant.image"
></shopify-media
></a>
<?php } else { ?>
<a
shopify-attr--disabled="!product.availableForSale"
class="product__link"
shopify-attr--href="'/products/' + product.handle "
><shopify-media
max-images="1"
query="product.selectedOrFirstAvailableVariant.image"
></shopify-media
></a>
<?php } ?>
</div>

<?php if ($card_behavior === 'quick-shop-only') { ?>
<a
shopify-attr--disabled="!product.availableForSale"
class="product__link"
onclick="getElementById('product-modal').showModal(); getElementById('product-modal-context').update(event);"
>
<?php } else { ?>
<a
shopify-attr--disabled="!product.availableForSale"
class="product__link"
shopify-attr--href="'/products/' + product.handle "
>
<?php } ?>
<!-- Product information on the card -->
<div class="product-card__details">
<div class="product-card__info">
<h3 class="product-card__title">
<span>
<shopify-data query="product.title"></shopify-data>
</span>
</h3>
</div>
<p class="product-card__price">
<shopify-money query="product.selectedOrFirstAvailableVariant.price"></shopify-money>
</p>
</div>
</a>
</div>
<?php if (!$has_context) { ?>
</template>
</shopify-context>
<?php } ?>

<?php
}} ?>

Anchor to Step 3: Customize the componentStep 3: Customize the component

Now you can modify the HTML structure, CSS classes, or add custom styling. For example, to add a custom wrapper class:

<div shopify-attr--disabled="!product.availableForSale" class="product-card my-custom-card-class">
<!-- Rest of the component remains the same -->

Anchor to Customize Product Quick ViewsCustomize Product Quick Views

The Product Quick View modal displays when customers click "Quick Shop" on product cards, showing product details without leaving the current page.

Anchor to Step 1: Create the override fileStep 1: Create the override file

Create a file named modal.php in a Shopify folder within your theme directory:

.
├── wp-content
│ └── themes
│ └── theme_dir
│ ├── assets
│ ├── functions.php
│ ├── parts
│ ├── patterns
│ ├── shopify # Shopify plugin customization
│ │ └── modal.php # Component customization override file
│ ├── styles
│ ├── templates
│ └── theme.json
│ ...

Anchor to Step 2: Copy the default codeStep 2: Copy the default code

Add this code to your modal.php file:

{theme_dir}/shopify/modal.php

<dialog id="product-modal" class="product-modal">
<!-- The handle of this context is automatically set when the dialog is opened -->
<shopify-context id="product-modal-context" type="product" wait-for-update>
<template>
<div class="product-modal__container">
<div class="product-modal__close-container">
<button class="product-modal__close" onclick="getElementById('product-modal').close();">&#10005;</button>
</div>
<div class="product-modal__content">
<div class="product-modal__layout">
<div class="product-modal__media">
<shopify-media max-images="1" width="400" height="500" query="product.selectedOrFirstAvailableVariant.image"></shopify-media>
</div>
<div class="product-modal__details">
<div class="product-modal__header">
<h1 class="product-modal__title">
<shopify-data query="product.title"></shopify-data>
</h1>
<div class="product-modal__price-container">
<shopify-money query="product.selectedOrFirstAvailableVariant.price"></shopify-money>
<shopify-money
class="product-modal__compare-price"
query="product.selectedOrFirstAvailableVariant.compareAtPrice"
></shopify-money>
</div>
<div class="product-modal__description-text">
<shopify-data query="product.descriptionHtml"></shopify-data>
</div>
</div>

<shopify-variant-selector></shopify-variant-selector>

<div class="product-modal__buttons">
<button
class="product-modal__add-button"
onclick="getElementById('cart').addLine(event); getElementById('cart').showModal();getElementById('product-modal').close();"
shopify-attr--disabled="!product.selectedOrFirstAvailableVariant.product.availableForSale"
>
Add to cart
</button>
<button
class="product-modal__buy-button"
onclick="document.querySelector('shopify-store').buyNow(event)"
class="product-buy-now__button"
shopify-attr--disabled="!product.selectedOrFirstAvailableVariant.product.availableForSale"
>
Buy now
</button>
</div>
</div>
</div>
</div>
</div>
</template>
</shopify-context>
</dialog>

Anchor to Step 3: Customize the modalStep 3: Customize the modal

You can customize the modal layout, styling, or button text. For example, to change the close button:

<button class="product-modal__close" onclick="getElementById('product-modal').close();">
Close ✕
</button>

Anchor to Customize Product Detail PagesCustomize Product Detail Pages

The Product Detail Page shows the full product information including images, variants, description, and purchase options.

Anchor to Step 1: Create the override fileStep 1: Create the override file

Create a file named pdp.php in a Shopify folder within your theme directory:

.
├── wp-content
│ └── themes
│ └── theme_dir
│ ├── assets
│ ├── functions.php
│ ├── parts
│ ├── patterns
│ ├── shopify # Shopify plugin customization
│ │ └── pdp.php # Component customization override file
│ ├── styles
│ ├── templates
│ └── theme.json
│ ...

Anchor to Step 2: Copy the default codeStep 2: Copy the default code

Add this code to your pdp.php file:

{theme_dir}/shopify/pdp.php

<div class="shopify-product-details">
<div class="single-product-layout">
<div class="single-product">
<!-- Set product you want to display -->
<shopify-context type="product" handle="<?php echo esc_attr($product_handle); ?>">
<template>
<div class="single-product__container">
<div class="single-product__media">
<!-- Image carousel -->
<div class="single-product__main-image">
<shopify-media layout="fixed" query="product.selectedOrFirstAvailableVariant.image"></shopify-media>
</div>
</div>
<div class="single-product__details">
<div class="single-product__info">
<h1 class="single-product__title">
<shopify-data query="product.title"></shopify-data>
</h1>
<div class="single-product__price">
<span>
<shopify-money query="product.selectedOrFirstAvailableVariant.price"></shopify-money>
<shopify-money
class="single-product__compare-price"
query="product.selectedOrFirstAvailableVariant.compareAtPrice"
></shopify-money>
</span>
</div>
</div>
<shopify-variant-selector></shopify-variant-selector>

<div class="single-product__buttons">
<div class="single-product__add-to-cart">
<div class="single-product__incrementor">
<button class="decrease" onclick="decreaseValue();">-</button>
<span class="single-product__count" id="single-product__count">1</span>
<button class="increase" onclick="increaseValue();">+</button>

Anchor to Step 3: Customize the product pageStep 3: Customize the product page

You can modify the layout, add custom fields, or change the styling. For example, to add a custom section:

<div class="single-product__custom-section">
<h3>Additional Information</h3>
<p>Your custom content here</p>
</div>

Anchor to Customize CollectionsCustomize Collections

The Collection Component displays groups of products from your Shopify collections on collection pages.

Anchor to Step 1: Create the override fileStep 1: Create the override file

Create a file named collection.php in a Shopify folder within your theme directory:

.
├── wp-content
│ └── themes
│ └── theme_dir
│ ├── assets
│ ├── functions.php
│ ├── parts
│ ├── patterns
│ ├── shopify # Shopify plugin customization
│ │ └── collection.php # Collection customization override file
│ ├── styles
│ ├── templates
│ └── theme.json
│ ...

Anchor to Step 2: Copy the default codeStep 2: Copy the default code

Add this code to your collection.php file:

{theme_dir}/shopify/collection.php

<div class="max-products-per-row-3 max-products-per-page-12 wp-block-shopify-collection-shopify-collection-block">
<shopify-context type="collection" handle="<?php echo esc_attr($collection_handle); ?>">
<template>
<div class="collection-grid__container">
<div class="collection-grid__grid">
<!-- Define a new context for the products within the collection -->
<shopify-list-context id="<?php echo esc_attr($collection_unique_id); ?>" type="product" query="collection.products" first="15">
<!-- This template is repeated for each product in the collection -->
<template>
<?php
include SHOPIFY_PLUGIN_DIR . 'includes/components/frontend/product-cards/storefront-product-card.php';
render_product_card_client('', true, $card_behavior); // The handle will be provided by the Shopify context
?>
</template>
</shopify-list-context>
</div>
<?php
// Include and render the reusable pagination snippet
include SHOPIFY_PLUGIN_DIR . 'includes/components/frontend/pagination.php';
// Render the pagination using the unique list id
render_shopify_pagination($collection_unique_id);
?>
</div>

</template>
</shopify-context>
</div>

Anchor to Step 3: Customize the collection displayStep 3: Customize the collection display

You can modify how products are displayed in collections. For example, to change the number of products shown:

<shopify-list-context id="<?php echo esc_attr($collection_unique_id); ?>" type="product" query="collection.products" first="24">

Anchor to Advanced: Server-Side RenderingAdvanced: Server-Side Rendering

For better SEO, you can implement Server-Side Rendering (SSR) by fetching data directly from the Shopify Storefront API in your PHP files instead of using the Storefront Web Components.

  • Improved SEO: Search engines can crawl the fully rendered HTML
  • Faster initial load times: Content is ready when the page loads
  • Better accessibility: Screen readers can access the content immediately

Anchor to Implementation approachImplementation approach

When implementing SSR, your custom PHP files will:

  1. Fetch data directly: Use the Shopify Storefront API to get product/collection data
  2. Render HTML server-side: Generate the complete HTML structure in PHP
  3. Handle pagination: Create custom pagination logic since you won't use the default web components

Note that SSR requires more development complexity and a deeper understanding of the Shopify Storefront API, but provides significant SEO benefits for product and collection pages.


Was this page helpful?