HTML & frameworks · 5 min read
How to embed Google reviews in HTML
If you control the markup, this is the shortest path there is: one script tag in the body, at the point the reviews should appear. It works the same on a hand-written HTML page, a Hugo template, an Astro layout or a React component.
Last reviewed by the Reviews Widget product team.
What the snippet actually does
The tag loads a small async script carrying your grid ID. It creates a shadow root at that point in the DOM, renders your reviews inside it, and injects matching JSON-LD. Shadow isolation is why your site's CSS cannot leak in and the widget's CSS cannot leak out.
Google reviews HTML, no plugin required
Getting the embed code for your Google reviews takes one click: open the Embed tab on your grid and copy the script tag. That tag is the whole integration. Because it is ordinary HTML, you can embed Google reviews on a website with no plugin, no CMS extension and no package to install — the same line works in a hand-written page, a Webflow custom code block, a Shopify theme file or a React component.
If you've been searching for a way to embed Google reviews on a website without a plugin, this is it — there's no WordPress plugin to update, no app subscription inside your CMS and nothing that breaks when the platform upgrades. The widget lives on our infrastructure; your page only ever holds the tag.
The Google review embed code carries only your grid ID, so nothing sensitive sits in your markup, and changing layout or colours later updates every page using that grid without you editing a single file. If you would rather follow a platform-specific walkthrough, start from the how-to guides.
Step-by-step for a plain HTML page
Skip the reading — build your widget now
Free plan, no credit card. Your reviews are embedded before you finish this guide.
- 1
Create your free Reviews Widget
Sign up, search your business name to attach your Google Business Profile, and let the first fetch pull in your reviews and aggregate rating.
- 2
Style the widget
Choose a layout and set colours, corner radius and font scale to match your site, using the live preview at desktop, tablet and mobile widths.
- 3
Copy the embed snippet
Open the Embed tab and copy the one-line script tag, which carries your grid ID as a data attribute.
- 4
Open your HTML file
Open the page in your editor and find the exact place in the body where the reviews should appear.
- 5
Paste the script tag
Paste the tag at that point in the markup. The widget renders in place, so its position in the body is its position on the page.
- 6
Deploy and verify
Upload or deploy the file, open the live URL, and confirm the reviews render.
- 7
Check the structured data
Run the live URL through Google's Rich Results Test to confirm the injected JSON-LD parses without errors.
React, Next.js, Astro and static generators
| Stack | Where it goes | Note |
|---|---|---|
| Plain HTML | Directly in the body | Renders exactly where the tag sits |
| React (Vite, CRA) | Append the script to a ref'd div in useEffect | Survives hydration and re-renders |
| Next.js | next/script, or a client component | Avoid rendering the tag during SSR output only |
| Astro | Directly in the .astro template | Astro emits it as static HTML |
| Hugo / Jekyll | In a layout, partial or include | Shared partial gives sitewide placement |
| Vue / Nuxt | onMounted, appending the script element | Same pattern as React's useEffect |
In any framework that hydrates, append the script element from a mount effect rather than rendering it as JSX. A script tag written as JSX is inert — React will not execute it — which is the most common reason a framework embed silently does nothing.
Performance and CSP notes
| Concern | Behaviour | What to do |
|---|---|---|
| Render blocking | The script loads asynchronously | Nothing required |
| Layout shift | The widget has no height until reviews load | Set a min-height on the wrapper |
| Style collisions | Shadow root isolates all styles | Restyle in the dashboard, not with site CSS |
| Strict CSP | Blocked scripts fail silently | Allow the widget origin in script-src and connect-src |
| Below-the-fold placement | Still loads on page load | Fine — the payload is small |
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Nothing renders, no console error | Script tag rendered as JSX in a framework | Append the script element in a mount effect |
| Console shows a CSP violation | Strict Content Security Policy | Allow the widget origin in script-src |
| Reviews appear at the wrong place | Tag placed in the head | Move the tag into the body where it belongs |
| Content jumps as reviews load | No reserved height | Add a min-height to the wrapping element |
| Widget missing in a browser but not others | Ad blocker or tracking protection | Test in a clean browser profile |
| Duplicated widget | Script appended twice by a re-render | Guard the effect so it runs once |
Sources & further reading
- MDN — the script element and async loading — How async script loading behaves
- web.dev — Cumulative Layout Shift — Why reserving height matters
- Google Search Central — review snippet guidelines — Self-serving review rules