Marketing & Social

Free Google Reviews Badge Widget

Show your Google rating, stars, and review count in one compact badge.

A compact badge that displays your business name, Google star rating, and review count, with a link straight to your Google profile. Ideal for local businesses, agencies, and service providers that want instant social proof in a header, footer, or contact page. Paste one script tag, set your rating and profile link, and it renders inline.

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/google-reviews-badge.js" data-hl-rating="4.9" data-hl-count="187" data-hl-business="Haynes Lab" data-hl-link="https://www.google.com/maps/search/haynes+lab" async></script>
<!-- Free Google Reviews Badge widget by haynes lab — https://hayneslab.dev/tools/widgets/google-reviews-badge -->
Inline (self-contained)html
<!-- Free Google Reviews Badge widget by haynes lab — https://hayneslab.dev/tools/widgets/google-reviews-badge -->
<script data-hl-rating="4.9" data-hl-count="187" data-hl-business="Haynes Lab" data-hl-link="https://www.google.com/maps/search/haynes+lab">
/*!
 * haynes lab — Google Reviews Badge widget (free)
 * Docs & embed code: https://hayneslab.dev/tools/widgets/google-reviews-badge
 */
(function () {
  'use strict';

  var PREFIX = 'hlw-google-reviews-badge';
  var STYLE_ID = 'hlw-google-reviews-badge-styles';
  var STAR_PATH = 'M12 2.6l2.8 6.2 6.7.7-5 4.5 1.4 6.6-5.9-3.4-5.9 3.4 1.4-6.6-5-4.5 6.7-.7z';

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

  function injectStyles() {
    if (document.getElementById(STYLE_ID)) return;
    var css =
      '.' + PREFIX + ', .' + PREFIX + ' * { box-sizing: border-box; }' +
      '.' + PREFIX + ' { display: inline-block; position: relative;' +
      ' font-family: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;' +
      ' font-size: 14px; line-height: 1.4; color: #1f2937; }' +
      '.' + PREFIX + '__card { display: inline-flex; align-items: center; gap: 12px;' +
      ' padding: 10px 16px; background: #ffffff; border: 1px solid #e5e7eb; border-radius: 12px;' +
      ' color: inherit; text-decoration: none; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); }' +
      'a.' + PREFIX + '__card:hover { border-color: #d1d5db; }' +
      'a.' + PREFIX + '__card:focus-visible { outline: 2px solid #4285f4; outline-offset: 2px; }' +
      '.' + PREFIX + '__gmark { display: inline-flex; align-items: center; justify-content: center;' +
      ' width: 38px; height: 38px; padding: 2px; border-radius: 50%; flex: 0 0 auto;' +
      ' background: conic-gradient(#4285f4 0deg 90deg, #34a853 90deg 180deg, #fbbc05 180deg 270deg, #ea4335 270deg 360deg); }' +
      '.' + PREFIX + '__gmark-letter { display: flex; align-items: center; justify-content: center;' +
      ' width: 100%; height: 100%; border-radius: 50%; background: #ffffff;' +
      ' color: #4285f4; font-weight: 700; font-size: 20px; line-height: 1; }' +
      '.' + PREFIX + '__body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }' +
      '.' + PREFIX + '__business { font-weight: 600; font-size: 14px; color: #111827; }' +
      '.' + PREFIX + '__row { display: inline-flex; align-items: center; gap: 6px; }' +
      '.' + PREFIX + '__stars { display: inline-flex; gap: 1px; }' +
      '.' + PREFIX + '__star { position: relative; width: 14px; height: 14px; flex: 0 0 auto; }' +
      '.' + PREFIX + '__star svg { display: block; width: 14px; height: 14px; }' +
      '.' + PREFIX + '__star-fill { position: absolute; top: 0; left: 0; height: 100%; overflow: hidden; }' +
      '.' + PREFIX + '__score { font-weight: 700; font-size: 13px; color: #111827; }' +
      '.' + PREFIX + '__count { font-size: 12px; color: #6b7280; white-space: nowrap; }' +
      '.' + PREFIX + '__credit { display: block; margin-top: 4px; text-align: right; font-size: 11px;' +
      ' color: #9ca3af; text-decoration: none; }' +
      '.' + PREFIX + '__credit svg { display: inline-block; vertical-align: -2px; margin-right: 4px; }' +
      '.' + PREFIX + '__credit:hover { color: #6b7280; text-decoration: underline; }';
    var style = document.createElement('style');
    style.id = STYLE_ID;
    style.textContent = css;
    document.head.appendChild(style);
  }

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

  function starSvg(fill) {
    var svgNS = 'http://www.w3.org/2000/svg';
    var svg = document.createElementNS(svgNS, 'svg');
    svg.setAttribute('viewBox', '0 0 24 24');
    svg.setAttribute('aria-hidden', 'true');
    svg.setAttribute('focusable', 'false');
    var path = document.createElementNS(svgNS, 'path');
    path.setAttribute('d', STAR_PATH);
    path.setAttribute('fill', fill);
    svg.appendChild(path);
    return svg;
  }

  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 rating = parseFloat(script.getAttribute('data-hl-rating'));
    if (isNaN(rating)) {
      console.warn('[haynes lab google-reviews-badge] Missing or invalid required data-hl-rating attribute (a number from 0 to 5). Nothing rendered.');
      return;
    }
    rating = Math.max(0, Math.min(5, rating));
    var score = Math.round(rating * 10) / 10;

    var countRaw = script.getAttribute('data-hl-count');
    var count = null;
    if (countRaw != null && countRaw !== '') {
      count = parseInt(countRaw, 10);
      if (isNaN(count) || count < 0) {
        console.warn('[haynes lab google-reviews-badge] data-hl-count is not a valid non-negative number. Review count hidden.');
        count = null;
      }
    }

    var business = script.getAttribute('data-hl-business') || 'Google Reviews';
    var link = script.getAttribute('data-hl-link');

    var summary = business + ': rated ' + score + ' out of 5 on Google' +
      (count != null ? ' based on ' + count + (count === 1 ? ' review' : ' reviews') : '');

    injectStyles();

    var root = el('span', PREFIX);

    var card = el(link ? 'a' : 'span', PREFIX + '__card');
    if (link) {
      card.href = link;
      card.target = '_blank';
      card.rel = 'noopener';
      card.setAttribute('aria-label', summary + ' — read reviews on Google');
    }

    var gmark = el('span', PREFIX + '__gmark');
    gmark.setAttribute('aria-hidden', 'true');
    gmark.appendChild(el('span', PREFIX + '__gmark-letter', 'G'));
    card.appendChild(gmark);

    var body = el('span', PREFIX + '__body');
    body.appendChild(el('span', PREFIX + '__business', business));

    var row = el('span', PREFIX + '__row');
    var stars = el('span', PREFIX + '__stars');
    stars.setAttribute('role', 'img');
    stars.setAttribute('aria-label', 'Rated ' + score + ' out of 5');
    for (var i = 0; i < 5; i++) {
      var star = el('span', PREFIX + '__star');
      star.appendChild(starSvg('#e5e7eb'));
      var pct = Math.max(0, Math.min(1, rating - i)) * 100;
      if (pct > 0) {
        var fill = el('span', PREFIX + '__star-fill');
        fill.style.width = pct + '%';
        fill.appendChild(starSvg('#fbbc05'));
        star.appendChild(fill);
      }
      stars.appendChild(star);
    }
    row.appendChild(stars);
    row.appendChild(el('span', PREFIX + '__score', score.toFixed(1)));
    if (count != null) {
      row.appendChild(el('span', PREFIX + '__count',
        '(' + count + (count === 1 ? ' review' : ' reviews') + ')'));
    }
    body.appendChild(row);
    card.appendChild(body);
    root.appendChild(card);

    var credit = el('a', PREFIX + '__credit');
    credit.appendChild(logoSvg());
    credit.appendChild(document.createTextNode('Powered by haynes lab'));
    credit.href = 'https://hayneslab.dev/tools/widgets/google-reviews-badge';
    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 google-reviews-badge] 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-rating(required)Your Google rating from 0 to 5. Decimals are supported and partial stars are filled accordingly.
data-hl-count(none)Number of Google reviews shown next to the score. Omit to hide the count.
data-hl-business"Google Reviews"Business name shown on the badge. Falls back to "Google Reviews" when omitted.
data-hl-link(none)URL of your Google Business Profile or reviews page the badge links to. Omit for a static badge.

Frequently asked questions

How do I install the Google reviews badge?

Copy the embed snippet and paste it where you want the badge to appear on your page. The widget renders inline right after the script tag — in a footer, sidebar, header, or next to your contact details.

How do I customize the rating, count, and link?

Everything is set through data-hl-* attributes on the script tag. Set data-hl-rating (decimals like 4.9 fill stars partially), data-hl-count for the review total, data-hl-business for your business name, and data-hl-link to your Google Business Profile so visitors can read or leave reviews.

Does it work on WordPress, Shopify, or Squarespace?

Yes. The widget is a single dependency-free vanilla JS file, so it runs anywhere you can paste a script tag — WordPress, Shopify (theme.liquid or a custom liquid block), Squarespace code injection, Webflow, or plain HTML.

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