Metafields Display

Dynamic metafield renderer with support for different field types.

A comprehensive metafield renderer that automatically handles different metafield types including text, numbers, dates, URLs, booleans, colors, files, lists, product references, and JSON. Includes styled output for each type.
metafields-display.liquidliquid
{% comment %} Metafields Display - snippets/metafields-display.liquid {% endcomment %}
{% comment %} 
  Usage: {% render 'metafields-display', resource: product, namespace: 'custom', key: 'material' %}
{% endcomment %}

{% assign metafield = resource.metafields[namespace][key] %}

{% if metafield %}
  <div class="metafield-wrapper" data-metafield="{{ namespace }}.{{ key }}">
    {% if label %}
      <span class="metafield-label">{{ label }}:</span>
    {% endif %}

    <div class="metafield-value">
      {% case metafield.type %}
        {% when 'single_line_text_field' or 'multi_line_text_field' %}
          <p>{{ metafield.value }}</p>

        {% when 'number_integer' or 'number_decimal' %}
          <span class="metafield-number">{{ metafield.value }}</span>

        {% when 'date' %}
          <time datetime="{{ metafield.value }}">
            {{ metafield.value | date: '%B %d, %Y' }}
          </time>

        {% when 'url' %}
          <a href="{{ metafield.value }}" 
             target="_blank" 
             rel="noopener noreferrer"
             class="metafield-link">
            {{ metafield.value }}
          </a>

        {% when 'boolean' %}
          <span class="metafield-boolean">
            {% if metafield.value %}
              <svg width="20" height="20" viewBox="0 0 20 20" fill="none">
                <path d="M7 10L9 12L13 8" stroke="#10b981" stroke-width="2"/>
                <circle cx="10" cy="10" r="9" stroke="#10b981" stroke-width="2"/>
              </svg>
              Yes
            {% else %}
              <svg width="20" height="20" viewBox="0 0 20 20" fill="none">
                <path d="M7 7L13 13M13 7L7 13" stroke="#ef4444" stroke-width="2"/>
                <circle cx="10" cy="10" r="9" stroke="#ef4444" stroke-width="2"/>
              </svg>
              No
            {% endif %}
          </span>

        {% when 'color' %}
          <div class="metafield-color">
            <span class="color-swatch" 
                  style="background-color: {{ metafield.value }}"></span>
            <span class="color-code">{{ metafield.value }}</span>
          </div>

        {% when 'file_reference' %}
          {% if metafield.value.content_type contains 'image' %}
            <img src="{{ metafield.value | img_url: 'medium' }}" 
                 alt="{{ metafield.value.alt }}"
                 class="metafield-image"
                 loading="lazy">
          {% elsif metafield.value.content_type contains 'video' %}
            <video controls class="metafield-video">
              <source src="{{ metafield.value.sources[0].url }}" 
                      type="{{ metafield.value.sources[0].mime_type }}">
            </video>
          {% else %}
            <a href="{{ metafield.value.url }}" 
               download
               class="metafield-download">
              Download {{ metafield.value.filename }}
            </a>
          {% endif %}

        {% when 'list.single_line_text_field' %}
          <ul class="metafield-list">
            {% for item in metafield.value %}
              <li>{{ item }}</li>
            {% endfor %}
          </ul>

        {% when 'product_reference' %}
          {% assign ref_product = metafield.value %}
          <div class="metafield-product-ref">
            <a href="{{ ref_product.url }}">
              <img src="{{ ref_product.featured_image | img_url: '100x' }}" 
                   alt="{{ ref_product.title }}">
              <span>{{ ref_product.title }}</span>
            </a>
          </div>

        {% when 'json' %}
          <pre class="metafield-json">{{ metafield.value | json }}</pre>

        {% else %}
          <span>{{ metafield.value }}</span>
      {% endcase %}
    </div>
  </div>

  <style>
  .metafield-wrapper {
    margin: 16px 0;
    display: flex;
    gap: 12px;
    align-items: flex-start;
  }

  .metafield-label {
    font-weight: 600;
    color: #374151;
    min-width: 120px;
  }

  .metafield-value {
    flex: 1;
  }

  .metafield-link {
    color: #3b82f6;
    text-decoration: underline;
  }

  .metafield-boolean {
    display: inline-flex;
    align-items: center;
    gap: 8px;
  }

  .metafield-color {
    display: flex;
    align-items: center;
    gap: 12px;
  }

  .color-swatch {
    width: 32px;
    height: 32px;
    border-radius: 6px;
    border: 2px solid #e5e7eb;
  }

  .color-code {
    font-family: monospace;
    font-size: 14px;
    color: #6b7280;
  }

  .metafield-image {
    max-width: 300px;
    border-radius: 8px;
  }

  .metafield-list {
    list-style: disc;
    padding-left: 20px;
    margin: 0;
  }

  .metafield-list li {
    margin: 4px 0;
  }

  .metafield-product-ref a {
    display: flex;
    align-items: center;
    gap: 12px;
    text-decoration: none;
    color: inherit;
  }

  .metafield-product-ref img {
    width: 60px;
    height: 60px;
    object-fit: cover;
    border-radius: 6px;
  }

  .metafield-json {
    background: #f3f4f6;
    padding: 12px;
    border-radius: 6px;
    font-size: 12px;
    overflow-x: auto;
  }
  </style>
{% endif %}

Usage

{% render 'metafields-display', resource: product, namespace: 'custom', key: 'material', label: 'Material' %}

Installation

Add to snippets/metafields-display.liquid

Let’s Build Something You’ll Be Proud Of

No fluff. Just thoughtful design and reliable development.

Work with me
Average response time: within 24 hours