Marketing & Social

Free Logo Cloud Widget

A "Trusted by" logo row with grayscale-to-color hover, from one script tag.

The Logo Cloud widget renders a clean "Trusted by" row of client, partner, or press logos on any website. It's ideal for landing pages, agencies, and SaaS sites that want instant social proof. Paste one script tag with your logos as a JSON list and the row appears exactly where you placed it.

Live demo

Embed this widget

Paste either snippet into your page — a Custom HTML block on WordPress, Shopify, or Squarespace works too. Both snippets update live as you customize, so what you copy is exactly what you configured.

Hosted (recommended)html
<script src="https://hayneslab.dev/widgets/logo-cloud.js" data-hl-config='[{"src":"https://placehold.co/140x40/1f2937/ffffff/png?text=Acme","alt":"Acme Corp"},{"src":"https://placehold.co/140x40/0e7490/ffffff/png?text=Northwind","alt":"Northwind"},{"src":"https://placehold.co/140x40/7c3aed/ffffff/png?text=Vertex","alt":"Vertex Labs"},{"src":"https://placehold.co/140x40/b91c1c/ffffff/png?text=Harbor","alt":"Harbor & Co"},{"src":"https://placehold.co/140x40/047857/ffffff/png?text=Lumen","alt":"Lumen Studio"}]' async></script>
<!-- Free Logo Cloud widget by haynes lab — https://hayneslab.dev/tools/widgets/logo-cloud -->
Inline (self-contained)html
<!-- Free Logo Cloud widget by haynes lab — https://hayneslab.dev/tools/widgets/logo-cloud -->
<script data-hl-config='[{"src":"https://placehold.co/140x40/1f2937/ffffff/png?text=Acme","alt":"Acme Corp"},{"src":"https://placehold.co/140x40/0e7490/ffffff/png?text=Northwind","alt":"Northwind"},{"src":"https://placehold.co/140x40/7c3aed/ffffff/png?text=Vertex","alt":"Vertex Labs"},{"src":"https://placehold.co/140x40/b91c1c/ffffff/png?text=Harbor","alt":"Harbor & Co"},{"src":"https://placehold.co/140x40/047857/ffffff/png?text=Lumen","alt":"Lumen Studio"}]'>
/*!
 * haynes lab — Logo Cloud widget (free)
 * Docs & embed code: https://hayneslab.dev/tools/widgets/logo-cloud
 */
(function () {
  'use strict';

  var PREFIX = 'hlw-logo-cloud';
  var STYLE_ID = 'hlw-logo-cloud-styles';

  function findScript() {
    return document.currentScript ||
      document.querySelector('script[src*="widgets/logo-cloud.js"]');
  }

  function injectStyles() {
    if (document.getElementById(STYLE_ID)) return;
    var css =
      '.' + PREFIX + ', .' + PREFIX + ' * { box-sizing: border-box; }' +
      '.' + PREFIX + ' { position: relative; max-width: 960px; margin: 0 auto; padding: 28px 32px 34px;' +
      ' font-family: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;' +
      ' font-size: 16px; line-height: 1.5; color: #1f2937; background: #ffffff;' +
      ' border: 1px solid #e5e7eb; border-radius: 12px; text-align: center; }' +
      '.' + PREFIX + '__title { margin: 0 0 20px; font-size: 13px; font-weight: 600;' +
      ' letter-spacing: 0.08em; text-transform: uppercase; color: #6b7280; }' +
      '.' + PREFIX + '__row { display: flex; flex-wrap: wrap; align-items: center;' +
      ' justify-content: center; gap: 20px 36px; }' +
      '.' + PREFIX + '__item { display: inline-flex; align-items: center; justify-content: center;' +
      ' text-decoration: none; border-radius: 6px; }' +
      'a.' + PREFIX + '__item:focus-visible { outline: 2px solid #f97316; outline-offset: 3px; }' +
      '.' + PREFIX + '__logo { display: block; height: 34px; width: auto; max-width: 140px; object-fit: contain; }' +
      '.' + PREFIX + '--grayscale .' + PREFIX + '__logo { filter: grayscale(1); opacity: 0.65;' +
      ' transition: filter 0.25s ease, opacity 0.25s ease; }' +
      '.' + PREFIX + '--grayscale .' + PREFIX + '__item:hover .' + PREFIX + '__logo,' +
      '.' + PREFIX + '--grayscale .' + PREFIX + '__item:focus-visible .' + PREFIX + '__logo {' +
      ' filter: grayscale(0); opacity: 1; }' +
      '.' + PREFIX + '__credit { position: absolute; right: 10px; bottom: 6px; font-size: 11px;' +
      ' display: inline-flex; align-items: center; gap: 4px; color: #9ca3af; text-decoration: none; }' +
      '.' + PREFIX + '__credit svg { display: block; }' +
      '.' + PREFIX + '__credit:hover { color: #6b7280; text-decoration: underline; }' +
      '@media (max-width: 560px) { .' + PREFIX + ' { padding: 22px 20px 32px; }' +
      ' .' + PREFIX + '__row { gap: 16px 24px; }' +
      ' .' + PREFIX + '__logo { height: 26px; max-width: 110px; } }';
    var style = document.createElement('style');
    style.id = STYLE_ID;
    style.textContent = css;
    document.head.appendChild(style);
  }

  function parseLogos(script) {
    var raw = script.getAttribute('data-hl-config');
    if (!raw) {
      console.warn('[haynes lab logo-cloud] Missing required data-hl-config attribute (JSON array of {src, alt, href}). Nothing rendered.');
      return null;
    }
    var items;
    try {
      items = JSON.parse(raw);
    } catch (e) {
      console.warn('[haynes lab logo-cloud] data-hl-config is not valid JSON. Nothing rendered.', e);
      return null;
    }
    if (!Array.isArray(items)) {
      console.warn('[haynes lab logo-cloud] data-hl-config must be a JSON array. Nothing rendered.');
      return null;
    }
    var valid = items.filter(function (t) {
      return t && typeof t.src === 'string' && t.src;
    });
    if (!valid.length) {
      console.warn('[haynes lab logo-cloud] data-hl-config has no valid logos (each needs at least "src"). Nothing rendered.');
      return null;
    }
    return valid;
  }

  function el(tag, className, text) {
    var node = document.createElement(tag);
    if (className) node.className = className;
    if (text != null) node.textContent = text;
    return node;
  }

  function logoSvg() {
    var svgNS = 'http://www.w3.org/2000/svg';
    var svg = document.createElementNS(svgNS, 'svg');
    svg.setAttribute('viewBox', '0 0 32 32');
    svg.setAttribute('width', '13');
    svg.setAttribute('height', '13');
    svg.setAttribute('aria-hidden', 'true');
    svg.setAttribute('focusable', 'false');
    function circle(cx, cy, r, attrs) {
      var c = document.createElementNS(svgNS, 'circle');
      c.setAttribute('cx', cx);
      c.setAttribute('cy', cy);
      c.setAttribute('r', r);
      for (var key in attrs) c.setAttribute(key, attrs[key]);
      svg.appendChild(c);
    }
    circle(16, 16, 16, { fill: '#0f0a0a' });
    circle(16, 16, 12, { fill: 'none', stroke: '#fff5f5', 'stroke-width': 1, opacity: 0.3 });
    circle(16, 16, 9, { fill: 'none', stroke: '#fff5f5', 'stroke-width': 1, opacity: 0.5 });
    circle(16, 16, 6, { fill: 'none', stroke: '#fff5f5', 'stroke-width': 1.2, opacity: 0.9 });
    circle(16, 16, 3, { fill: '#06b6d4' });
    circle(24.5, 7.5, 2, { fill: '#f97316' });
    circle(7, 16, 1.8, { fill: '#f97316' });
    circle(20, 20, 1.5, { fill: '#f97316' });
    return svg;
  }

  function build(script) {
    var items = parseLogos(script);
    if (!items) return;

    var title = script.getAttribute('data-hl-title');
    if (title === null) title = 'Trusted by';
    var grayscale = script.getAttribute('data-hl-grayscale') !== 'false';

    injectStyles();

    var root = el('div', PREFIX + (grayscale ? ' ' + PREFIX + '--grayscale' : ''));
    root.setAttribute('role', 'region');
    root.setAttribute('aria-label', title || 'Partner logos');

    if (title) root.appendChild(el('p', PREFIX + '__title', title));

    var row = el('div', PREFIX + '__row');
    items.forEach(function (t) {
      var img = el('img', PREFIX + '__logo');
      img.src = t.src;
      img.alt = typeof t.alt === 'string' ? t.alt : '';
      img.loading = 'lazy';
      var item;
      if (typeof t.href === 'string' && t.href) {
        item = el('a', PREFIX + '__item');
        item.href = t.href;
        item.target = '_blank';
        item.rel = 'noopener';
        if (img.alt) item.setAttribute('aria-label', img.alt);
      } else {
        item = el('span', PREFIX + '__item');
      }
      item.appendChild(img);
      row.appendChild(item);
    });
    root.appendChild(row);

    var credit = el('a', PREFIX + '__credit');
    credit.appendChild(logoSvg());
    credit.appendChild(document.createTextNode('Powered by haynes lab'));
    credit.href = 'https://hayneslab.dev/tools/widgets/logo-cloud';
    credit.target = '_blank';
    credit.rel = 'noopener';
    root.appendChild(credit);

    if (script.parentNode && script.parentNode.nodeName !== 'HEAD') {
      script.insertAdjacentElement('afterend', root);
    } else {
      document.body.appendChild(root);
    }
  }

  function init() {
    var script = findScript();
    if (!script) {
      console.warn('[haynes lab logo-cloud] Could not locate its own script tag. Nothing rendered.');
      return;
    }
    build(script);
  }

  if (document.body) {
    init();
  } else {
    document.addEventListener('DOMContentLoaded', init);
  }
})();

</script>

Configuration

Every option is an attribute on the script tag — the same attributes the customizer above exposes. All attributes are optional unless marked required — defaults apply when omitted.

AttributeDefaultDescription
data-hl-config(required)JSON array of logo objects with "src" (image URL), "alt" (name), and optional "href" (link).
data-hl-title"Trusted by"Heading text shown above the logos; set to an empty string to hide it.
data-hl-grayscale"true"Set to "false" to show logos in full color instead of grayscale that colors on hover.

Frequently asked questions

How do I install the Logo Cloud?

Paste the script tag snippet wherever you want the logo row to appear on your page — the widget renders inline at that exact spot. Put your logos in the data-hl-config attribute as a JSON array of {"src", "alt", "href"} objects.

Can I change the heading or the grayscale effect?

Yes. Use data-hl-title to change the heading text (set it to an empty string to hide it), and set data-hl-grayscale="false" to show logos in full color with no hover effect. Each logo can also link out via its "href" field.

Does it work on WordPress, Shopify, or Squarespace?

Yes — it's a single vanilla JavaScript file with no dependencies, so it works on any platform that lets you embed a script tag, including WordPress, Shopify, Squarespace, Wix, and plain HTML sites.

More free widgets

Need a custom widget?

We build custom widgets, integrations, and whole products. Tell us what your site needs and we'll scope it.

Get in Touch