Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.pixcraft.es/llms.txt

Use this file to discover all available pages before exploring further.

Shopify Integration

This guide shows how to integrate the PixCraft API into a Shopify store using a combination of Liquid templates and JavaScript.

Architecture

Since Shopify doesn’t allow server-side API calls from Liquid, you’ll need a small backend proxy:
  1. Backend proxy (Node.js, PHP, or serverless function) — holds your API key and calls PixCraft
  2. Shopify theme snippet — shows the configurator UI on product pages
  3. JavaScript — handles user interaction and calls your proxy

Step 1: Create a backend proxy

Deploy a simple serverless function (Vercel, Netlify, or Cloudflare Workers):
// api/pixcraft-proxy.js (Vercel serverless function)
export default async function handler(req, res) {
  if (req.method !== 'POST') return res.status(405).end();

  const response = await fetch('https://www.pixcraft.es/api/v1/generate', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.PIXCRAFT_API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(req.body),
  });

  const data = await response.json();
  res.status(response.status).json(data);
}

Step 2: Add the Liquid snippet

Create snippets/pixcraft-configurator.liquid:
{% comment %}
  PixCraft Pattern Configurator
  Include on product pages: {% render 'pixcraft-configurator' %}
{% endcomment %}

<div id="pixcraft-configurator" style="margin: 20px 0; padding: 20px; border: 1px solid #e5e5e5; border-radius: 8px;">
  <h3 style="margin-bottom: 12px;">Design Your Pattern</h3>

  <div style="margin-bottom: 12px;">
    <label for="pixcraft-image">Upload your image:</label>
    <input type="file" id="pixcraft-image" accept="image/jpeg,image/png,image/webp">
  </div>

  <div style="display: flex; gap: 12px; margin-bottom: 12px;">
    <div>
      <label for="pixcraft-width">Width (cm):</label>
      <input type="number" id="pixcraft-width" value="100" min="10" max="1000">
    </div>
    <div>
      <label for="pixcraft-height">Height (cm):</label>
      <input type="number" id="pixcraft-height" value="100" min="10" max="1000">
    </div>
  </div>

  <button id="pixcraft-generate-btn" class="btn btn--primary">
    Generate Pattern
  </button>

  <div id="pixcraft-result" style="margin-top: 16px; display: none;">
    <h4>Your Pattern</h4>
    <div id="pixcraft-summary"></div>
    <div id="pixcraft-materials"></div>
  </div>
</div>

<script>
  const PROXY_URL = 'https://your-proxy.vercel.app/api/pixcraft-proxy';

  document.getElementById('pixcraft-generate-btn').addEventListener('click', async () => {
    const fileInput = document.getElementById('pixcraft-image');
    const file = fileInput.files[0];
    if (!file) return alert('Please select an image');

    const reader = new FileReader();
    reader.onload = async (e) => {
      const base64 = e.target.result.split(',')[1];

      const btn = document.getElementById('pixcraft-generate-btn');
      btn.disabled = true;
      btn.textContent = 'Generating...';

      try {
        const response = await fetch(PROXY_URL, {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            image: base64,
            niche: '{{ product.metafields.pixcraft.niche | default: "mosaics" }}',
            width_cm: parseInt(document.getElementById('pixcraft-width').value),
            height_cm: parseInt(document.getElementById('pixcraft-height').value),
          }),
        });

        const data = await response.json();

        if (data.success) {
          document.getElementById('pixcraft-result').style.display = 'block';
          document.getElementById('pixcraft-summary').innerHTML = `
            <p>${data.dimensions.cols} × ${data.dimensions.rows} grid (${data.dimensions.total_units} units)</p>
          `;
          document.getElementById('pixcraft-materials').innerHTML = data.materials.map(m =>
            `<div style="display:flex;align-items:center;gap:8px;margin:4px 0;">
              <span style="width:16px;height:16px;background:${m.hex};border:1px solid #ccc;border-radius:2px;display:inline-block;"></span>
              ${m.color_name}: ${m.quantity} (${m.percentage}%)
            </div>`
          ).join('');
        }
      } catch (err) {
        alert('Error generating pattern');
      }

      btn.disabled = false;
      btn.textContent = 'Generate Pattern';
    };
    reader.readAsDataURL(file);
  });
</script>

Step 3: Include in your product template

In sections/product-template.liquid or your product page template:
{% render 'pixcraft-configurator' %}

Step 4: Product metafields (optional)

Use Shopify metafields to configure which niche each product uses:
  1. Go to Settings → Custom data → Products
  2. Add a metafield: namespace pixcraft, key niche, type single line text
  3. Set the niche ID (e.g., mosaics, curtains) on each product
The Liquid snippet reads this via {{ product.metafields.pixcraft.niche }}.

Security note

Never expose your PixCraft API key in client-side code. Always route requests through your backend proxy.