Show your whole help center, with its search, categories and articles, as a page of your website or app. A short script creates a frame that fits the height of each page and keeps your page's address in step with what the reader is viewing.
The embed suits a dedicated help page. To offer help next to your own interface, on any page, use the widget instead; see Widget installation and options.
Who can do this: Owners and Admins allow your website, and whoever edits your website's code adds the embed
Before you start
Allow the page's host. Add the host of the page that shows the help center, such as
app.example.com, to Embedding origins in Settings. Until it's there, browsers refuse to show your help center in the frame. See Choose which websites can show the widget, and for how entries match, Content Security Policy and allowed origins.Serve the page over HTTPS on the standard port. Browsers show the frame only on
https://pages without a port number. A page athttp://localhost:3000orhttp://127.0.0.1:8080can't show it, even with its host in the list.List every page in the chain. If your page is itself shown inside another page, such as a reporting tool or a website builder's custom-code frame, every host in that chain must be in Embedding origins.
Add the embed
Put this where the help center should appear, with your help center's subdomain in place of acme (for acme.helpcenter.io):
<div id="hc_embed"></div>
<script>
var subdomain = 'acme';
</script>
<script src="https://helpcenter.io/js/embed.js"></script>
<div id="hc_embed">is where the frame goes. It must come before the embed script, which looks for it when it runs. Style it like any element of your page; the frame fills its width.subdomainmust be a global variable, declared withvarin a regular script before the embed script.embed.jsloads fromhelpcenter.iofor every help center.
Help centers on a custom domain
If your help center uses a custom domain, name it in window._hcEmbedOpts:
<div id="hc_embed"></div>
<script>
var subdomain = 'acme';
window._hcEmbedOpts = { customDomain: 'help.acme.com' };
</script>
<script src="https://helpcenter.io/js/embed.js"></script>
Without customDomain, the frame still shows your help center, but it can't adjust its height or follow links: a help center with a custom domain moves visitors from its helpcenter.io address to the custom domain, and the embed script only listens to the address it loaded.
Setting | Where | What it does |
|---|---|---|
| Global variable | Required unless you set |
|
| Required when your help center has a custom domain. The domain only, without |
How the embed behaves
Height. The frame takes the height of each help center page when it loads, so visitors scroll your page as usual. Content that grows after the page has loaded isn't measured again.
Navigation. Links between pages of your help center open inside the frame, and your page's address follows along, for example
https://app.example.com/help#/en/content/reset-your-password. Reloading or sharing that address opens the same help center page.Search. Searches run inside the frame. Your page's address then shows
#/search, without the search terms.Links that don't open. Links to other websites, email links, and links to a heading on the same page do nothing inside the embed.
Your page's fragment. The embed writes to your page's URL fragment (the part after
#), so it doesn't fit a page that uses the fragment for its own routing.Use the script, not a plain
<iframe>. In a plain frame, links inside your help center don't open.
The frame has no title, which screen readers announce. Give it one after the embed script:
<div id="hc_embed"></div>
<script>
var subdomain = 'acme';
</script>
<script src="https://helpcenter.io/js/embed.js"></script>
<script>
document.querySelector('#hc_embed iframe').setAttribute('title', 'Help center');
</script>
Private help centers
On a private help center, readers must be signed in inside the frame, with JWT single sign-on. How long that sign-in lasts depends on where your help center lives:
On your own site, it works. With a custom domain on your own domain, such as
help.example.cominsideapp.example.com, the frame's first page sends the reader through your Login URL, and a session keeps them signed in on every page after that. Your Login URL runs inside the frame: for a reader who is already signed in to your app, it sends them straight back.On another site, sign-in doesn't hold. With
acme.helpcenter.ioinsideapp.example.com, browsers don't keep the help center's session cookie in the frame. The embed script's frame never gets past sign-in: each sign-in sends it back to your Login URL, in a loop when your Login URL signs readers straight back in. A token in?jwt=on a frame's first address signs in that page only, and the next page goes back to your Login URL. See Troubleshoot single sign-on.
For private content on a page of another site, use the widget with JWT sign-in, which sends a token with every request and needs no cookie; see Sign readers into the widget with a JWT. The embed script has no option for a token. How ?jwt= and the Login URL sign readers in is in How JWT single sign-on works.
Show the help center only inside your app
With JS-only access on, in Settings → General, your help center is shown through the embed and the widget on the websites in Embedding origins, rather than as a website of its own (see Show your help center only inside your app):
Opening one of its pages directly shows "Help center not available." with the status
403 Forbidden.Following a link to it from a website that isn't in Embedding origins shows "Embedding not allowed."
The embed and the widget keep working on the websites in Embedding origins.
JS-only access keeps the help center from being browsed as a normal website, but it is not access control. To limit who can read your articles, make the help center Private and sign readers in with a JWT.
It relies on the address browsers send along with each request (the referrer). A page with Referrer-Policy: no-referrer can't show the embed: the frame shows "Help center not available." Keep at least the origin in the referrer, as the default policy, strict-origin-when-cross-origin, does.
Troubleshooting
The frame stays blank. Open the browser console. A message like this names the page the browser objected to, and lists the hosts your help center allows right now:
Framing 'https://acme.helpcenter.io/' violates the following Content Security Policy
directive: "frame-ancestors 'self' app.example.com". The request has been blocked.
Add the missing host to Embedding origins, serve the page over HTTPS on the standard port, and check the other pages around it. Changes to the list can take a couple of minutes to apply.
The frame doesn't adjust its height, and links inside it don't open. Your help center has a custom domain and the embed has no customDomain, or the page uses a plain <iframe> instead of the embed script.
The frame shows "Help center not available." JS-only access is on and your page sends no referrer. Change its Referrer-Policy.
Your page's Content Security Policy blocks the embed. Allow https://helpcenter.io in script-src and your help center's address in frame-src, plus your Login URL's origin on a private help center. See Content Security Policy and allowed origins.