One <script> tag, placed in the single layout file every page renders through, loaded async, with a guard so client-side navigation doesn't load it twice. That's the whole answer.
The rest of this post is the five places people get it wrong.
The line
<script async src= "EMBED_SRC" data-site= "YOUR_SITE_KEY" ></script>
Enter fullscreen mode
Exit fullscreen mode
Two values, both issued for your site: EMBED_SRC and YOUR_SITE_KEY . Copy them from the snippet you were given β don't retype them from a screenshot, and don't hand-edit the source URL.
Put it immediately before </body> . Not in <head> : async helps, but there's no reason for the widget to compete with your largest contentful paint for bandwidth.
Where it goes β once
Static site
The footer partial β whatever your build includes on every page. One file, one paste.
Single-page app
The root layout: the _app file, App.vue , layout.tsx , the component that wraps every route.β¦