Printful API based Storefront

I have a hobby site for my podcast and I’m trying to implement a storefront with products that I already have on Printful. I’m not the best with Javascript but I’m trying!

Some upfront facts: I’m using hugo for an SSG, hosting on Gitlab, and deploying through Netlify. Netlify is also handling my backend function stuff. I’m using Snipcart to handle processing transactions and shopping cart stuff.

Link to website: Lutheran Answers

Link to individual product page: Cool Dad Hat

This will be easiest to map out in English first, then I’ll show you some code.

When the product page loads the first API kicks off and pulls the specific product information (as specified in front matter of the content file).

The main product and its image/price/etc are loaded into the page. I’ve also managed to cobble together some (I’m sure very ugly) code that creates a select box with variant dropdowns.

The goal is that when you change variants in the select box, the picture updates to reflect the variant selected, as does the price, and the snipcart button.

I’m really just looking for ideas on how I can make that happen?

I’m also open to improving my code, slimming it down, making it a bit more DRY, etc.

Here is the code I have that’s running things at the moment. There is a bit of GO in there so that it will pull a specific product instead of every product.

  document.addEventListener('DOMContentLoaded', async () => {
    const response = await fetch('/.netlify/functions/products'{{- with .Params.product -}}, {
      method: 'POST',
      body: "{{ . }}"
    }{{- end -}}).then(response => response.json())

    const product = response.result
    const img = document.getElementById('mockup')
    const cart = document.getElementById('cart')
    var sel = document.getElementById("productOptions");

    product.sync_variants.forEach(function(obj) { 
      var opt = document.createElement("option");
      opt.value = obj.id;
      opt.text = obj.name;
      sel.add(opt);
    });

    img.src = product.sync_product.thumbnail_url
    cart.setAttribute("data-item-image", product.sync_product.thumbnail_url)
    cart.setAttribute("data-item-id", product.sync_variants[0].id)
    cart.setAttribute("data-item-price", product.sync_variants[0].retail_price)
    document.getElementById('price').innerHTML = product.sync_variants[0].retail_price

  });

Here’s the JSON object that the API grabs for this specific page:

{
   "code":200,
   "result":{
      "sync_product":{
         "id":261109299,
         "external_id":"61c88af2f35987",
         "name":"Awesome Luther Rose Dad Hat",
         "variants":3,
         "synced":3,
         "thumbnail_url":"https://files.cdn.printful.com/files/585/5859bc8b395605fc2555ab13ee18a13d_preview.png",
         "is_ignored":false
      },
      "sync_variants":[
         {
            "id":3053908626,
            "external_id":"61c88af2f35a88",
            "sync_product_id":261109299,
            "name":"Awesome Luther Rose Dad Hat - Black",
            "synced":true,
            "variant_id":7854,
            "warehouse_product_variant_id":null,
            "retail_price":"28.00",
            "sku":"61C88AF2F2C0F_Black",
            "currency":"USD",
            "product":{
               "variant_id":7854,
               "product_id":206,
               "image":"https://files.cdn.printful.com/products/206/7854_1584455281.jpg",
               "name":"Yupoong Unstructured Classic Dad Cap - 6245CM (Black)"
            },
            "files":[
               {
                  "id":321846523,
                  "type":"default",
                  "hash":"063e14ee3ce70055c36a1e6ff40d067b",
                  "url":null,
                  "filename":"Untitled-design.png",
                  "mime_type":"image/png",
                  "size":968104,
                  "width":3889,
                  "height":5000,
                  "dpi":278,
                  "status":"ok",
                  "created":1621198040,
                  "thumbnail_url":"https://files.cdn.printful.com/files/063/063e14ee3ce70055c36a1e6ff40d067b_thumb.png",
                  "preview_url":"https://files.cdn.printful.com/files/063/063e14ee3ce70055c36a1e6ff40d067b_preview.png",
                  "visible":true
               },
               {
                  "id":388907126,
                  "type":"preview",
                  "hash":"5859bc8b395605fc2555ab13ee18a13d",
                  "url":null,
                  "filename":"classic-dad-hat-black-front-61c88af02717c.jpg",
                  "mime_type":"image/jpeg",
                  "size":201992,
                  "width":1000,
                  "height":1000,
                  "dpi":null,
                  "status":"ok",
                  "created":1640532722,
                  "thumbnail_url":"https://files.cdn.printful.com/files/585/5859bc8b395605fc2555ab13ee18a13d_thumb.png",
                  "preview_url":"https://files.cdn.printful.com/files/585/5859bc8b395605fc2555ab13ee18a13d_preview.png",
                  "visible":false
               }
            ],
            "options":[
               {
                  "id":"embroidery_type",
                  "value":"flat"
               },
               {
                  "id":"thread_colors",
                  "value":[
                     
                  ]
               },
               {
                  "id":"text_thread_colors",
                  "value":[
                     
                  ]
               },
               {
                  "id":"thread_colors_3d",
                  "value":[
                     
                  ]
               },
               {
                  "id":"thread_colors_back",
                  "value":[
                     
                  ]
               },
               {
                  "id":"text_thread_colors_back",
                  "value":[
                     
                  ]
               },
               {
                  "id":"thread_colors_right",
                  "value":[
                     
                  ]
               },
               {
                  "id":"text_thread_colors_right",
                  "value":[
                     
                  ]
               },
               {
                  "id":"thread_colors_left",
                  "value":[
                     
                  ]
               },
               {
                  "id":"text_thread_colors_left",
                  "value":[
                     
                  ]
               }
            ],
            "is_ignored":false
         },
         {
            "id":3053908627,
            "external_id":"61c88af2f35ae8",
            "sync_product_id":261109299,
            "name":"Awesome Luther Rose Dad Hat - Navy",
            "synced":true,
            "variant_id":7857,
            "warehouse_product_variant_id":null,
            "retail_price":"28.00",
            "sku":"61C88AF2F2C0F_Navy",
            "currency":"USD",
            "product":{
               "variant_id":7857,
               "product_id":206,
               "image":"https://files.cdn.printful.com/products/206/7857_1584455384.jpg",
               "name":"Yupoong Unstructured Classic Dad Cap - 6245CM (Navy)"
            },
            "files":[
               {
                  "id":321846523,
                  "type":"default",
                  "hash":"063e14ee3ce70055c36a1e6ff40d067b",
                  "url":null,
                  "filename":"Untitled-design.png",
                  "mime_type":"image/png",
                  "size":968104,
                  "width":3889,
                  "height":5000,
                  "dpi":278,
                  "status":"ok",
                  "created":1621198040,
                  "thumbnail_url":"https://files.cdn.printful.com/files/063/063e14ee3ce70055c36a1e6ff40d067b_thumb.png",
                  "preview_url":"https://files.cdn.printful.com/files/063/063e14ee3ce70055c36a1e6ff40d067b_preview.png",
                  "visible":true
               },
               {
                  "id":388907127,
                  "type":"preview",
                  "hash":"34547008dc7e9ec8f78ecc6c6dce9cb9",
                  "url":null,
                  "filename":"classic-dad-hat-navy-front-61c88af027295.jpg",
                  "mime_type":"image/jpeg",
                  "size":207264,
                  "width":1000,
                  "height":1000,
                  "dpi":null,
                  "status":"ok",
                  "created":1640532722,
                  "thumbnail_url":"https://files.cdn.printful.com/files/345/34547008dc7e9ec8f78ecc6c6dce9cb9_thumb.png",
                  "preview_url":"https://files.cdn.printful.com/files/345/34547008dc7e9ec8f78ecc6c6dce9cb9_preview.png",
                  "visible":false
               }
            ],
            "options":[
               {
                  "id":"embroidery_type",
                  "value":"flat"
               },
               {
                  "id":"thread_colors",
                  "value":[
                     
                  ]
               },
               {
                  "id":"text_thread_colors",
                  "value":[
                     
                  ]
               },
               {
                  "id":"thread_colors_3d",
                  "value":[
                     
                  ]
               },
               {
                  "id":"thread_colors_back",
                  "value":[
                     
                  ]
               },
               {
                  "id":"text_thread_colors_back",
                  "value":[
                     
                  ]
               },
               {
                  "id":"thread_colors_right",
                  "value":[
                     
                  ]
               },
               {
                  "id":"text_thread_colors_right",
                  "value":[
                     
                  ]
               },
               {
                  "id":"thread_colors_left",
                  "value":[
                     
                  ]
               },
               {
                  "id":"text_thread_colors_left",
                  "value":[
                     
                  ]
               }
            ],
            "is_ignored":false
         },
         {
            "id":3053908628,
            "external_id":"61c88af2f35b46",
            "sync_product_id":261109299,
            "name":"Awesome Luther Rose Dad Hat - White",
            "synced":true,
            "variant_id":7853,
            "warehouse_product_variant_id":null,
            "retail_price":"28.00",
            "sku":"61C88AF2F2C0F_White",
            "currency":"USD",
            "product":{
               "variant_id":7853,
               "product_id":206,
               "image":"https://files.cdn.printful.com/products/206/7853_1584455533.jpg",
               "name":"Yupoong Unstructured Classic Dad Cap - 6245CM (White)"
            },
            "files":[
               {
                  "id":321846523,
                  "type":"default",
                  "hash":"063e14ee3ce70055c36a1e6ff40d067b",
                  "url":null,
                  "filename":"Untitled-design.png",
                  "mime_type":"image/png",
                  "size":968104,
                  "width":3889,
                  "height":5000,
                  "dpi":278,
                  "status":"ok",
                  "created":1621198040,
                  "thumbnail_url":"https://files.cdn.printful.com/files/063/063e14ee3ce70055c36a1e6ff40d067b_thumb.png",
                  "preview_url":"https://files.cdn.printful.com/files/063/063e14ee3ce70055c36a1e6ff40d067b_preview.png",
                  "visible":true
               },
               {
                  "id":388907128,
                  "type":"preview",
                  "hash":"a8095660e29c688e036e138c867941b0",
                  "url":null,
                  "filename":"classic-dad-hat-white-front-61c88af02737c.jpg",
                  "mime_type":"image/jpeg",
                  "size":243444,
                  "width":1000,
                  "height":1000,
                  "dpi":null,
                  "status":"ok",
                  "created":1640532722,
                  "thumbnail_url":"https://files.cdn.printful.com/files/a80/a8095660e29c688e036e138c867941b0_thumb.png",
                  "preview_url":"https://files.cdn.printful.com/files/a80/a8095660e29c688e036e138c867941b0_preview.png",
                  "visible":false
               }
            ],
            "options":[
               {
                  "id":"embroidery_type",
                  "value":"flat"
               },
               {
                  "id":"thread_colors",
                  "value":[
                     
                  ]
               },
               {
                  "id":"text_thread_colors",
                  "value":[
                     
                  ]
               },
               {
                  "id":"thread_colors_3d",
                  "value":[
                     
                  ]
               },
               {
                  "id":"thread_colors_back",
                  "value":[
                     
                  ]
               },
               {
                  "id":"text_thread_colors_back",
                  "value":[
                     
                  ]
               },
               {
                  "id":"thread_colors_right",
                  "value":[
                     
                  ]
               },
               {
                  "id":"text_thread_colors_right",
                  "value":[
                     
                  ]
               },
               {
                  "id":"thread_colors_left",
                  "value":[
                     
                  ]
               },
               {
                  "id":"text_thread_colors_left",
                  "value":[
                     
                  ]
               }
            ],
            "is_ignored":false
         }
      ]
   },
   "extra":[
      
   ]
}

And here’s the templating for the page itself (again, for Hugo, so there’s some GoLang stuff):

{{ define "main" }}

  <div class="content">

    <h1>
      {{ .Title }}
    </h1>

    <section class="product-group">
      <img id="mockup" class="product-image">
      <div class="product-details">
        <select id="productOptions">
          
        </select>
      </div>
    </section>

      Price: <span id="price"></span>

    <span class="spacer">

      {{ .Content }}

      <a id="cart" class="snipcart-add-item button-red"
        data-item-url="{{ $.Page.Permalink | relURL }}"
        data-item-description="{{ .Content }}"
        data-item-name="{{ $.Page.Title }}">
        Add to cart
      </a>

      {{ partial "social-share.html" . }}

  </div>

{{ end }}

Any ideas on how I can make this better or accomplish the goal of getting everything to link up?