Social Links and Policy Links
Add social media icons, payment methods, policy links, and copyright notices to your footer using Shopify's built-in settings and objects.
Every footer needs certain standard elements: social links, policy links, payment icons, and copyright. Shopify provides built-in objects and settings to make these easy to implement.
Social Media Links
Using Theme Settings
Configure social links in theme settings (not section settings) so they’re consistent across the site:
{# config/settings_schema.json #}{ "name": "Social media", "settings": [ { "type": "header", "content": "Accounts" }, { "type": "text", "id": "social_facebook", "label": "Facebook", "info": "https://facebook.com/shopify" }, { "type": "text", "id": "social_instagram", "label": "Instagram", "info": "https://instagram.com/shopify" }, { "type": "text", "id": "social_twitter", "label": "X (Twitter)", "info": "https://twitter.com/shopify" }, { "type": "text", "id": "social_youtube", "label": "YouTube", "info": "https://youtube.com/shopify" }, { "type": "text", "id": "social_tiktok", "label": "TikTok", "info": "https://tiktok.com/@shopify" }, { "type": "text", "id": "social_pinterest", "label": "Pinterest", "info": "https://pinterest.com/shopify" }, { "type": "text", "id": "social_linkedin", "label": "LinkedIn", "info": "https://linkedin.com/company/shopify" } ]}Social Links Snippet
{# snippets/social-icons.liquid #}
{%- liquid assign social_accounts = 'facebook, instagram, twitter, youtube, tiktok, pinterest, linkedin, snapchat, tumblr, vimeo' | split: ', ' assign has_social = false
for account in social_accounts assign setting_name = 'social_' | append: account if settings[setting_name] != blank assign has_social = true break endif endfor-%}
{%- if has_social -%} <ul class="social-icons" role="list"> {%- for account in social_accounts -%} {%- assign setting_name = 'social_' | append: account -%} {%- assign url = settings[setting_name] -%}
{%- if url != blank -%} <li class="social-icons__item"> <a href="{{ url }}" class="social-icons__link" target="_blank" rel="noopener noreferrer" aria-label="{{ account | capitalize }}" > {%- render 'icon-social', icon: account -%} </a> </li> {%- endif -%} {%- endfor -%} </ul>{%- endif -%}Social Icon Snippet
{# snippets/icon-social.liquid #}
{%- case icon -%} {%- when 'facebook' -%} <svg aria-hidden="true" width="24" height="24" viewBox="0 0 24 24" fill="currentColor"> <path d="M18 2h-3a5 5 0 00-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 011-1h3z"/> </svg>
{%- when 'instagram' -%} <svg aria-hidden="true" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> <rect x="2" y="2" width="20" height="20" rx="5" ry="5"/> <path d="M16 11.37A4 4 0 1112.63 8 4 4 0 0116 11.37z"/> <line x1="17.5" y1="6.5" x2="17.51" y2="6.5"/> </svg>
{%- when 'twitter' -%} <svg aria-hidden="true" width="24" height="24" viewBox="0 0 24 24" fill="currentColor"> <path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/> </svg>
{%- when 'youtube' -%} <svg aria-hidden="true" width="24" height="24" viewBox="0 0 24 24" fill="currentColor"> <path d="M23.498 6.186a3.016 3.016 0 00-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 00.502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 002.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 002.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z"/> </svg>
{%- when 'tiktok' -%} <svg aria-hidden="true" width="24" height="24" viewBox="0 0 24 24" fill="currentColor"> <path d="M19.59 6.69a4.83 4.83 0 01-3.77-4.25V2h-3.45v13.67a2.89 2.89 0 01-5.2 1.74 2.89 2.89 0 012.31-4.64 2.93 2.93 0 01.88.13V9.4a6.84 6.84 0 00-1-.05A6.33 6.33 0 005 20.1a6.34 6.34 0 0010.86-4.43v-7a8.16 8.16 0 004.77 1.52v-3.4a4.85 4.85 0 01-1-.1z"/> </svg>
{%- when 'pinterest' -%} <svg aria-hidden="true" width="24" height="24" viewBox="0 0 24 24" fill="currentColor"> <path d="M12 0C5.373 0 0 5.372 0 12c0 5.084 3.163 9.426 7.627 11.174-.105-.949-.2-2.405.042-3.441.218-.937 1.407-5.965 1.407-5.965s-.359-.719-.359-1.782c0-1.668.967-2.914 2.171-2.914 1.023 0 1.518.769 1.518 1.69 0 1.029-.655 2.568-.994 3.995-.283 1.194.599 2.169 1.777 2.169 2.133 0 3.772-2.249 3.772-5.495 0-2.873-2.064-4.882-5.012-4.882-3.414 0-5.418 2.561-5.418 5.207 0 1.031.397 2.138.893 2.738a.36.36 0 01.083.345l-.333 1.36c-.053.22-.174.267-.402.161-1.499-.698-2.436-2.889-2.436-4.649 0-3.785 2.75-7.262 7.929-7.262 4.163 0 7.398 2.967 7.398 6.931 0 4.136-2.607 7.464-6.227 7.464-1.216 0-2.359-.631-2.75-1.378l-.748 2.853c-.271 1.043-1.002 2.35-1.492 3.146C9.57 23.812 10.763 24 12 24c6.627 0 12-5.373 12-12 0-6.628-5.373-12-12-12z"/> </svg>
{%- when 'linkedin' -%} <svg aria-hidden="true" width="24" height="24" viewBox="0 0 24 24" fill="currentColor"> <path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 01-2.063-2.065 2.064 2.064 0 112.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/> </svg>
{%- endcase -%}Social Icons CSS
.social-icons { display: flex; flex-wrap: wrap; gap: var(--spacing-sm); list-style: none; padding: 0; margin: 0;}
.social-icons__link { display: flex; align-items: center; justify-content: center; width: 40px; height: 40px; color: inherit; opacity: 0.7; transition: opacity 0.2s;}
.social-icons__link:hover { opacity: 1;}
.social-icons__link svg { width: 20px; height: 20px;}Policy Links
Shopify provides a shop.policies object with all store policies:
{# snippets/policy-links.liquid #}
{%- if shop.policies.size > 0 -%} <nav class="policy-links" aria-label="Legal"> <ul class="policy-links__list"> {%- for policy in shop.policies -%} {%- if policy != blank -%} <li class="policy-links__item"> <a href="{{ policy.url }}" class="policy-links__link"> {{ policy.title }} </a> </li> {%- endif -%} {%- endfor -%} </ul> </nav>{%- endif -%}Available Policies
The shop.policies array can include:
shop.policies.refund_policyshop.policies.privacy_policyshop.policies.terms_of_serviceshop.policies.shipping_policyshop.policies.subscription_policy
Access individual policies directly:
{%- if shop.privacy_policy -%} <a href="{{ shop.privacy_policy.url }}">{{ shop.privacy_policy.title }}</a>{%- endif -%}Policy Links CSS
.policy-links__list { display: flex; flex-wrap: wrap; gap: var(--spacing-sm) var(--spacing-md); list-style: none; padding: 0; margin: 0;}
.policy-links__link { font-size: 0.875rem; color: rgba(255, 255, 255, 0.6); text-decoration: none; transition: color 0.2s;}
.policy-links__link:hover { color: #ffffff;}Payment Icons
Display accepted payment methods using Shopify’s payment icons:
{# snippets/payment-icons.liquid #}
{%- unless shop.enabled_payment_types == empty -%} <div class="payment-icons"> <span class="visually-hidden">Payment methods</span> <ul class="payment-icons__list" role="list"> {%- for type in shop.enabled_payment_types -%} <li class="payment-icons__item"> {{ type | payment_type_svg_tag: class: 'payment-icon' }} </li> {%- endfor -%} </ul> </div>{%- endunless -%}Payment Icons CSS
.payment-icons__list { display: flex; flex-wrap: wrap; gap: var(--spacing-xs); list-style: none; padding: 0; margin: 0;}
.payment-icon { height: 24px; width: auto;}
/* Or fixed width for alignment */.payment-icons__item { width: 38px; height: 24px;}
.payment-icon { width: 100%; height: 100%; object-fit: contain;}Copyright Notice
Dynamic copyright with current year:
{# Basic copyright #}<p class="footer__copyright"> © {{ 'now' | date: '%Y' }} {{ shop.name }}</p>
{# With "All rights reserved" #}<p class="footer__copyright"> © {{ 'now' | date: '%Y' }} {{ shop.name }}. All rights reserved.</p>
{# With customizable text from settings #}<p class="footer__copyright"> © {{ 'now' | date: '%Y' }} {{ shop.name }}. {%- if section.settings.copyright_text != blank -%} {{ section.settings.copyright_text }} {%- endif -%}</p>Country/Currency Selector
For international stores:
{# snippets/country-selector.liquid #}
{%- if localization.available_countries.size > 1 -%} <div class="country-selector"> {%- form 'localization', class: 'country-selector__form' -%} <label for="country-selector" class="visually-hidden"> Country/region </label>
<select name="country_code" id="country-selector" class="country-selector__select" onchange="this.form.submit()" > {%- for country in localization.available_countries -%} <option value="{{ country.iso_code }}" {% if country.iso_code == localization.country.iso_code %}selected{% endif %} > {{ country.name }} ({{ country.currency.iso_code }} {{ country.currency.symbol }}) </option> {%- endfor -%} </select>
<button type="submit" class="country-selector__button visually-hidden"> Update </button> {%- endform -%} </div>{%- endif -%}Language Selector
{# snippets/language-selector.liquid #}
{%- if localization.available_languages.size > 1 -%} <div class="language-selector"> {%- form 'localization', class: 'language-selector__form' -%} <label for="language-selector" class="visually-hidden"> Language </label>
<select name="locale_code" id="language-selector" class="language-selector__select" onchange="this.form.submit()" > {%- for language in localization.available_languages -%} <option value="{{ language.iso_code }}" {% if language.iso_code == localization.language.iso_code %}selected{% endif %} > {{ language.endonym_name | capitalize }} </option> {%- endfor -%} </select>
<button type="submit" class="visually-hidden"> Update </button> {%- endform -%} </div>{%- endif -%}Complete Footer Bottom Bar
Putting it all together:
<div class="footer__bottom"> <div class="footer__bottom-container container"> <div class="footer__bottom-left"> {# Copyright #} <p class="footer__copyright"> © {{ 'now' | date: '%Y' }} {{ shop.name }} </p>
{# Policy links #} {%- render 'policy-links' -%} </div>
<div class="footer__bottom-center"> {# Social icons #} {%- render 'social-icons' -%} </div>
<div class="footer__bottom-right"> {# Selectors #} <div class="footer__selectors"> {%- render 'country-selector' -%} {%- render 'language-selector' -%} </div>
{# Payment icons #} {%- render 'payment-icons' -%} </div> </div></div>.footer__bottom { padding-top: var(--spacing-lg); border-top: 1px solid rgba(255, 255, 255, 0.1);}
.footer__bottom-container { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--spacing-md);}
.footer__bottom-left { display: flex; flex-wrap: wrap; align-items: center; gap: var(--spacing-md);}
.footer__bottom-right { display: flex; align-items: center; gap: var(--spacing-lg);}
.footer__selectors { display: flex; gap: var(--spacing-sm);}
/* Mobile: Stack vertically */@media (max-width: 767px) { .footer__bottom-container { flex-direction: column; text-align: center; }
.footer__bottom-left, .footer__bottom-right { justify-content: center; }}Practice Exercise
Create a footer bottom bar that includes:
- Copyright with dynamic year
- Social links from theme settings
- Policy links from shop.policies
- Payment icons
- Country selector (if multiple countries)
Test by:
- Adding/removing social URLs in theme settings
- Checking that all policies display
- Verifying payment icons match your store’s settings
Key Takeaways
- Use theme settings for social links (consistent across site)
shop.policiesprovides all store policies automaticallypayment_type_svg_tagrenders payment method icons- Dynamic year with
{{ 'now' | date: '%Y' }} - Localization forms for country/language selectors
- Use
aria-labelon social links for accessibility target="_blank"withrel="noopener"for external links
What’s Next?
With all footer elements in place, the next lesson covers Accessibility for Navigation Regions to ensure your header and footer work for everyone.
Finished this lesson?
Mark it complete to track your progress.
Discussion
Loading comments...