Analytics
Análises web próprias — PostHog, Google Analytics, Plausible, Mixpanel, Segment e mais — como adaptadores no blume.config.ts.
O Blume injeta as análises para você a partir de uma lista analytics no blume.config.ts. Cada entrada é um adaptador importado de blume/analytics: um por provedor, além do script() para qualquer um que não tenha adaptador.
import { defineConfig } from "blume";
import { googleAnalytics, plausible, posthog, vercel } from "blume/analytics";
export default defineConfig({
analytics: [
posthog({ key: "phc_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" }),
vercel(),
googleAnalytics({ id: "G-XXXXXXXXXX" }),
plausible({ domain: "docs.example.com" }),
],
});
Os adaptadores são emitidos no <head> na ordem em que você os lista, e você pode combinar quantos quiser. Todo adaptador é só dado: o que ele retorna é validado junto com o resto da sua config e embutido no site construído, então pode carregar qualquer valor JSON, mas nunca uma função. Uma opção repassada que o JSON não consegue carregar (uma função, undefined, um bigint) falha na validação indicando o caminho dela, em vez de sumir do build.
As análises são carregadas apenas em builds de produção. Os scripts são emitidos pelo blume build, nunca pelo blume dev, então o tráfego local nunca chega aos seus painéis e você não precisa de um projeto de “desenvolvimento” separado.
Para pedir a permissão dos leitores antes, defina consent: todo adaptador desta página passa a esperar até que o leitor permita as análises.
Todo identificador abaixo — uma chave de projeto, um ID de medição, um token de site — é o identificador público, do lado do navegador, que vem no próprio snippet de instalação do provedor. Cada adaptador renderiza esse snippet, então é seguro fazer commit dele no repositório da sua documentação; o Blume nunca pede um segredo.
Adaptadores
| Adaptador | Provedor | Obrigatório |
|---|---|---|
adobe() |
Adobe Analytics | url |
amplitude() |
Amplitude | key |
clarity() |
Microsoft Clarity | id |
clearbit() |
Clearbit | key |
clics() |
Clics | projectId |
cloudflare() |
Cloudflare Web Analytics | token |
databuddy() |
Databuddy | clientId |
fathom() |
Fathom | site |
googleAnalytics() |
Google Analytics 4 | id |
googleTagManager() |
Google Tag Manager | id |
heap() |
Heap | id |
hightouch() |
Hightouch | key |
hotjar() |
Hotjar | id |
logrocket() |
LogRocket | id |
mixpanel() |
Mixpanel | token |
oneDollarStats() |
OneDollarStats | — |
pirsch() |
Pirsch | code |
plausible() |
Plausible | domain |
posthog() |
PostHog | key |
segment() |
Segment | key |
vercel() |
Vercel Web Analytics | — |
script() |
Qualquer outro | src ou content |
A documentação do Blume usa um roteador do lado do cliente, então a maior parte da navegação é uma troca dentro da página, e não um carregamento completo. Todo adaptador conta essas trocas como visualizações de página: provedores cujo script acompanha sozinho as mudanças no histórico não precisam de nada extra, e, para os que só contam carregamentos reais (PostHog, Segment, Hightouch), o próprio Blume envia a visualização de página. As duas exceções são os gerenciadores de tags — o Google Tag Manager e o Adobe carregam um contêiner cujas próprias regras decidem o que é disparado, então dê a ele um acionador de mudança no histórico.
PostHog
Informe a sua chave de API do projeto ao posthog() para adicionar o PostHog. O host padrão é o PostHog Cloud US; defina host para o EU Cloud (https://eu.i.posthog.com) ou para uma instância auto-hospedada.
analytics: [
posthog({
key: "phc_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
host: "https://us.i.posthog.com", // optional, this is the default
}),
],
key e host são as duas opções que o Blume mapeia (host vira api_host). Qualquer outra coisa que você passar — persistence, capture_pageview, autocapture, disable_session_recording e todas as outras opções do posthog.init — é repassada ao posthog.init sem alterações.
O Blume só envia um $pageview a cada navegação do roteador do cliente enquanto o PostHog captura apenas os carregamentos de página, que é o comportamento dele quando você não define nem capture_pageview nem defaults. Com capture_pageview: "history_change", ou com uma data em defaults como "2025-05-24", que vem no snippet atual do PostHog, o próprio PostHog captura as navegações, então o Blume não envia nada extra. Com capture_pageview: false, nenhuma visualização de página é enviada.
Vercel Web Analytics
Adicione vercel() para incluir o Vercel Web Analytics. O Blume renderiza o componente Astro oficial da Vercel, que injeta o script nativo, servido a partir do seu próprio domínio, assim que o Web Analytics estiver ativado para o projeto no painel da Vercel.
analytics: [vercel()],
Não são necessárias chaves — o script envia os dados para o projeto em que foi feito o deploy. Isso só coleta dados em deploys na Vercel, onde o endpoint /_vercel/insights existe. Qualquer opção que você passar é repassada ao componente como prop (mode, debug, endpoint, scriptSrc, …); beforeSend é uma função e não pode passar pela config, então atribua window.webAnalyticsBeforeSend a partir de um adaptador script().
Cloudflare Web Analytics
O Cloudflare Web Analytics tem duas formas de configuração, e só uma delas precisa de um adaptador.
Zona com proxy (configuração automática). Se a Cloudflare serve o seu site — um Worker com domínio personalizado, Pages ou qualquer zona com a nuvem laranja ativada —, ative o Web Analytics para a zona no painel da Cloudflare e pronto. A Cloudflare injeta o beacon na edge, então deixe o cloudflare() de fora; listá-lo também faria cada visualização de página ser contada duas vezes.
Qualquer outro host (configuração manual). Para um site que a Cloudflare não faz proxy, adicione o site em Web Analytics no painel, copie o token do snippet JS fornecido (o token dentro de data-cf-beacon) e passe-o aqui. O Blume renderiza a mesma tag de beacon que o snippet.
analytics: [
cloudflare({
token: "0123456789abcdef0123456789abcdef",
}),
],
O objeto de opções inteiro vira o JSON data-cf-beacon do beacon, então qualquer outra configuração do beacon (spa, …) é repassada diretamente.
Google Analytics 4
Informe o ID de medição do seu fluxo de dados da web do GA4 (G-…, nos detalhes do fluxo, em Admin → Data Streams da propriedade) ao googleAnalytics(). O Blume renderiza a tag do Google exatamente como nas instruções de instalação do fluxo: o carregador assíncrono do gtag.js, além da inicialização do dataLayer e da chamada config.
analytics: [
googleAnalytics({
id: "G-XXXXXXXXXX",
anonymize_ip: true, // optional: any other `config` parameter
}),
],
id é a única opção que o Blume mapeia. Qualquer outra coisa que você passar vai na chamada gtag('config', …) sem alterações (send_page_view, cookie_domain, debug_mode, …). A medição otimizada do GA4 conta mudanças no histórico como visualizações de página por padrão, então as navegações do lado do cliente são rastreadas sem nenhuma configuração extra. O Google Analytics leva um ou dois dias para mostrar dados novos; a extensão Google Analytics Debugger mostra as requisições conforme elas acontecem.
Google Tag Manager
Informe o seu ID do contêiner (GTM-…, exibido no cabeçalho do espaço de trabalho) ao googleTagManager(). O Blume renderiza a metade do snippet do contêiner que vai no <head>; o iframe <noscript> é para navegadores sem JavaScript, que de qualquer forma nunca executam análises.
analytics: [
googleTagManager({
id: "GTM-XXXXXXX",
dataLayer: "dataLayer", // optional, this is the default
}),
],
Quais tags disparam, e em quê, é definido pela configuração do contêiner. As navegações do lado do cliente chegam ao contêiner como mudanças no histórico, então dispare as tags de visualização de página a partir de um acionador History Change, em vez do acionador de carregamento de página. Os banners de consentimento de cookies também ficam por sua conta, configurados no contêiner.
Plausible
Informe o domínio que você adicionou no Plausible ao plausible(). Para uma instância auto-hospedada ou com proxy, defina host com a origem dela; o padrão é o Plausible Cloud.
analytics: [
plausible({
domain: "docs.example.com",
host: "https://plausible.example.com", // optional, defaults to https://plausible.io
}),
],
domain vira data-domain e host define de onde o /js/script.js é carregado. Qualquer outra opção vira um atributo data- próprio na tag (api: "/api/event" → data-api). Variantes do script com comportamento extra embutido no nome do arquivo (script.outbound-links.js, …) são uma tag diferente; carregue-as com script().
Clics
Informe o ID do projeto, que fica em Configure → Tracking no painel do Clics, ao clics(). O Blume adiciona o rastreador de navegador do Clics com o atributo obrigatório data-project-id.
import { clics } from "blume/analytics";
analytics: [clics({ projectId: "YOUR_PROJECT_ID" })],
O rastreador conta automaticamente os carregamentos de página e as navegações do lado do cliente, incluindo as do roteador do cliente do Blume, então não adicione um segundo hook de visualização de página. Ele também rastreia links externos por padrão. Defina disableOutboundLinks: true para desativar esses eventos. Para um build de produção visualizado no localhost, defina allowLocalhost: true; o blume dev comum não carrega análises.
Os eventos personalizados do Blume não chegam ao Clics: o rastreador de navegador dele não tem uma função global de eventos para onde repassá-los. Para enviar os seus próprios eventos, chame o helper track() do @clicsdev/tracker no seu próprio código do lado do cliente.
Fathom
Informe o seu ID do site (nas configurações de script do site no Fathom) ao fathom().
analytics: [
fathom({
site: "ABCDEFGH",
"honor-dnt": "true", // optional: any other `data-` setting
}),
],
site vira data-site. Qualquer outra opção vira um atributo data- próprio na tag (honor-dnt, excluded-domains, canonical, …), como strings. O padrão de spa é "auto", para que o Fathom conte as navegações do roteador do cliente; passe o seu próprio valor de spa para sobrescrevê-lo.
Pirsch
Informe o seu código de identificação (Settings → Developer → Identification Code no Pirsch) ao pirsch().
analytics: [
pirsch({
code: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
}),
],
code vira data-code, e o Blume dá à tag o id pianjs, que o script do Pirsch usa para encontrar a si mesmo. Qualquer outra opção vira um atributo data- próprio (dev, exclude, include, domain, endpoint, …).
Databuddy
Informe o seu ID do cliente (nas configurações do site no Databuddy) ao databuddy().
analytics: [
databuddy({
clientId: "xxxxxxxxxxxxxxxxxxxxx",
"track-web-vitals": "true", // optional: any other `data-` setting
"skip-patterns": '["/admin/*"]',
}),
],
clientId vira data-client-id. Qualquer outra opção vira um atributo data- próprio na tag, então use o nome exatamente como o atributo é escrito, em kebab-case (track-web-vitals, track-errors, track-outgoing-links, api-url, …). O Databuddy ignora um nome em camelCase como trackWebVitals. Os valores são strings: "true" ou "false" para uma opção liga/desliga, e um array JSON para skip-patterns e mask-patterns. O Databuddy lê qualquer outro valor de lista como vazio.
OneDollarStats
Adicione o domínio do site no OneDollarStats e depois liste o oneDollarStats(). Ele não precisa de chave, porque o OneDollarStats associa os eventos a um site pelo domínio de onde eles vêm.
analytics: [oneDollarStats()],
Cada opção vira um atributo data- próprio na tag, e os valores são strings:
hostnameregistra todo evento sob esse nome de host (docs.example.com, semhttps://nem caminho) em qualquer host, não só nolocalhost, então deploys de preview e o ambiente de staging contam como tráfego desse site. Deixe-o sem definir, a menos que todo build deva registrar os eventos sob esse nome.devmode: "true"junto comhostnamepermite que umblume previewlocal envie eventos. Nolocalhost, o rastreador não envia nada sem os dois, então deixe-os de fora da config que vai para o repositório.urlé o endpoint do coletor para onde os eventos são enviados (https://collector.onedollarstats.com/eventspor padrão), e não a URL do site.autocollect: "false"desativa as visualizações de página automáticas."hash-routing": "true"envia uma visualização de página a cada navegação, mesmo quando só o#fragmentmuda, como num clique no sumário. Com"false", o Blume omite o atributo, porque o rastreador ativa o roteamento por hash sempre que ele está presente.
Mixpanel
Informe o seu token do projeto (configurações do projeto → Access Keys no Mixpanel) ao mixpanel(). Se o projeto usa residência de dados na UE ou na Índia, defina region de acordo, senão o Mixpanel descarta os eventos.
analytics: [
mixpanel({
token: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
region: "eu", // optional: "us" (default), "eu", or "in"
}),
],
token e region são as opções que o Blume mapeia (region vira api_host). O Blume também define track_pageview como "url-with-path-and-query-string", para que a própria biblioteca rastreie cada navegação. Qualquer outra coisa que você passar — incluindo track_pageview — é repassada ao mixpanel.init sem alterações (persistence, autocapture, record_sessions_percent, …).
Amplitude
Informe a sua chave de API do projeto (nas configurações do projeto no Amplitude) ao amplitude(). O Blume renderiza o snippet de carregamento de script do Browser SDK: o bundle do SDK vinculado à chave, além da chamada init.
analytics: [
amplitude({
key: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
serverZone: "EU", // optional: any other `init` option
}),
],
key é a única opção que o Blume mapeia. As opções do init partem do que vem no snippet do painel — autocapture: true e fetchRemoteConfig: true — e qualquer outra coisa que você passar é mesclada por cima delas sem alterações. O autocapture cobre visualizações de página e mudanças no histórico, então as navegações do lado do cliente são contadas.
Segment
Informe a chave de escrita da sua fonte JavaScript no Segment ao segment(). Se você serve o analytics.js a partir de um domínio personalizado para contornar bloqueadores de anúncios, defina cdn com essa origem.
analytics: [
segment({
key: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
cdn: "https://cdn.example.com", // optional, defaults to https://cdn.segment.com
}),
],
key e cdn são as opções que o Blume mapeia: o snippet carrega a biblioteca a partir de cdn e diz a ela para buscar as integrações de lá também. Qualquer outra coisa que você passar é repassada como as opções do analytics.load sem alterações (integrations, …).
Hightouch
Informe a chave de escrita da sua fonte de eventos no Hightouch ao hightouch(). O host padrão da API de eventos é o da região US East; defina host (sem o esquema) se o seu espaço de trabalho usa outra região.
analytics: [
hightouch({
key: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
host: "us-east-1.hightouch-events.com", // optional, this is the default
}),
],
key e host são as opções que o Blume mapeia (host vira apiHost). Qualquer outra coisa que você passar é repassada como as opções do htevents.load sem alterações.
Heap
Informe o seu ID do app (o ID do ambiente nas configurações de instalação do projeto no Heap) ao heap().
analytics: [
heap({
id: "1234567890",
disableTextCapture: true, // optional: any other `heap.load` option
}),
],
id é a única opção que o Blume mapeia. Qualquer outra coisa que você passar vira o objeto de configuração do heap.load sem alterações.
Hotjar
Informe o seu ID do site (o número no código de rastreamento do site no Hotjar) ao hotjar().
analytics: [
hotjar({
id: 1234567,
version: 6, // optional, this is the default
}),
],
id é o hjid e version é o hjsv no código de rastreamento do Hotjar; o adaptador não aceita mais nada.
Microsoft Clarity
Informe o seu ID do projeto (do código de rastreamento do projeto no Clarity) ao clarity().
analytics: [
clarity({
id: "xxxxxxxxxx",
}),
],
O adaptador não aceita mais nada; as configurações do Clarity ficam no painel dele.
LogRocket
Informe o seu ID do app (org/app, nas configurações do projeto no LogRocket) ao logrocket(). O Blume renderiza o snippet de instalação: o SDK, além da chamada protegida ao LogRocket.init.
analytics: [
logrocket({
id: "your-org/your-app",
release: "1.2.0", // optional: any other `init` option
}),
],
id é a única opção que o Blume mapeia. Qualquer outra coisa que você passar é repassada ao LogRocket.init sem alterações (release, console, network, dom, …). Um sanitizador de requisição ou de resposta é uma função e não pode passar pela config; nesses casos, remova o adaptador e chame o LogRocket.init você mesmo a partir de um adaptador script().
Clearbit
Informe a sua chave de API publicável (pk_…) ao clearbit(). O Blume renderiza a tag do Clearbit, que carrega quaisquer tags — Reveal, formulários — que você gerencia no Clearbit.
analytics: [
clearbit({
key: "pk_xxxxxxxxxxxxxxxx",
}),
],
O adaptador não aceita mais nada.
Adobe Analytics
Informe a URL do script de incorporação do seu ambiente do Launch (Adobe Experience Platform Tags) ao adobe(). Copie-a das instruções de instalação do ambiente, em Environments, no Data Collection; a de produção se parece com https://assets.adobedtm.com/…/launch-….min.js.
analytics: [
adobe({
url: "https://assets.adobedtm.com/xxxxxxxx/launch-xxxxxxxx.min.js",
}),
],
O Blume carrega o script de forma assíncrona; o que ele rastreia é definido pelas regras da propriedade. As navegações do lado do cliente não recarregam a página, então crie na propriedade uma regra para mudanças no histórico (ou chame _satellite.track a partir de um adaptador script()).
Scripts personalizados
Use script() para carregar qualquer provedor sem adaptador, ou a tag de um provedor em um formato que o adaptador dele não renderiza. Cada um renderiza uma tag <script> e precisa definir exatamente um entre src (externo) ou content (inline).
analytics: [
// Umami
script({
src: "https://cloud.umami.is/script.js",
strategy: "defer",
attributes: { "data-website-id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" },
}),
// An inline snippet
script({
content: "console.log('analytics ready')",
}),
],
attributes é um mapa de atributos HTML adicionais (data-*, id, …) aplicados à tag, e strategy adiciona async ou defer a scripts externos.
Um src relativo à raiz aponta para um arquivo em public/ (src: "/js/redirects.js" para public/js/redirects.js), então, com um deployment.base, ele recebe a base, assim como um link: com base: "/docs", a tag carrega /docs/js/redirects.js. Um src que já começa com a base fica como foi escrito, e uma URL absoluta ou relativa ao protocolo é repassada sem alterações, então um script servido fora da base do site precisa da URL completa.
Opções
| Adaptador | Opção | Padrão | Descrição |
|---|---|---|---|
adobe() |
url |
— | URL do script de incorporação do ambiente do Launch. Obrigatória. |
amplitude() |
key |
— | Chave de API do projeto no Amplitude. Obrigatória. |
amplitude() |
qualquer outra | autocapture: true, fetchRemoteConfig: true |
Mesclada nas opções do amplitude.init sem alterações. |
clarity() |
id |
— | ID do projeto no Clarity. Obrigatória. |
clearbit() |
key |
— | Chave de API publicável do Clearbit. Obrigatória. |
clics() |
projectId |
— | ID público do projeto no Clics. Obrigatória. |
clics() |
allowLocalhost |
false |
Emite data-allow-localhost para visualizações locais de um build de produção. |
clics() |
disableOutboundLinks |
false |
Emite data-disable-outbound-links para interromper o rastreamento de links externos. |
cloudflare() |
token |
— | Token do site no Cloudflare Web Analytics (configuração manual). Obrigatória. |
cloudflare() |
qualquer outra | — | Repassada no JSON data-cf-beacon do beacon sem alterações. |
databuddy() |
clientId |
— | ID do cliente no Databuddy. Obrigatória. |
databuddy() |
qualquer outra | — | Renderizada como um atributo data- na tag. |
fathom() |
site |
— | ID do site no Fathom. Obrigatória. |
fathom() |
spa |
"auto" |
Rastreamento de mudanças no histórico do Fathom (data-spa). |
fathom() |
qualquer outra | — | Renderizada como um atributo data- na tag. |
googleAnalytics() |
id |
— | ID de medição do GA4. Obrigatória. |
googleAnalytics() |
qualquer outra | — | Repassada na chamada gtag('config', …) sem alterações. |
googleTagManager() |
id |
— | ID do contêiner do Tag Manager. Obrigatória. |
googleTagManager() |
dataLayer |
dataLayer |
Nome da variável global da camada de dados que o contêiner lê. |
heap() |
id |
— | ID do app no Heap. Obrigatória. |
heap() |
qualquer outra | — | Repassada como a configuração do heap.load sem alterações. |
hightouch() |
key |
— | Chave de escrita da fonte de eventos do Hightouch. Obrigatória. |
hightouch() |
host |
us-east-1.hightouch-events.com |
Host da API de eventos, sem o esquema. |
hightouch() |
qualquer outra | — | Repassada como as opções do htevents.load sem alterações. |
hotjar() |
id |
— | ID do site no Hotjar (hjid). Obrigatória. |
hotjar() |
version |
6 |
Versão do código de rastreamento (hjsv). |
logrocket() |
id |
— | ID do app no LogRocket (org/app). Obrigatória. |
logrocket() |
qualquer outra | — | Repassada ao LogRocket.init sem alterações. |
mixpanel() |
token |
— | Token do projeto no Mixpanel. Obrigatória. |
mixpanel() |
region |
us |
Região de residência de dados: us, eu ou in. |
mixpanel() |
qualquer outra | track_pageview: "url-with-path-and-query-string" |
Mesclada nas opções do mixpanel.init sem alterações. |
oneDollarStats() |
hostname |
— | Nome de host, sem esquema nem caminho, sob o qual todo evento é registrado, em qualquer host. |
oneDollarStats() |
qualquer outra | — | Renderizada como um atributo data- na tag ("hash-routing": "false" é omitido). |
pirsch() |
code |
— | Código de identificação do Pirsch. Obrigatória. |
pirsch() |
qualquer outra | — | Renderizada como um atributo data- na tag. |
plausible() |
domain |
— | O domínio do site no Plausible. Obrigatória. |
plausible() |
host |
https://plausible.io |
Origem de uma instância auto-hospedada ou com proxy. |
plausible() |
qualquer outra | — | Renderizada como um atributo data- na tag. |
posthog() |
key |
— | Chave de API do projeto PostHog. Obrigatória. |
posthog() |
host |
https://us.i.posthog.com |
Host de ingestão do PostHog (EU Cloud ou auto-hospedado). |
posthog() |
qualquer outra | — | Repassada ao posthog.init sem alterações. |
segment() |
key |
— | Chave de escrita da fonte no Segment. Obrigatória. |
segment() |
cdn |
https://cdn.segment.com |
Origem de um domínio personalizado que faz proxy da CDN do Segment. |
segment() |
qualquer outra | — | Repassada como as opções do analytics.load sem alterações. |
vercel() |
mode, debug, … |
— | Repassadas ao componente Astro oficial como props. |
script() |
src |
— | URL do script externo. Mutuamente exclusivo com content. |
script() |
content |
— | Corpo do script inline. Mutuamente exclusivo com src. |
script() |
strategy |
— | async ou defer para um script externo. |
script() |
attributes |
— | Atributos HTML adicionais aplicados à tag <script>. |
Eventos personalizados
O feedback de página do Blume (feedback, e feedback_comment quando o feedback escrito está ativado), a busca (search, search_select), o assistente (ask, ask_answer, ask_error) e o player de narração (narration_play, narration_complete) enviam eventos personalizados por meio de todo adaptador configurado que tenha uma API no cliente — PostHog, Mixpanel, Heap, Segment, Hightouch, Amplitude, LogRocket, Adobe, Google Analytics, Google Tag Manager (como um push de { event } no window.dataLayer), Plausible, Databuddy, Fathom, OneDollarStats (com cada valor de propriedade como string), Pirsch, Clarity, Hotjar e Vercel. O Fathom, o Clarity e o Hotjar recebem só o nome do evento, então contam cada evento sem as propriedades dele. A Cloudflare e o Clearbit não têm API de eventos, e o Clics não tem uma API global que o Blume possa chamar. Todo evento também é disparado como um CustomEvent blume:track no window, com { event, props } em detail, para que um adaptador script() possa repassá-lo para qualquer outro lugar. O assistente nunca envia o texto de uma pergunta a um provedor, e a busca envia as consultas exatamente como foram digitadas, a menos que você defina search.analytics.queries como false, o que faz ela enviar o tamanho de cada consulta no lugar do texto; de qualquer forma, o texto continua chegando ao evento blume:track, para que um listener escrito por você o repasse. Para fazer o deploy do seu site já construído, veja Deploy.