Customization
Most of the cart templates are overridable. You can also override the CSS for aesthetic changes.
Getting started
When including Snipcart, you have to create an element to mount the cart on.
<!-- Snipcart stylesheet -->
<link rel="stylesheet" href="https://cdn.snipcart.com/themes/v3.0.28/default/snipcart.css" />
<!-- Element where you set your API key and insert your custom templates -->
<div id="snipcart" data-api-key="<API_KEY>">
</div>
<!-- Snipcart script -->
<script src="https://cdn.snipcart.com/themes/v3.0.28/default/snipcart.js"></script>
In this element, you can provide your own templates. Refer to this documentation entry to see the list of components. Every component that has a Default Template can be overridden.
To override a template, insert a node into div#snipcart
. The node tag must be the name of the component you want to override.
<div hidden id="snipcart" data-api-key="<API_KEY>">
<component-to-override>
<!-- The template must have a single root element -->
<div class="root">
</div>
</component-to-override>
</div>
You must provide a root node for each component you override. For instance, this wouldn't be valid:
<div hidden id="snipcart" data-api-key="<API_KEY>">
<component-to-override>
<!-- You can't have more than one root element in your template. -->
<div class="root">
</div>
<div class="root">
</div>
</component-to-override>
</div>
Sections
Some sections in the cart are also overridable. This allows you to add any element in specific sections of the cart without requiring a full override. This can be useful when you only want to add a custom notice or a custom field.
The key here is to specify which section you want to override beside the component name:
<div hidden id="snipcart" data-api-key="<API_KEY>">
<!-- Specify the section name with section attribute -->
<component-to-override section="top">
<div class="root">
This will be inserted into the section named `top`.
</div>
</component-to-override>
</div>
Defining templates in an external file
You can also include your templates in an external file, this is especially helpful for customers building applications with frameworks like Next, Gatsby or Nuxt. To avoid conflicts with templating engines of such frameworks, this is the approach we suggest.
To do so, simply refer your external file via the data-templates-url
attribute on your div#snipcart
<div id="snipcart" data-api-key="<API_KEY>" data-templates-url="/snipcart-templates.html">
</div>
In your snipcart-templates.html
file, put all your overridden components in a div with id snipcart-templates
<!DOCTYPE html>
<html>
<head><title>Templates</title></head>
<body>
<div id="snipcart-templates">
<component-to-override>
<!-- The template must have a single root element -->
<div class="root">
</div>
</component-to-override>
</div>
</body>
</html>
You can take a look at this documentation entry to see all overridable sections.
How it works
Under the hood, the cart is built with Vue.js. So Vue directives are supported in your custom templates.
However, you don't need to learn Vue to write your own templates. But if you do know it, you might be able to push things a bit further.
We tried to encapsulate all the logic inside micro-components and component wrappers. That way, it's simpler to understand how a template works without having to know Vue.
However, we kept some Vue directives like v-if
and @click
in our templates. We considered trying to encapsulate them into component wrappers but realized it would create a lot of useless components, so we decided to keep them in templates.
Examples
Here is an example of what can be done with our customizable templates.
Simplify cart items
Let's say you want to update the template of each item in the cart. You want to remove images, descriptions, etc.—keep the bare minimum.
<div hidden id="snipcart" data-api-key="<api_key>">
<item-line>
<li class="snipcart__item__line snipcart__box">
<div class="snipcart__item__line__product">
<div class="snipcart__item__line__header">
<h2 class="snipcart__item__line__header__title">
{{ item.name }}
</h2>
<item-quantity class="snipcart__item__line__quantity" v-if="!adding"></item-quantity>
<div class="snipcart__item__line__header__actions">
<remove-item-action class="snipcart__button--icon">
<icon name="trash" class="icon--red" alt="item.remove_item"></icon>
</remove-item-action>
</div>
</div>
</div>
</li>
</item-line>
</div>

Add phone field in address form
If you want to collect the phone number in the address form, you can add the phone field and the value will appear in the customer info.
<div id="snipcart" data-api-key="<api_key>" hidden>
<address-fields section="top">
<div>
<snipcart-label for="phone">
Phone number
</snipcart-label>
<snipcart-input name="phone">
</snipcart-input>
</div>
</address-fields>
</div>

Customize address fields
By default, the address fields offer your customers an address autocomplete component for a faster checkout experience. You might want something more classic.
To do so, you can override the address-fields
component like that:
<div hidden id="snipcart" data-api-key="<api_key>">
<address-fields>
<div>
<fieldset class="snipcart-form__set">
<div class="snipcart-form__row">
<div class="snipcart-form__field snipcart-form__cell--large">
<snipcart-label
class="snipcart__font--tiny"
for="address1"
>{{ $localize('address_form.address1') }}</snipcart-label>
<snipcart-input name="address1"></snipcart-input>
<snipcart-error-message name="address1"></snipcart-error-message>
</div>
<div class="snipcart-form__field snipcart-form__cell--tidy">
<snipcart-label
class="snipcart__font--tiny"
for="address2"
>{{ $localize('address_form.address2') }}</snipcart-label>
<snipcart-input name="address2"></snipcart-input>
<snipcart-error-message name="address2"></snipcart-error-message>
</div>
</div>
<div class="snipcart-form__field">
<snipcart-label
class="snipcart__font--tiny"
for="city"
>{{ $localize('address_form.city') }}</snipcart-label>
<snipcart-input name="city"></snipcart-input>
<snipcart-error-message name="city"></snipcart-error-message>
</div>
<div class="snipcart-form__field">
<snipcart-label
class="snipcart__font--tiny"
for="country"
>{{ $localize('address_form.country') }}</snipcart-label>
<snipcart-typeahead type="dropdown" name="country" autocomplete="country"></snipcart-typeahead>
</div>
<div class="snipcart-form__row">
<div class="snipcart-form__field snipcart-form__cell--large">
<snipcart-label
class="snipcart__font--tiny"
for="province"
>{{ $localize('address_form.province') }}</snipcart-label>
<snipcart-typeahead type="dropdown" name="province" autocomplete="province state"></snipcart-typeahead>
</div>
<div class="snipcart-form__field snipcart-form__cell--tidy">
<snipcart-label
class="snipcart__font--tiny"
for="postalCode"
>{{ $localize('address_form.postalCode') }}</snipcart-label>
<snipcart-input name="postalCode"></snipcart-input>
<snipcart-error-message name="postalCode"></snipcart-error-message>
</div>
</div>
</fieldset>
</div>
</address-fields>
</div>
Customize the payment form
You can customize the payment form using the Snipcart sdk. See the sdk reference here.
Conclusion
We suggest you take a look at our components reference documentation. You'll find the documentation of each overridable template along with its default template.