Embed Hairgen.ai Studio on Your Website
Installation
- Add the script
<div id="hairgen-ai-widget" data-token="YOUR_TOKEN_HERE"></div> <script src="https://www.hairgen.ai/js/embed-1.js"></script>
- Adjust the z-index if needed and we're done! Example:
<div id="hairgen-ai-widget" data-token="YOUR_TOKEN_HERE" style="relative;z-index:1000" ></div> <!-- hairgen.ai script... -->
Customization (optional)
Localization
You can change virtually any text and styles within the widget. The full set of options along with their defaults is detailed in step 2.
Create a root element (do not use the id
hairgen-ai-widget
as it will be automatically initialized with default settings)<div id="hairgen-ai-widget-custom"></div> <script src="https://www.hairgen.ai/js/embed-1.js"></script>
Initialize the widget via code and we're done!
var widgetRootEl = document.getElementById("hairgen-ai-widget-custom"); var token = YOUR_TOKEN_HERE; window.hairgenAIWidget(widgetRootEl, token, { // whether to load the script asynchronously (default: ) async: false, // whether to show the post-render survey survey: true, // the landing media in order of appearance. Will be automatically skewed to match the style on the page. // can be photos or videos. // * Photos: // Array size should be exactly 2. Will automatically have swipe // effect applied between 1st photo (before) and 2nd photo (after). // * videos: // Should be 460x460 pixels landingMedia: [ `https://www.hairgen.ai/videos/draw-hairline-1.mp4`, `https://www.hairgen.ai/videos/results-1.mp4`, `https://www.hairgen.ai/videos/draw-hairline-3.mp4`, `https://www.hairgen.ai/videos/results-3.mp4`, ], // set to "" if you will override button styles via the stylesheet // can be any valid css color buttonColor: "", buttonHoverColor: "", buttonTextColor: "", // styles injected into the widget stylesheet: "/custom-hairgen-ai-style.css", // change any of the text i18n: { "landing-title": "See how you'll look with more hair.", "landing-subtitle": [ "Free AI simulation on ", { text: "your photos", tag: "strong" }, " in 35 seconds.", ], "button-landing": "Get Started", "powered-by": "Powered by", "add-photo": "Add photo", "add-photos": "Add photos", "button-done-cropping": "", "button-clear": "", "button-undo": "", "button-redo": "", "brush-size": "", "button-render": "", "button-resend-code": "Resend Code", "step-1-title": "1. Upload a photo of yourself.", "step-2-title": "2. Draw the area to add hair to.", "step-3-title": "3. Render.", "error-draw": "Please draw where to put more hair before submitting!", name: "Name", email: "Email", // used in phone first option "label-phone-first": "Your Phone", "button-phone-first": "Go", // end "phone-number": "Phone Number", "error-invalid-phone": "Invalid phone number.", "error-invalid-code": "Invalid code.", "error-generic": "Something went wrong. Please try again later.", "agree-tos": [ "I agree to the ", { text: "terms and conditions", tag: "a", href: "https://www.hairgen.ai/tos/", }, ], "button-verify": "Verify", "auth-code": "2-Factor Authentication Code", "enter-code": "Enter Code", "button-submit": "Submit", disclaimer: [ "The hair-transplant simulation is for ", { text: "illustrative purposes only", tag: "u" }, ". Actual results may vary and cannot be guaranteed.", ], "button-book-consultation": "Book Consultation", "button-call-clinic": "Call Clinic", "button-try-another": "Try Another", survey: "How does seeing this affect your decision to get a hair transplant?", "button-more": "👍 More likely", "button-less": "👎 Less likely", "survey-end": "Thank you for your feedback!", "button-call-instead": "Call me instead", "call-incoming": "You will receive a phone call with your verification code.", }, });
Webhooks (optional)
Enable the webhook
- Open Studio and navigate to Web Widgets → Settings for the widget you want to configure.
- Enter the HTTPS endpoint you want to notify in Webhook URL and save the settings.
The widget now sends an HTTP POST
request with a JSON payload each time a gallery is created and when that gallery later passes two-factor verification. Requests time out after roughly 30 seconds, so respond with a 2xx
status as quickly as possible.
Event payloads
All webhook requests share the same structure. The event
field indicates whether you are receiving the initial creation event or the follow-up verification event.
{
"event": "web_widget.gallery.created",
"createdAt": "2025-09-21T19:03:04.123Z",
"widget": {
"token": "abc123",
"name": "Landing Page 2 Web Widget"
},
"gallery": {
"id": 9876,
"password": "pvdqpt",
"url": "https://www.hairgen.ai/studio/web-widgets/abc123/pvdqpt",
"photoId": 0,
"verified": false
},
"lead": {
"name": "Jordan Smith",
"email": "[email protected]",
"phoneNumber": "+14155550100"
},
"owner": {
"email": "[email protected]"
},
"uploadId": "ul_a1b2c3"
}
When the gallery is verified, you receive a second payload with the same shape and event
value web_widget.gallery.verified
. That payload swaps createdAt
for verifiedAt
and sets gallery.verified
to true
:
{
"event": "web_widget.gallery.verified",
"verifiedAt": "2025-09-21T19:05:18.567Z",
"widget": {
"token": "abc123",
"name": "Main Website Widget"
},
"gallery": {
"id": 9876,
"password": "pvdqpt",
"url": "https://www.hairgen.ai/studio/web-widgets/abc123/pvdqpt",
"photoId": 0,
"verified": true
},
"lead": {
"name": "Jordan Smith",
"email": "[email protected]",
"phoneNumber": "+14155550100"
},
"owner": {
"email": "[email protected]"
},
"uploadId": "ul_a1b2c3"
}
Use the event
field to branch your integration—for example, send an SMS when web_widget.gallery.created
arrives without a verified event after 5 minutes, and push the lead into your CRM and cancel the cart abandonment SMS only after web_widget.gallery.verified
confirms that the phone number was validated.