Everything you need to get started with Beautimonial
Beautimonial is a smart testimonial widget for brands. Install it on your website and your customers can submit reviews and beautify them with one click.
The result: professional, polished testimonials that actually convert visitors into customers.
Install Widget
Customer Leaves Review
Testimonial Goes Live
When you sign up, Beautimonial drops you into a short guided setup β three steps from account to live widget. You can skip any step and finish it later from your dashboard.
Tell us about your business
Get & install your widget code
</head> tag) and save.<script src="https://beautimonial.com/widget.js?token=YOUR_TOKEN"></script>Verify your installation
When to use this: you write the HTML yourself β static sites, hand-built pages, or any platform with a custom HTML/JavaScript field.
<script src="https://beautimonial.com/widget.js?token=YOUR_TOKEN"></script>Where to paste: once per page, just before the closing </body> tag. Replace YOUR_TOKEN with the token from Dashboard β Widget Settings β Embed.
When to use this: a client-rendered React app with no framework script helper β Create React App, Vite, or a similar single-page setup. Using Next.js? Skip to 2.3.
Inject the tag from a component that stays mounted for the whole session β your top-level App, not an individual page. The guard is the important part: React 18 StrictMode runs effects twice in development, and re-renders must never append a second copy of the script.
// App.jsx
import { useEffect } from "react";
const WIDGET_SRC = "https://beautimonial.com/widget.js?token=YOUR_TOKEN";
export default function App() {
useEffect(() => {
// Already in the DOM? Do nothing β prevents a duplicate widget on
// re-render and on StrictMode's double-invoked effects.
if (document.querySelector(`script[src="${WIDGET_SRC}"]`)) return;
const script = document.createElement("script");
script.src = WIDGET_SRC;
script.async = true;
document.body.appendChild(script);
}, []);
return <YourRoutes />;
}Don't remove the script in an effect cleanup β the widget should live as long as the page does.
When to use this: any Next.js app, App Router or Pages Router. Next.js ships its own script loader, so use that instead of the useEffect pattern above.
Add it once in your root layout so it covers every route:
// app/layout.tsx (App Router)
import Script from "next/script";
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>
{children}
<Script
src="https://beautimonial.com/widget.js?token=YOUR_TOKEN"
strategy="afterInteractive"
/>
</body>
</html>
);
}On the Pages Router, put the same <Script> inside your pages/_app.tsx component.
Why not useEffect here: Next.js renders on the server first, then hydrates in the browser. The built-in <Script> component is built for that lifecycle β it loads the tag once, keeps it loaded across client-side navigations, and doesn't interfere with hydration. Hand-rolled useEffect injection in a Next.js app has to solve all of that itself, and the edge cases (double injection, route changes, hydration timing) are exactly what the built-in component already handles.
strategy="afterInteractive" loads the widget after the page becomes interactive. That's the right choice here β the widget isn't needed for your first paint, so it never competes with your own content for load time.When to use this: your site already has its own comment or review box, and you want the Beautify button to appear right inside it instead of a floating button that opens a popup. This is a second, separate script from 2.1 β different file, same token. You can run both.
#review-text or .review-form textarea. Until it's set, Widget Settings shows a reminder in place of the embed code β the script has nothing to attach to without it.<script src="https://beautimonial.com/inline-widget.js?token=YOUR_TOKEN"></script>Where to paste: just before the closing </body> tag. Put it on every page of your site, including your homepage β not just the pages with a comment box. It costs nothing on pages without one (the script finds no field and does nothing), and 2.7 needs it on your homepage to start a reply session. To find your selector: right-click the field on your site β Inspect β right-click the highlighted HTML β Copy β Copy selector.
The selector lives in your dashboard, not in the tag β so if you later restyle your form and its markup changes, the button quietly stops appearing. Update the selector in Widget Settings to match and it comes back. No code change, no redeploy.
When to use this: a client-rendered React app β Create React App, Vite, or similar. Using Next.js? Skip to 2.6. Set your comment box CSS selector first, exactly as in 2.4 β that part is the same everywhere.
Inject it the same way as 2.2 β from a component that stays mounted, with a guard against StrictMode's double-invoked effects. Your comment box doesn't have to exist yet: the widget watches the page and attaches its button whenever your field turns up, so a form behind a route change, a tab, a modal, or a βload commentsβ click is picked up automatically.
// App.jsx
import { useEffect } from "react";
const INLINE_SRC = "https://beautimonial.com/inline-widget.js?token=YOUR_TOKEN";
export default function App() {
useEffect(() => {
// Already in the DOM? Do nothing β prevents a duplicate script on
// re-render and on StrictMode's double-invoked effects.
if (document.querySelector(`script[src="${INLINE_SRC}"]`)) return;
const script = document.createElement("script");
script.src = INLINE_SRC;
script.async = true;
document.body.appendChild(script);
}, []);
return <YourRoutes />;
}One React-specific note worth knowing: the widget inserts its button as a plain DOM sibling immediately after your field. If React re-renders and replaces the field itself, the button is rebuilt alongside it automatically. The one case that doesn't self-heal is React removing the button while leaving your field in place β which takes a render that reaches between the two. Keeping the markup around your field stable (stable keys, no conditional re-mounting of the form wrapper) avoids it.
When to use this: any Next.js app, App Router or Pages Router, where your comment box is part of the server-rendered page. Set your comment box CSS selector first, as in 2.4.
Use next/script exactly as in 2.3. Put it in your root layout, so it loads on every route including your homepage. The widget watches for your field rather than requiring it up front, so it doesn't matter whether the form is server-rendered, hydrated in, or fetched later on the client.
// app/layout.tsx (App Router)
import Script from "next/script";
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>
{children}
<Script
src="https://beautimonial.com/inline-widget.js?token=YOUR_TOKEN"
strategy="afterInteractive"
/>
</body>
</html>
);
}On the Pages Router, put the same <Script> in pages/_app.tsx, which is the equivalent whole-app slot.
Nothing to install. Once inline-widget.js is on your site (2.4β2.6), website replies are already available β the feature sits dormant in the same script until you start a session. There is no second tag, no route to add, and nothing your site's code has to do.
https://yourdomain.com β because that is the domain you registered, and your comments live on your own site rather than in your dashboard, so we can't know which page to open. If inline-widget.js is scoped to your comment page only, there is nothing at the root to start the session with, and no β¨ Reply button will appear on any page β silently. Installing site-wide (2.4β2.6) avoids this.Start a session from your dashboard
Reply where the comment lives
The session expires on its own
One thing worth checking: which elements on your page count as βa commentβ. Out of the box we look for common comment markup β .comment-item, .comment, li.comment. Plenty of sites, React apps especially, use their own class names. If yours do, no Reply buttons appear and nothing reports an error. Point it at your markup with attributes on the same script tag:
<script src="https://beautimonial.com/inline-widget.js?token=YOUR_TOKEN"
data-comment-selector=".CommentCard"
data-author-selector=".CommentCard__author"
data-text-selector=".CommentCard__body"
data-reply-selector="textarea"></script>data-comment-selector β the container for a single comment. Each match gets its own Reply button. Default: .comment-item, .comment, li.commentdata-author-selector β who wrote the comment, so the draft can greet them by name. Default: .comment-author, .author, .fn, .comment-author-namedata-text-selector β the comment text the draft responds to. Default: .comment-body, .comment-text, .comment-content, pdata-reply-selector β the box on your site the draft is written into. Default: textareaAll four are optional β leave one out and its default applies. They affect website replies only; the Beautify button takes its selector from Widget Settings, as described in 2.4.
Login to your Shopify admin
Online Store β Themes β Edit Code
Find theme.liquid file (or layout/theme.liquid)
Paste your Beautimonial code just before </body> tag
Click Save
Visit your store to test β
Option A (Recommended): Plugin
Option B: Theme Editor
Appearance β Theme Editor β find footer.php or header.php β paste before </body> β Update File
Option C: Elementor users
Site Settings β Custom Code β Body End β paste your code
Go to Project Settings
Click "Custom Code" tab
Paste code in "Footer Code" section
Click Save & Publish
Re-publish your site β
Go to Settings
Click "Advanced"
Click "Code Injection"
Paste code in "Footer" section
Click Save β
Go to Settings in Wix dashboard
Click "Custom Code" (under "Advanced" section)
Click "+ Add Custom Code"
Paste your Beautimonial code
Set "Place Code in" β Body - End
Apply to: All Pages
Click Apply β
Every space comes with a hosted collect page β a shareable link that works without installing anything. Find it in Dashboard β Widget Settings and share it anywhere: email signatures, DMs, QR codes, invoices, thank-you pages.
https://beautimonial.com/t/your-space-slugAlready have a review or comment box on your site? The inline widget adds a Beautify button inside your existing form instead of a floating button.
<script src="https://beautimonial.com/inline-widget.js?token=YOUR_TOKEN"></script>Install the inline script
Point it at your comment box
#review-text). Right-click your field β Inspect β Copy β Copy selector.Done
Instead of one blank box, Beautimonial walks customers through your questions one at a time β and turns the answers into a single polished story.
Set your questions per space in Dashboard β Widget Settings. Good questions follow the story arc: what problem did you have, what was it like using the product, what changed for you?
When your customer clicks Beautify, their words are polished for grammar, structure, and flow β and nothing else. Beautification never invents claims, numbers, or outcomes your customer didn't state. Here's the promise, step by step:
Short reviews like "great product" are nice but don't convert. When a customer's answer is thin, the widget asks one or two quick follow-up questions β "what did it help you do?", "what changed for you?" β so the specifics come from the customer, not from us.
With NPS enabled, customers first pick a 0β10 score. Customers who score you 7 or higher continue to the public testimonial flow; customers who score 0β6 are routed to a private feedback form instead.
Bring the testimonials you already have β from Google reviews, social posts, emails, or another testimonial tool. Dashboard β Import offers three modes:
name and testimonial (or text/review). Optional: title, email, rating, date. You preview every row before anything is imported.Add one and CSV imports are treated as owner-curated quotes: they go straight to Approved, exactly as written, with original dates preserved. Link imports land in Pending instead β automatic extraction can be imperfect, so they take one review click before going live.
Testimonials imported from a link also show a small βOriginally posted on [platform]β link on your Gratitude Canvas that points back to the original public post β a quiet proof-it's-real signal for visitors who want to verify.
On Pro and Business, your widget can collect real customer videos alongside written testimonials. Turn on Video testimonials in Dashboard β Widget Settings, and the review form shows a βπ₯ Record a video insteadβ option.
How customers record. Clicking it asks for camera permission and opens a live preview β recording works in modern browsers, with no app and no account. Videos run up to 90 seconds, and your customer can re-record as many times as they like before submitting. An optional one-line caption is published exactly as written. If the camera is unavailable or permission is declined, the form simply continues in words β nobody hits a dead end.
What Beautify does here. The video ships as recorded. While the camera is on, the optional β¨ Beautify panel gives your customer capture-time adjustments they control live β lighting and tone always available (brightness, contrast, warmth), and skin enhancement capped at 30% β comparable to a video call's camera settings, not an after-the-fact edit. What they see in the preview is exactly what you receive; nothing is ever altered after recording.
Reviewing and approving. Every video lands in your queue as Pending β always, even if auto-approve is on for written testimonials. You watch it first; approve it and it plays on your Gratitude Canvas as a click-to-play card. Pro keeps 2 videos live at a time and Business 5, counted across your account β and the slots renew forever: unpublish an older video and the slot frees immediately for a new one. It's a cap on simultaneous live videos, never a lifetime total.
Downloading. Any video still in storage can be downloaded as an MP4 from the moderation queue β worth doing before you remove one you might want to keep.
Unpublishing, rejecting, deleting. Removing a video from display permanently deletes the file from storage β it cannot be re-published (your customer would need to record again), and any download link stops working too. The confirm dialog says exactly this and offers a βDownload a copy firstβ button.
Housekeeping. Videos left Pending for 30 days are removed automatically β we email you a reminder at day 25. And once 10 videos are waiting for review, the widget pauses offering video capture to new visitors until you catch up; anyone mid-recording always completes normally.
Your Gratitude Canvas is a hosted page showing every approved testimonial for a space, ready to share at a link:
https://beautimonial.com/wall/your-space-slugIt supports a light or dark theme and your accent color via URL parameters, e.g. ?theme=light&accent=%236366f1.
The cards themselves follow your Brand Kit: the background color or gradient you set in Dashboard β Brand Kit carries over to the Canvas automatically. And with no accent parameter, the page uses your Brand Kit brand color β so a bare share link is already on-brand.
Drop the Canvas into your own site with an iframe that resizes itself to fit its content. Copy the ready-made snippet from Dashboard β Widget Settings β Display:
<iframe id="beautimonial-wall-light"
src="https://beautimonial.com/wall/your-space-slug?theme=light&accent=%236366f1"
style="width:100%; height:600px; border:none; display:block;" loading="lazy"></iframe>
<script>
window.addEventListener("message", function (e) {
if (e.data && e.data.type === "beautimonial-wall-resize") {
document.getElementById("beautimonial-wall-light").style.height = e.data.height + "px";
}
});
</script>The two halves do different jobs. The iframe shows your Canvas; the small script makes it grow. Your Canvas measures itself and posts its height out to the page, and the listener resizes the frame to match. Leave the script out and the frame stays at its starting height β taller walls get clipped, shorter ones sit in empty space.
On Pro and above, add &mode=carousel to the src for a compact auto-rotating carousel strip instead of the full grid β ideal for a homepage or footer. The ready-made snippet (400px starting height, its own frame id) is in Dashboard β Widget Settings β Display.
React and Next.js: one thing to change. The iframe itself is a plain HTML element and behaves identically in every framework β no useEffect needed, no <Script> component, nothing special for server rendering or hydration. The resize listener is the exception, and it's worth knowing why.
<script> tags written in JSX. Paste the snippet above straight into a component and it renders without complaint, but the listener never runs β you get a frame frozen at 600px with content cut off and no error anywhere to explain it. Move the listener into an effect instead.This version works in both React and Next.js. Three small conversions: the listener moves into useEffect, the id and getElementById become a ref, and the style string becomes an object.
"use client"; // Next.js only β omit this line in CRA or Vite
import { useEffect, useRef } from "react";
export default function TestimonialWall() {
const frame = useRef(null);
useEffect(() => {
function onMessage(e) {
if (e.data && e.data.type === "beautimonial-wall-resize" && frame.current) {
frame.current.style.height = `${e.data.height}px`;
}
}
window.addEventListener("message", onMessage);
return () => window.removeEventListener("message", onMessage);
}, []);
return (
<iframe
ref={frame}
src="https://beautimonial.com/wall/your-space-slug?theme=light"
title="Customer testimonials"
loading="lazy"
style={{ width: "100%", height: 600, border: "none", display: "block" }}
/>
);
}next/script here. That component exists to load third-party scripts from a URL; this listener is a few lines of your own code, so a "use client" component with an effect is all it takes β and it's the same code in both frameworks.Pulse shows small rotating toast pop-ups of real, recent testimonials to visitors as they browse your site β social proof at the moment it matters. It rides on the same widget script you already installed, so there's no second embed to add.
On Pro and above, your widget automatically adds review structured data (JSON-LD) to the pages it runs on, so search engines can read your testimonials β no copy-paste needed. Turn it on in Dashboard β Widget Settings β SEO Schema & AEO.
On any paid plan you can hide the "Powered by Beautimonial" badge on your widget and Canvas: Dashboard β Widget Settings β branding toggle. Free spaces always show the badge.
Your dashboard has these sections:
Approving a testimonial
Rejecting a testimonial
Unpublishing or deleting
Approved by mistake, or want something off your wall? Unpublish takes a live testimonial off your site without losing it; delete removes it entirely.
Why can't I edit testimonials?
By design. Testimonials stay exactly as your customer approved them β that's what makes them trustworthy. Your customer edits and approves the polished version before submitting; from your side you approve, reject, unpublish, or delete. You can view each testimonial's original and polished versions side by side at any time.
Replying to a review builds trust with everyone who reads it. From Dashboard β Testimonials, Draft Reply suggests a warm, on-brand reply to any testimonial that you can edit before you use it.
Everything about how you collect lives here:
Dashboard β Analytics answers "is this working?" with real numbers:
Every plan can create Social Media Cards and Animated Videos; higher plans add more tools:
| Plan | Price | Includes |
|---|---|---|
| Free | Free |
|
| Starter | $9.99/month |
|
| Pro | $19.99/month |
|
| Business | $39.99/month |
|
| Agency | Custom |
|
*Custom limits negotiated per account. Contact support@beautimonial.com to discuss what's right for your use case.
The Free plan caps how many testimonials are live on your site at once β 10 β not how many you can collect. Collection never stops:
Dashboard β Billing β Upgrade Plan β select new plan β complete payment β new limits active immediately β
Dashboard β Billing β Cancel Plan β confirm cancellation β access continues until billing period ends β no further charges β you move to the free plan and keep all your testimonials
Q: When am I charged?
A: Monthly, on the same date you subscribed. You receive an email reminder before each charge.
Q: Can I change plans anytime?
A: Yes! Upgrade or downgrade anytime from billing.
Q: What payment methods are accepted?
A: Credit cards, debit cards, UPI, net banking, and wallets via Razorpay.
Q: Do beautifications carry over?
A: No. Limits reset on the 1st of each month. Unused beautifications don't carry over.
Issue: the "Leave a Review" button doesn't appear on my website.
Check 1: Is your embed code correct?
Go to Dashboard β Widget Settings, copy your embed code again, and make sure YOUR token is in the URL (not a sample token).
Check 2: Is your domain registered?
Dashboard β Widget Settings β Domain. Make sure your domain is saved, e.g. mywebsite.com (no https://).
Check 3: Is your subscription active?
Dashboard β Billing. Check your subscription is active and your domain is registered in Widget Settings.
Check 4: Is the code installed correctly?
The code must be in the HTML of your page, just before the closing </body> tag. Check for typos.
Check 5: Cache issue?
Clear your browser cache, try an incognito/private window, or try a different browser.
Beautify button not working
Customer clicks Beautify but nothing happens. Possible causes:
Note: plan limits are never the cause β even at your limit, the customer flow completes normally.
Not receiving email notifications
Still not receiving? Email support@beautimonial.com
Does my customer need to create an account?
No! Customers just visit your website, click the widget button, leave their review, and click Beautify. Zero signup required.
Can I edit beautified testimonials?
No β testimonials stay exactly as your customer approved them; that's what keeps them authentic. Your customer can edit the polished version before approving it. From your dashboard you approve, reject, unpublish, or delete.
What happens if I hit my monthly limit?
Your customers never notice. The review flow always completes normally β if a beautification limit is reached, we save the customer's words with a light tidy-up (spacing and typos only) and the testimonial still lands in your dashboard as usual. Upgrade anytime for a higher monthly allowance.
Does Beautify change what my customer actually said?
No. Beautification polishes grammar, structure, and flow β it never adds claims, numbers, or outcomes your customer didn't state. Every polished version is checked against the original, and if the check fails we fall back to your customer's own words, cleaned up mechanically. Your customer reviews and approves the final text before it ever reaches you.
What happens when my free wall is full?
Nothing breaks. With 10 testimonials live, newly approved ones are held as 'Waiting' β safely stored and ready to go live the moment a slot opens or you upgrade. We'll email you when your wall fills up. Customers can always keep submitting.
Can someone steal my widget code?
No. Your widget is domain-locked. It only works on your registered domain. If someone copies your code, it won't work on their website.
What happens to testimonials if I cancel?
Nothing is deleted. Cancelling moves you to the free plan at the end of your billing period β every live testimonial stays live (we never auto-unpublish), and if you have more than 10 live, new publishes simply wait for a slot.
Can I have the widget on multiple websites?
Yes! Pro plan supports 2 domains, Business plan supports 5 domains. Each domain gets its own widget settings.
Do you offer a free plan?
Beautimonial is free on the Free plan: collect testimonials and keep up to 10 live on your site at any time, no card required. Upgrade when your wall fills up.
How do I change my widget language?
Currently, Beautimonial supports English. Multi-language support is coming soon.
Can I collect testimonials without installing anything?
Yes! Every space has a hosted collect page at beautimonial.com/t/your-space-slug. Share the link in emails, DMs, QR codes, or invoices β no code needed.
Can I bring in testimonials I already have?
Yes. Dashboard β Import lets you paste testimonials one at a time, upload a CSV from Google reviews or another testimonial tool, or import straight from a public post link on X, Reddit, TikTok, YouTube, or Instagram. Link imports show you the text for review first and land in Pending for one approval click. Original dates are preserved.
What happens when an unhappy customer leaves feedback?
With Smart NPS routing enabled, customers who score you 0β6 are routed to a private feedback form instead of the public flow. Their feedback is emailed to you and never appears publicly.
Is there an API available?
API access is available on our Agency plan. Contact support@beautimonial.com for details.
Plain-English definitions of the key terms you'll see across your dashboard and the pricing page. Each links from its info icon on the pricing comparison table.
A testimonial that's been approved and is publicly displayed β on your Gratitude Canvas, embedded widget, or anywhere else your testimonials show up on your site. Not yet approved ("Pending"), or approved but queued past your plan's display limit ("Waiting"), don't count as Live. Free plan: up to 10 Live testimonials at once. Paid plans: unlimited.
Each time a raw customer comment gets polished into a clean, professional testimonial β whether from your floating widget, inline comment box, or Guided Q&A flow. Counted once per finished result, not per question answered or per preview. Resets monthly, shared across all your spaces on one account.
One Space = one complete testimonial setup for one website or domain β its own widget, its own collected testimonials, its own settings. Most customers only need one Space. Agencies or multi-brand businesses managing several websites can use multiple Spaces (2 on Pro, 5 on Business) to keep each site's testimonials separate.
A hosted page showing all your approved (Live) testimonials in one place β shareable as its own link, or embedded directly into your website. Updates automatically as you approve new testimonials.
The floating "Leave a Review" button and form that appears on your website, letting customers submit feedback. One line of code adds it to any page.
A short, animated version of an approved testimonial β text and stars animate into place β that you can download and share on social media. Not a customer-recorded video; a designed, branded motion graphic built from the testimonial's text.
A static, downloadable image version of a testimonial, styled with your Brand Kit, ready to post on Instagram, LinkedIn, or X.
A real video your customer records inside the review widget β up to 90 seconds, shipped exactly as recorded, and approved by you before it goes live on your Gratitude Canvas. Pro shows 2 videos live at a time and Business 5, counted across your account. These are permanently renewable slots, not a lifetime allowance: unpublish an older video and the slot frees immediately for a new one, as many times as you like. Some testimonial tools cap the total number of videos you can ever collect and make you upgrade for more β Beautimonial's cap is only on how many are live at once. Not the same as Animated Videos, which are designed motion graphics built from a testimonial's text.
Automatic tagging of private feedback (from unhappy customers routed away from public display) into categories β so you can see recurring reasons behind low scores without reading every response individually.
A dashboard view built on top of Objection Insights tagging, surfacing trends across your private feedback so you can identify and address recurring issues at a glance, rather than reading each response individually.
Small pop-up notifications that surface a recent 5-star testimonial to website visitors in real time, as social proof while they're deciding.
Before leaving a review, customers rate 0-10. High scorers continue to the public review flow; low scorers are routed to a private feedback form only you see β keeping public testimonials genuine while still capturing honest criticism privately.
Can't find what you're looking for?
Our support team is here to help.
Email: support@beautimonial.com
Response: Within 24 hours