Início rápido
#O Atria é uma única tag de script clássica. Ela adiciona um botão de suporte no canto da página e abre o chat em um iframe isolado.
No painel administrativo do Atria, abra Agentes, escolha um agente e copie o snippet. Ele já contém o ID do agente (que começa com
agt_).Cole-a imediatamente antes da tag de fechamento
</body>em todas as páginas que devem exibir o chat. Um script comdeferem<head>também funciona.index.html <script src="https://atria.bemagic.online/widget.js?agentId=agt_YOUR_AGENT_ID" defer></script>Prefere atributos a parâmetros na URL?
data-agent-idfunciona da mesma forma.html <script src="https://atria.bemagic.online/widget.js" data-agent-id="agt_YOUR_AGENT_ID" defer></script>Recarregue o site e clique no botão. As mensagens aparecem em tempo real em Admin → Sessões.
Como o widget funciona
#Feito para ser um convidado discreto em qualquer página: pequeno, isolado e carregado sob demanda.
O carregador tem cerca de 3,5 kB compactado com gzip e não tem dependências. Ele renderiza o botão em sua própria shadow root (
#atria-support), para que seu CSS não o danifique e o CSS dele não afete sua página.O chat em si é um iframe servido por
https://atria.bemagic.online, criado somente quando alguém abre o botão. Nada pesado é carregado antes disso.Todas as solicitações de rede acontecem dentro do iframe. Sua página só precisa permitir o carregamento do script e a exibição do chat em um frame.
O visitante recebe um ID anônimo armazenado no
localStoragedo seu site (atria:visitor-id). A conversa aberta e o estado do chat ficam nosessionStorage, para que o chat acompanhe os visitantes entre páginas.Quando o chat está minimizado, novas respostas aparecem como um indicador de mensagens não lidas no botão.
Identifique visitantes autenticados
#Informe ao Atria quem está conversando para que agentes e operadores possam cumprimentar as pessoas pelo nome e ver informações úteis.
Defina
window.AtriaSettingsem qualquer lugar da página. O valor é lido quando o visitante abre o chat, então você pode defini-lo após o login sem recarregar o widget.html <script> window.AtriaSettings = { visitor: { id: "user_8231", // your user ID (string or number) name: "Marta Silva", email: "marta@example.com", metadata: { plan: "Pro", company: "Crumbs Bakery" }, }, }; </script>
Política de Segurança de Conteúdo
#Se o site enviar um cabeçalho CSP, permita o Atria em duas diretivas. Só isso.
Adicione a origem do Atria a
script-src(para carregar o carregador) eframe-src(para exibir o chat). Não é necessário alterarconnect-src,style-srcouimg-src: os estilos do botão usam folhas de estilo construíveis, que não são bloqueadas porstyle-src.http Content-Security-Policy: script-src 'self' https://atria.bemagic.online; frame-src https://atria.bemagic.online;Usa nonces com
'strict-dynamic'? Adicione seu nonce à tag do Atria. O carregador nunca injeta outros scripts.html <script nonce="{{ nonce }}" src="https://atria.bemagic.online/widget.js?agentId=agt_YOUR_AGENT_ID" defer></script>
Aplicativos de página única e transições
#O roteamento no cliente, as transições de visualização e as substituições do body são tratados automaticamente.
Carregue o script uma vez no layout raiz ou em
index.html. As mudanças de rota em React, Vue, Svelte, Angular e similares não o afetam.Se um framework substituir todo o
<body>(Turbo, htmx boost, transições de visualização do Astro, Livewirewire:navigate, swup ou Barba), o botão será recolocado automaticamente.Em carregamentos completos da página, a conversa aberta e o estado do painel são restaurados para que os visitantes continuem de onde pararam.
Privacidade e consentimento
#O que o widget armazena e quando se comunica com o Atria.
Até que o visitante abra o chat, a única solicitação ao Atria é o carregamento de
widget.js. O widget não define cookies no seu site.Ele armazena um ID anônimo do visitante em
localStorage, além do ID da conversa atual e do estado do painel emsessionStorage. Uma sessão só é criada quando o visitante envia a primeira mensagem, junto com a URL da página, o referenciador, o idioma do navegador e o fuso horário.Se o banner de consentimento exigir aprovação prévia das ferramentas de suporte, injete o script após o consentimento:
js function loadAtria() { const script = document.createElement("script"); script.src = "https://atria.bemagic.online/widget.js?agentId=agt_YOUR_AGENT_ID"; script.defer = true; document.body.appendChild(script); }
Solução de problemas
#As causas mais comuns, em ordem.
O botão nem aparece? Abra o console. Um erro de CSP mencionando
script-srcsignifica que você precisa permitirhttps://atria.bemagic.online. Sem erros? Verifique se a tag não usatype="module"e se não foi empacotada, combinada ou atrasada por um otimizador.O botão aparece, mas o painel está em branco? Adicione
https://atria.bemagic.onlineaframe-src(ouchild-src/default-src).O chat informa que o agente está indisponível? O
agentIdestá ausente ou incorreto. Copie o snippet novamente em Admin → Agentes.Recebe avisos de hidratação do React durante o desenvolvimento? Algo adicionou nós ao
<body>antes da hidratação. Carregue o Atria após a hidratação (consulte o guia do seu framework) para eliminar o aviso.O botão do Atria cobre seu próprio botão flutuante? Ele fica no canto inferior direito, acima de tudo. Mova seu botão ou oculte um deles em telas pequenas.
Meta-frameworks
Next.js (App Router)
#Use next/script no layout raiz para que o chat carregue após a hidratação em todas as rotas.
Adicione o script a
app/layout.tsx:app/layout.tsx import Script from "next/script"; export default function RootLayout({ children }: { children: React.ReactNode }) { return ( <html lang="en"> <body> {children} <Script src="https://atria.bemagic.online/widget.js?agentId=agt_YOUR_AGENT_ID" strategy="afterInteractive" /> </body> </html> ); }Se você definir cabeçalhos de segurança em
next.config.ts, permita o Atria:next.config.ts import type { NextConfig } from "next"; const csp = [ "default-src 'self'", "script-src 'self' https://atria.bemagic.online", "frame-src https://atria.bemagic.online", ].join("; "); const nextConfig: NextConfig = { async headers() { return [ { source: "/:path*", headers: [{ key: "Content-Security-Policy", value: csp }], }, ]; }, }; export default nextConfig;Usa uma CSP baseada em nonce em
proxy.ts(middleware.tsantes do Next.js 16)? Leia o nonce no layout e repasse-o:app/layout.tsx import { headers } from "next/headers"; import Script from "next/script"; export default async function RootLayout({ children }: { children: React.ReactNode }) { const nonce = (await headers()).get("x-nonce") ?? undefined; return ( <html lang="en"> <body> {children} <Script src="https://atria.bemagic.online/widget.js?agentId=agt_YOUR_AGENT_ID" strategy="afterInteractive" nonce={nonce} /> </body> </html> ); }
Next.js (Pages Router)
#Carregue-o uma vez em _app usando next/script.
Adicione o script ao lado do componente da página:
pages/_app.tsx import type { AppProps } from "next/app"; import Script from "next/script"; export default function App({ Component, pageProps }: AppProps) { return ( <> <Component {...pageProps} /> <Script src="https://atria.bemagic.online/widget.js?agentId=agt_YOUR_AGENT_ID" strategy="afterInteractive" /> </> ); }
React Router v7 / Remix
#Adicione-o a root.tsx. No React 18, carregue-o após a hidratação para evitar avisos.
React 19 (padrão do React Router v7): coloque a tag no body do documento, após
<Scripts />.app/root.tsx export function Layout({ children }: { children: React.ReactNode }) { return ( <html lang="en"> <head> <Meta /> <Links /> </head> <body> {children} <ScrollRestoration /> <Scripts /> <script src="https://atria.bemagic.online/widget.js?agentId=agt_YOUR_AGENT_ID" defer /> </body> </html> ); }React 18 (Remix v2): carregue-o por um effect para que o React hidrate o documento primeiro.
app/root.tsx import { useEffect } from "react"; export default function App() { useEffect(() => { if (document.getElementById("atria-script")) return; const script = document.createElement("script"); script.id = "atria-script"; script.src = "https://atria.bemagic.online/widget.js?agentId=agt_YOUR_AGENT_ID"; document.body.appendChild(script); }, []); return <Outlet />; }Defina os cabeçalhos CSP em
entry.server.tsx(ou em uma exportaçãoheaders) e adicione o Atria ascript-srceframe-src.
Gatsby
#Use <Script> do Gatsby com a estratégia post-hydrate.
Envolva todas as páginas uma vez em
gatsby-browser:gatsby-browser.tsx import { Script } from "gatsby"; export const wrapPageElement = ({ element }) => ( <> {element} <Script src="https://atria.bemagic.online/widget.js?agentId=agt_YOUR_AGENT_ID" strategy="post-hydrate" /> </> );
Nuxt
#Declare o script em nuxt.config.ts para incluí-lo em todas as páginas.
Adicione-o ao head do app, no fim do body:
nuxt.config.ts export default defineNuxtConfig({ app: { head: { script: [ { src: "https://atria.bemagic.online/widget.js?agentId=agt_YOUR_AGENT_ID", defer: true, tagPosition: "bodyClose", }, ], }, }, });Usa
nuxt-security? Adicione o Atria à CSP:nuxt.config.ts export default defineNuxtConfig({ security: { headers: { contentSecurityPolicy: { "script-src": ["'self'", "'nonce-{{nonce}}'", "https://atria.bemagic.online"], "frame-src": ["https://atria.bemagic.online"], }, }, }, });
SvelteKit
#Adicione-o a src/app.html.
Cole a tag antes do fechamento do body:
src/app.html <body data-sveltekit-preload-data="hover"> <div style="display: contents">%sveltekit.body%</div> <script nonce="%sveltekit.nonce%" src="https://atria.bemagic.online/widget.js?agentId=agt_YOUR_AGENT_ID" defer></script> </body>Se você usa
kit.csp, adicione o Atria às diretivas:svelte.config.js const config = { kit: { csp: { directives: { "script-src": ["self", "https://atria.bemagic.online"], "frame-src": ["https://atria.bemagic.online"], }, }, }, }; export default config;
Astro
#Adicione-o ao layout base com is:inline.
is:inlineinstrui o Astro a manter a tag exatamente como foi escrita:src/layouts/Layout.astro <html lang="en"> <body> <slot /> <script is:inline src="https://atria.bemagic.online/widget.js?agentId=agt_YOUR_AGENT_ID" defer></script> </body> </html>
Angular
#Adicione-o a src/index.html, não ao template de um componente.
Cole a tag antes do fechamento do body:
src/index.html <body> <app-root></app-root> <script src="https://atria.bemagic.online/widget.js?agentId=agt_YOUR_AGENT_ID" defer></script> </body>Vai carregá-lo pelo código (por exemplo, após o consentimento)? Execute-o fora da zona do Angular para que os eventos do widget não acionem a detecção de alterações:
ts this.ngZone.runOutsideAngular(() => { const script = document.createElement("script"); script.src = "https://atria.bemagic.online/widget.js?agentId=agt_YOUR_AGENT_ID"; document.body.appendChild(script); });
Qwik City
#Adicione a tag a src/root.tsx.
Cole-a dentro do body:
src/root.tsx <body lang="en"> <RouterOutlet /> <script src="https://atria.bemagic.online/widget.js?agentId=agt_YOUR_AGENT_ID" defer /> </body>
SolidStart
#Adicione a tag ao documento de entrada do servidor.
Cole-a após a raiz do app:
src/entry-server.tsx <body> <div id="app">{children}</div> {scripts} <script src="https://atria.bemagic.online/widget.js?agentId=agt_YOUR_AGENT_ID" defer /> </body>
Bibliotecas de UI e SPAs
React (Vite, Create React App)
#Aplicativos de página única só precisam da tag em index.html.
Cole-a antes do fechamento do body (
public/index.htmlno Create React App):index.html <body> <div id="root"></div> <script type="module" src="/src/main.tsx"></script> <script src="https://atria.bemagic.online/widget.js?agentId=agt_YOUR_AGENT_ID" defer></script> </body>Precisa carregá-lo condicionalmente? Use um effect e não o remova durante a limpeza:
tsx useEffect(() => { if (!user || document.getElementById("atria-script")) return; window.AtriaSettings = { visitor: { id: user.id, name: user.name } }; const script = document.createElement("script"); script.id = "atria-script"; script.src = "https://atria.bemagic.online/widget.js?agentId=agt_YOUR_AGENT_ID"; document.body.appendChild(script); }, [user]);
Vue
#Adicione a tag a index.html em projetos Vite.
Cole-a antes do fechamento do body:
index.html <body> <div id="app"></div> <script type="module" src="/src/main.ts"></script> <script src="https://atria.bemagic.online/widget.js?agentId=agt_YOUR_AGENT_ID" defer></script> </body>
Svelte (Vite)
#Adicione a tag a index.html.
Cole-a antes do fechamento do body:
index.html <script src="https://atria.bemagic.online/widget.js?agentId=agt_YOUR_AGENT_ID" defer></script>
Solid, Preact e Lit
#Qualquer app baseado em Vite funciona da mesma forma: uma tag em index.html.
Cole-a antes do fechamento do body:
index.html <script src="https://atria.bemagic.online/widget.js?agentId=agt_YOUR_AGENT_ID" defer></script>
Ember
#Adicione a tag a app/index.html.
Cole-a após
{{content-for "body-footer"}}:app/index.html {{content-for "body-footer"}} <script src="https://atria.bemagic.online/widget.js?agentId=agt_YOUR_AGENT_ID" defer></script>
Ionic e Capacitor
#Funciona em apps híbridos por meio do WebView, com a mesma tag em index.html.
Cole-a antes do fechamento do body em
src/index.html(Angular) ouindex.html(React e Vue):index.html <script src="https://atria.bemagic.online/widget.js?agentId=agt_YOUR_AGENT_ID" defer></script>
Sites estáticos e documentação
HTML puro, jQuery e Alpine.js
#Cole a tag em todas as páginas, antes de </body>.
Essa é toda a instalação:
index.html <!doctype html> <html lang="en"> <body> <!-- your page --> <script src="https://atria.bemagic.online/widget.js?agentId=agt_YOUR_AGENT_ID" defer></script> </body> </html>
Hugo, Jekyll e Eleventy
#Adicione a tag ao layout base.
Hugo:
layouts/_default/baseof.html {{ block "main" . }}{{ end }} <script src="https://atria.bemagic.online/widget.js?agentId=agt_YOUR_AGENT_ID" defer></script> </body>Jekyll:
_layouts/default.html {{ content }} <script src="https://atria.bemagic.online/widget.js?agentId=agt_YOUR_AGENT_ID" defer></script> </body>Eleventy:
_includes/base.njk {{ content | safe }} <script src="https://atria.bemagic.online/widget.js?agentId=agt_YOUR_AGENT_ID" defer></script> </body>
Docusaurus
#Registre o script na configuração do site.
Adicione-o a
scripts:docusaurus.config.ts const config = { scripts: [{ src: "https://atria.bemagic.online/widget.js?agentId=agt_YOUR_AGENT_ID", defer: true }], }; export default config;
VitePress
#Adicione o script ao head do site.
Adicione-o a
head:.vitepress/config.ts import { defineConfig } from "vitepress"; export default defineConfig({ head: [["script", { src: "https://atria.bemagic.online/widget.js?agentId=agt_YOUR_AGENT_ID", defer: "" }]], });
Renderização no servidor
Ruby on Rails (com Turbo)
#Adicione a tag ao layout da aplicação.
Coloque-a em
<head>para que o Turbo a carregue uma vez e a mantenha entre visitas:app/views/layouts/application.html.erb <head> <%= javascript_include_tag "https://atria.bemagic.online/widget.js?agentId=agt_YOUR_AGENT_ID", defer: true, nonce: true %> </head>Permita o Atria no inicializador da CSP:
config/initializers/content_security_policy.rb Rails.application.configure do config.content_security_policy do |policy| policy.script_src :self, "https://atria.bemagic.online" policy.frame_src "https://atria.bemagic.online" end end
Laravel (Blade, Livewire, Inertia)
#Adicione a tag ao layout Blade principal.
Blade e Livewire:
resources/views/layouts/app.blade.php <head> <script src="https://atria.bemagic.online/widget.js?agentId=agt_YOUR_AGENT_ID" defer data-navigate-once></script> </head>Inertia: adicione-o à visualização raiz, fora de
@inertia:resources/views/app.blade.php <body> @inertia <script src="https://atria.bemagic.online/widget.js?agentId=agt_YOUR_AGENT_ID" defer></script> </body>
Django e Flask
#Adicione a tag ao template base.
Cole-a antes do fechamento do body:
templates/base.html {% block content %}{% endblock %} <script src="https://atria.bemagic.online/widget.js?agentId=agt_YOUR_AGENT_ID" defer></script> </body>Com
django-csp4, permita o Atria nas configurações:settings.py CONTENT_SECURITY_POLICY = { "DIRECTIVES": { "script-src": ["'self'", "https://atria.bemagic.online"], "frame-src": ["https://atria.bemagic.online"], }, }
Phoenix (LiveView)
#Adicione a tag ao layout raiz.
Cole-a antes do fechamento do body:
lib/my_app_web/components/layouts/root.html.heex {@inner_content} <script src="https://atria.bemagic.online/widget.js?agentId=agt_YOUR_AGENT_ID" defer></script> </body>
ASP.NET Core (MVC, Razor Pages, Blazor)
#Adicione a tag ao layout compartilhado ou à página host do Blazor.
MVC e Razor Pages usam
Views/Shared/_Layout.cshtml(ouPages/Shared/_Layout.cshtml). Blazor usaComponents/App.razorouwwwroot/index.html.Views/Shared/_Layout.cshtml @RenderBody() <script src="https://atria.bemagic.online/widget.js?agentId=agt_YOUR_AGENT_ID" defer></script> </body>
Criadores de sites e CMS
WordPress
#Adicione o script à fila pelo tema ou cole-o usando um plugin de cabeçalho e rodapé.
Com um plugin como o WPCode, adicione a tag como snippet global de rodapé. Ou adicione o script à fila pelo tema filho:
functions.php add_action('wp_enqueue_scripts', function () { wp_enqueue_script( 'atria', 'https://atria.bemagic.online/widget.js?agentId=agt_YOUR_AGENT_ID', [], null, ['strategy' => 'defer', 'in_footer' => true] ); });
Shopify
#Adicione a tag a theme.liquid.
Em Loja virtual → Temas → … → Editar código, abra
layout/theme.liquide cole a tag antes de</body>:layout/theme.liquid {{ content_for_layout }} <script src="https://atria.bemagic.online/widget.js?agentId=agt_YOUR_AGENT_ID" defer></script> </body>
Webflow
#Use o código personalizado para todo o site.
Em Configurações do site → Código personalizado, cole a tag no código do rodapé, salve e publique.
html <script src="https://atria.bemagic.online/widget.js?agentId=agt_YOUR_AGENT_ID" defer></script>
Wix
#Use Configurações → Código personalizado.
Clique em Adicionar código personalizado, cole a tag, escolha Todas as páginas e Carregar código uma vez e defina a posição como Fim do body.
html <script src="https://atria.bemagic.online/widget.js?agentId=agt_YOUR_AGENT_ID" defer></script>
Squarespace
#Use Injeção de código.
Em Site → Páginas → Ferramentas do site → Injeção de código, cole a tag no rodapé e salve.
html <script src="https://atria.bemagic.online/widget.js?agentId=agt_YOUR_AGENT_ID" defer></script>
Framer
#Use as configurações de código personalizado do site.
Em Configurações do site → Geral → Código personalizado, cole a tag em Fim da tag <body> e publique.
html <script src="https://atria.bemagic.online/widget.js?agentId=agt_YOUR_AGENT_ID" defer></script>
Ghost
#Use Injeção de código.
Em Configurações → Injeção de código, cole a tag no rodapé do site e salve.
html <script src="https://atria.bemagic.online/widget.js?agentId=agt_YOUR_AGENT_ID" defer></script>
HubSpot CMS
#Use o HTML do rodapé do site.
Em Configurações → Site → Páginas, cole a tag no HTML do rodapé do site e salve.
html <script src="https://atria.bemagic.online/widget.js?agentId=agt_YOUR_AGENT_ID" defer></script>
Google Tag Manager
#Adicione uma tag HTML personalizada que seja acionada em todas as páginas.
Crie uma tag HTML personalizada com o snippet e o acionador Todas as páginas (ou seu acionador de consentimento) e publique o contêiner.
html <script src="https://atria.bemagic.online/widget.js?agentId=agt_YOUR_AGENT_ID" defer></script>