https://a.storyblok.com/f/270183/40469/7f8526f41f/blog_nuxt_server-side-analytics_1200x600.png

Análise do lado do servidor em sites Jamstack

Publicado em November 30, 2020

Tempo de leitura: 5 minutos

Os sites Jamstack não possuem um back-end. Isso torna sua capacidade de coletar dados analíticos particularmente vulnerável a bloqueadores. Vamos resolver esse problema.

Este exemplo inclui uma função do Netlify que enviará nossos eventos para o Google Analytics e uma regra de redirecionamento do Netlify .

O problema

Os rastreadores e os pixels de rastreamento são códigos HTML criados para capturar o comportamento dos usuários ou registrar suas visitas quando acessam um site ou abrem um e-mail. Eles são úteis para monitorar o uso do seu site e, às vezes, as conversões.

O problema é que alguns rastreadores são lentos e, muitas vezes, invasivos. Os bloqueadores de anúncios foram inicialmente criados para impedir que anúncios e pixels de rastreamento prejudicassem o desempenho das páginas da web, ou para melhorar a experiência do usuário, mas, posteriormente, passaram a ser utilizados também para aumentar a privacidade dos usuários.

Um efeito colateral foi que muitos proprietários de sites perderam a noção do que funcionava e do que não funcionava em seus sites. Características de rastreamento físico ainda podem ser usadas para monitorar certas métricas; por exemplo, adicionar o identificador de um artigo a um link de cadastro para verificar de onde veio o cadastro.

Isso ainda não nos ajuda a determinar com precisão se nosso conteúdo está sendo visualizado, um requisito fundamental para avaliar a conversão.

A solução

A análise do lado do servidor tornou-se uma forma popular de acompanhar a atividade dos usuários. Ela não tem o mesmo alcance da análise tradicional (não consegue rastrear facilmente as interações na página), mas é capaz de capturar detalhes importantes, como visualizações únicas de página.

Plataformas de hospedagem como Netlify, ou provedores de Edge como Cloudflare e Fastly, oferecem análises do lado do servidor como parte de suas soluções. No entanto, ao utilizar um provedor para análises, muitas vezes você fica restrito quanto à forma de armazenar essas informações, o que limita a geração de relatórios internos.

Por esse motivo, algumas pessoas preferem desenvolver suas próprias soluções de análise do lado do servidor. Para isso, o Google oferece alguns guias de introdução rápida para algumas linguagens, e para outras existem pacotes como universal-analytics.

Aqui, vamos criar nossa própria solução usando universal-analytics e uma função do Netlify.

Função do Netlify

As Netlify Functions são, basicamente, funções do AWS Lambda, mas sem a AWS. A experiência do desenvolvedor na AWS deixa MUITO a desejar, e a Netlify transformou a experiência do usuário em um modelo de negócios. As Netlify Functions não são exceção, permitindo que as pessoas escrevam código em JavaScript ou Go em um diretório configurado e o publiquem em poucas etapas. O endpoint é derivado do nome do arquivo ou da pasta e pode usar as dependências do aplicativo pai ou ser responsável pelas próprias.

Uma função super simples pode ser assim:

// functions/hello-world/index.js

exports.handler = (event, context) => {
  console.log('Only the server will see this!')

  return {
    statusCode: 200,
    body: 'Hello, world!',
  }
}

Depois de implantado, você poderá acessá-lo por meio de uma URL como esta: https://your-app.netlify.app/.netlify/functions/hello-world

Mas você também pode continuar realizando outras ações depois de enviar uma resposta, assim:

// functions/hello-world/index.js

exports.handler = (event, context, callback) => {
  callback(null, {
    statusCode: 200,
    body: 'Hello, world!',
  })

  console.log('The server will still see this!')
}

Agora, poderíamos usar essa funcionalidade para enviar nossos dados analíticos ao Google.

Observação: Se você estiver adicionando dependências a uma função, será necessário adicionar o @netlify/plugin-functions-install-core plug-in à sua netlify.toml configuração. Esse plugin garantirá que todas as dependências da função estejam instaladas quando ela for implantada.

Precisamos instalar universal-analytics primeiro, então certifique-se de estar no diretório da sua função antes de executar o comando a seguir.

npm install universal-analytics

Certifique-se de ter um ID do Google Analytics e adicione-o ao seu variáveis de ambiente do Netlify.

Agora, podemos usá-la em nossa função.

// functions/hello-world/index.js

const ua = require('universal-analytics')
const visitor = ua(process.env.GOOGLE_ANALYTICS_ID)

exports.handler = (event, context, callback) => {
  callback(null, {
    statusCode: 200,
    body: 'Hello, world!',
  })

  const { queryStringParameters: data } = event

  try {
    if (data) {
      visitor.pageview(data).send()
    }
  } catch (error) {
    console.log(error) // eslint-disable-line
  }
}

Agora, pelo seu navegador, você pode enviar dados diretamente da URL para o Google: https://your-app.netlify.app/.netlify/functions/hello-world?dp=/my-custom-page

Os dados que você pode enviar incluem — entre outros — os seguintes parâmetros:

{
  dp, // path e.g. /my-custom-page
  dt, // title of the page
  dh, // hostname e.g. https://netlify.com
  dr, // referrer e.g. https://netlify.com/as-a-referrer or /a-link
  ua, // user agent e.g. very obscure string meaning "chrome on mac"
  cs, // utm_source
  cm, // utm_medium
  cn, // utm_campaign
  ck, // utm_term
  cc, // utm_content
}

Aqui está uma lista completa dos parâmetros aceitáveis.

Adicione a “Imagem”

Chamar apenas esse script, por meio de algo como um middleware de roteador ou uma solicitação AJAX, pode ser suficiente em muitos casos para gerar relatórios satisfatórios, mas ele ainda pode ser reconhecido como uma solicitação XHR por um navegador ou por um bloqueador de anúncios e, consequentemente, bloqueado.

Uma solução (normalmente excessivamente complexa) que decidi adotar era semelhante ao método do pixel de rastreamento. No entanto, como retornamos uma imagem estrutural visível, os bloqueadores de anúncios a têm ignorado completamente até o momento.

Screenshot of AdBlock Plus ignoring the tracker on Vonage LearnScreenshot of AdBlock Plus

Vamos retornar uma imagem SVG da função do Netlify e inseri-la em uma página usando uma tag de imagem.

Vamos usar essa imagem.

A fonte desta imagem pode ser encontrada aqui:

<svg id="svg1923" width="733" xmlns="http://www.w3.org/2000/svg" height="733">
<circle cy="366.5" cx="366.5" r="366.5"/>
<circle cy="366.5" cx="366.5" r="336.5" fill="#fede58"/>
<path d="m325 665c-121-21-194-115-212-233v-8l-25-1-1-18h481c6 13 10 27 13 41 13 94-38 146-114 193-45 23-93 29-142 26z"/>
<path d="m372 647c52-6 98-28 138-62 28-25 46-56 51-87 4-20 1-57-5-70l-423-1c-2 56 39 118 74 157 31 34 72 54 116 63 11 2 38 2 49 0z" fill="#871945"/>
<path d="m76 342c-13-26-13-57-9-85 6-27 18-52 35-68 21-20 50-23 77-18 15 4 28 12 39 23 18 17 30 40 36 67 4 20 4 41 0 60l-6 21z"/>
<path d="m234 323c5-6 6-40 2-58-3-16-4-16-10-10-14 14-38 14-52 0-15-18-12-41 6-55 3-3 5-5 5-6-1-4-22-8-34-7-42 4-57.6 40-66.2 77-3 17-1 53 4 59h145.2z" fill="#fff"/>
<path d="m378 343c-2-3-6-20-7-29-5-28-1-57 11-83 15-30 41-52 72-60 29-7 57 0 82 15 26 17 45 49 50 82 2 12 2 33 0 45-1 10-5 26-8 30z"/>
<path d="m565 324c4-5 5-34 4-50-2-14-6-24-8-24-1 0-3 2-6 5-17 17-47 13-58-9-7-16-4-31 8-43 4-4 7-8 7-9 0 0-4-2-8-3-51-17-105 20-115 80-3 15 0 43 3 53z" fill="#fff"/>
<path d="m504 590s-46 40-105 53c-66 15-114-7-114-7s14-76 93-95c76-18 126 49 126 49z" fill="#f9bedd"/>
</svg>

Agora, para retornar a imagem da nossa função:

// functions/hello-world/index.js

const ua = require('universal-analytics')
const visitor = ua(process.env.GOOGLE_ANALYTICS_ID)

exports.handler = (event, context, callback) => {
  callback(null, {
    statusCode: 200,
    headers: {
      'Content-Type': 'image/svg+xml',
    },
    body: `<svg id="svg1923" width="733" xmlns="http://www.w3.org/2000/svg" height="733">
<circle cy="366.5" cx="366.5" r="366.5"/>
<circle cy="366.5" cx="366.5" r="336.5" fill="#fede58"/>
<path d="m325 665c-121-21-194-115-212-233v-8l-25-1-1-18h481c6 13 10 27 13 41 13 94-38 146-114 193-45 23-93 29-142 26z"/>
<path d="m372 647c52-6 98-28 138-62 28-25 46-56 51-87 4-20 1-57-5-70l-423-1c-2 56 39 118 74 157 31 34 72 54 116 63 11 2 38 2 49 0z" fill="#871945"/>
<path d="m76 342c-13-26-13-57-9-85 6-27 18-52 35-68 21-20 50-23 77-18 15 4 28 12 39 23 18 17 30 40 36 67 4 20 4 41 0 60l-6 21z"/>
<path d="m234 323c5-6 6-40 2-58-3-16-4-16-10-10-14 14-38 14-52 0-15-18-12-41 6-55 3-3 5-5 5-6-1-4-22-8-34-7-42 4-57.6 40-66.2 77-3 17-1 53 4 59h145.2z" fill="#fff"/>
<path d="m378 343c-2-3-6-20-7-29-5-28-1-57 11-83 15-30 41-52 72-60 29-7 57 0 82 15 26 17 45 49 50 82 2 12 2 33 0 45-1 10-5 26-8 30z"/>
<path d="m565 324c4-5 5-34 4-50-2-14-6-24-8-24-1 0-3 2-6 5-17 17-47 13-58-9-7-16-4-31 8-43 4-4 7-8 7-9 0 0-4-2-8-3-51-17-105 20-115 80-3 15 0 43 3 53z" fill="#fff"/>
<path d="m504 590s-46 40-105 53c-66 15-114-7-114-7s14-76 93-95c76-18 126 49 126 49z" fill="#f9bedd"/>
</svg>`,
  })

  const { queryStringParameters: data } = event

  try {
    if (data) {
      visitor.pageview(data).send()
    }
  } catch (error) {
    console.log(error) // eslint-disable-line
  }
}

Adicione isso ao seu site usando a URL que usamos anteriormente:

<img 
  alt="An SVG file of a very smiley Emoji"
  title="An SVG Emoji"
  width="128" 
  src="/.netlify/functions/hello-world?dp=/my-custom-page"
/>

Se tudo der certo, ficará assim:

Screenshot of the smiley included in pageAn image of a smiley

Regra de redirecionamento

Então, a parte mais engenhosa e tortuosa da minha ideia de plano maligno talvez seja o que vem a seguir. Eu estava um pouco paranóico com a possibilidade de um bloqueador de anúncios detectar uma URL que não fosse de imagem, mas contivesse parâmetros na string de consulta, como algo tão suspeito quanto a fonte de uma imagem, e bloqueá-la mesmo assim.

Entrar Redirecionamentos do Netlify.

Usando o netlify.toml na raiz do seu projeto, você pode redirecionar um caminho para outro.

[[redirects]]
  from = "/images/smiley-face.svg"
  to = "/.netlify/functions/hello-world"
  status = 200
  force = true

Agora, você pode usar um caminho de imagem para incluir seu smiley.

<img 
  alt="An SVG file of a very smiley Emoji"
  title="An SVG Emoji"
  width="128" 
  src="/images/smiley-face.svg?dp=/my-custom-page"
/>

Você pode codificar a string de consulta da maneira que quiser, mas lembre-se de decodificá-la dentro da função.

Conclusão

A análise de dados é um superpoder para o marketing e para os criadores de conteúdo. Ela nos permite atender melhor à comunidade, ajustando nossas metas com base nos dados que conseguimos coletar.

Muitas vezes, surgem preocupações com a privacidade e a velocidade em relação aos rastreadores. Mas, desde que se aja de boa-fé — como acredito que estamos fazendo —, a análise de dados beneficia os espectadores tanto quanto a qualquer outra pessoa.

Essa é uma maneira bacana de realizar análises do lado do servidor (que os bloqueadores não conseguem bloquear), quando você não tem um ambiente do lado do servidor à sua disposição.

Compartilhar:

https://a.storyblok.com/f/270183/250x250/451101b4f0/lukeoliff.png
Luke OliffEx-funcionários da Vonage

Educador de tecnologia com um jeito amigável, pai de família, defensor da diversidade, provavelmente discuto um pouco demais. Ex-engenheiro de backend. Fale comigo sobre JavaScript (front-end ou back-end), o incrível Vue.js, DevOps, DevSecOps e tudo relacionado ao JamStack. Escritor no DEV.to