Sprucely title background

Integração

Você pode integrar dashboards interativos do Sprucely.io ao seu site ou aplicação web de três formas: incorporando-os com um iframe HTML padrão, renderizando-os nativamente com o runtime JavaScript independente, ou montando os componentes React independentes. O iframe é a forma mais rápida de configurar; os runtimes independentes desenham os dashboards diretamente na sua página e permitem enviar novos dados em tempo de execução. O formato JSON que os runtimes independentes leem - dashboards, gráficos e datasets - está documentado na referência de formato de dados. Para automação de dashboards orientada por IA, consulte a seção de MCP APIs.

Incorporando Dashboards em HTML

A integração mais simples usa o elemento HTML iframe padrão e funciona em qualquer site, ou até em páginas HTML locais. O dashboard precisa estar compartilhado, seja na nuvem ou on-premise, para carregar com sucesso. Observe que dashboards on-premise só carregam quando o cliente que os acessa está dentro da mesma rede corporativa.

Instruções:

1) Extraia o link de incorporação do dashboard - Na página Dashboards, garanta que seu dashboard esteja compartilhado e clique no ícone deste dashboard. Um banner verde de notificação vai avisar que o link foi copiado para a área de transferência. Você vai usar esse link para substituir o conteúdo do src do iframe HTML abaixo.

2) Incorpore o dashboard com tamanho fixo

<html>
  <head>
    <title>Sprucely.io Dashboard</title>
  </head>
  <body>
    <h1>Sprucely.io Dashboard</h1>
    <iframe src="https://www.sprucely.io/service/dashboards/embed/[userId]/[dashboardId]/"
            allow="clipboard-write"
            style="height: 500px; width: 700px;"
            title="Sprucely.io Dashboard"></iframe>
  </body>
</html>

(ou) Incorpore o dashboard com largura dinâmica - Redimensiona o dashboard automaticamente com base na largura do documento pai

Você pode usar o parâmetro de estilo aspect-ratio para recalcular automaticamente a altura com base na largura.

<html>
  <head>
    <title>Sprucely.io Dashboard</title>
  </head>
  <body>
    <h1>Sprucely.io Dashboard</h1>
    <iframe src="https://www.sprucely.io/service/dashboards/embed/[userId]/[dashboardId]/"
            allow="clipboard-write"
            scrolling="no"
            style="width: 100%; aspect-ratio: 1.5; border: none;"
            title="Sprucely.io Dashboard"></iframe>
  </body>
</html>

3) Outras opções úteis de incorporação

Você pode adicionar modificações de estilo personalizadas ao bloco de estilo do elemento iframe, para customizar a aparência do frame. Esses parâmetros seguem as diretrizes de HTML e CSS padrão. O exemplo abaixo adiciona uma borda cinza ao redor do dashboard:

<html>
  <head>
    <title>Sprucely.io Dashboard</title>
  </head>
  <body>
    <h1>Sprucely.io Dashboard</h1>
    <iframe src="https://www.sprucely.io/service/dashboards/embed/[userId]/[dashboardId]/"
            allow="clipboard-write"
            style="height: 100%; width: 100%; border: 2px solid grey;"
            title="Sprucely.io Dashboard"></iframe>
  </body>
</html>

Incorporação com JavaScript Independente

O runtime independente renderiza os dashboards diretamente dentro da sua página - sem iframe. Seus dados são carregados em um banco de dados no navegador e desenhados como gráficos totalmente interativos; o runtime só entra em contato com o Sprucely.io para validar seu token de acesso.

Instruções:

1) Crie um token de acesso - Na seção Tokens de acesso do seu perfil, crie um token de acesso para a origem a partir da qual suas páginas são servidas (por exemplo, https://www.yourdomain.com). O runtime valida que a origem da página de incorporação corresponde ao token antes de renderizar.

2) Carregue o runtime e renderize um dashboard - Adicione o script do runtime à sua página, conecte o banco de dados no navegador uma vez com sprucely_db, e depois renderize cada dashboard com sprucely_create. A página completa abaixo também conecta um botão que anexa mais linhas:

<html>
  <head>
    <title>Orders Dashboard</title>
  </head>
  <body>
    <div id="database"></div>
    <div id="orders_dashboard"></div>
    <button onclick="addRows()">Add rows</button>

    <script src="https://www.sprucely.io/cross-origin/sprucely-runtime.min.js"></script>
    <script>
      const data = {
        name:    "Orders",
        headers: ["region", "amount", "items"],
        types:   ["VARCHAR", "FLOAT", "INTEGER"],
        entries: [
          ["North", 120.50, 2],
          ["South",  89.95, 1],
          ["North", 432.00, 5],
          ["South",  74.50, 1]
        ]
      };

      const dashboard = {
        config: {
          type: "dashboard",
          style: {
            widget: {
              color: "#667FFF",
              backgroundColor: "#0C0B29",
              primaryColor: "#01EEAE",
              primaryColorSubtle: "#C70584",
              secondaryColor: "#2C2B49"
            }
          }
        },
        data: {
          type: "dash",
          children: [
            {
              type: "dash_stacker_hor",
              children: [
                { type: "dash_chart", datasetId: "Orders", x: "region", chartType: "bar", dataFunction: "count" },
                { type: "dash_chart", datasetId: "Orders", x: "amount", y: "items", chartType: "hexbin", dataFunction: "count" }
              ]
            }
          ]
        }
      };

      sprucely_db({
        id: "database",
        host: "https://www.yourdomain.com",
        accessToken: "YOUR_ACCESS_TOKEN"
      });
      sprucely_create({ id: "orders_dashboard", dashboard, data });

      function addRows() {
        sprucely_add({
          name:    "Orders",
          headers: ["region", "amount", "items"],
          types:   ["VARCHAR", "FLOAT", "INTEGER"],
          entries: [
            ["East", 310.40, 3],
            ["West", 129.95, 1]
          ]
        });
      }
    </script>
  </body>
</html>

3) Anexe dados em tempo de execução - Chame sprucely_add com linhas adicionais a qualquer momento. Todo dashboard que usa o dataset é atualizado automaticamente:

sprucely_add({
  name:    "Orders",
  headers: ["region", "amount", "items"],
  types:   ["VARCHAR", "FLOAT", "INTEGER"],
  entries: [
    ["East", 310.40, 3],
    ["West", 129.95, 1]
  ]
});

Referência de funções

  • sprucely_db({ id, host, accessToken }) - conecta o banco de dados no navegador e valida seu token de acesso contra a origem da página. Renderiza um banner de status no elemento identificado por id. Chame-a uma vez por página, antes de criar dashboards.
  • sprucely_create({ id, dashboard, data }) - renderiza um dashboard no elemento identificado por id. O parâmetro dashboard define layout e estilização; data fornece o dataset com seu nome, cabeçalhos, tipos de coluna (VARCHAR, INTEGER, FLOAT ou TIMESTAMP) e linhas - veja a referência de formato de dados.
  • sprucely_add(data) - anexa linhas ao dataset cujo nome corresponde a um dataset já carregado, e depois atualiza todos os dashboards que o usam.

Incorporação com React Independente

Se o seu site é construído com React, você pode renderizar dashboards como componentes em vez de carregar o script manualmente. Os componentes usam os mesmos tokens de acesso, definições de dashboard e formato de dataset do runtime JavaScript independente.

Instruções:

1) Crie um token de acesso - Assim como no JavaScript independente, crie um token de acesso para a origem do seu site na seção Tokens de acesso do seu perfil.

2) Renderize os componentes de dashboard - Obtenha o runtime em https://www.sprucely.io/cross-origin/sprucely-runtime.min.cjs.js e coloque-o no seu projeto. Monte um componente Sprucely.Database por página, e um componente Sprucely.Dashboard por dashboard. Os dashboards mostram um indicador de carregamento até que o banco de dados tenha validado o token de acesso, e então renderizam. A aplicação completa abaixo renderiza dois dashboards a partir de datasets separados e anexa novas linhas ao primeiro após cinco segundos:

// Get https://www.sprucely.io/cross-origin/sprucely-runtime.min.cjs.js
// and place it in your project, next to this file.

import React, { useEffect } from "react";
import { createRoot } from "react-dom/client";
import Sprucely, { sprucely_add } from "./sprucely-runtime.min.cjs.js";

const style = {
  widget: {
    color: "#667FFF",
    backgroundColor: "#0C0B29",
    primaryColor: "#01EEAE",
    primaryColorSubtle: "#C70584",
    secondaryColor: "#2C2B49"
  }
};

const orders = {
  name:    "Orders",
  headers: ["region", "amount", "items"],
  types:   ["VARCHAR", "FLOAT", "INTEGER"],
  entries: [
    ["North", 120.50, 2],
    ["South",  89.95, 1],
    ["North", 432.00, 5],
    ["South",  74.50, 1]
  ]
};

const returns = {
  name:    "Returns",
  headers: ["reason", "amount", "days"],
  types:   ["VARCHAR", "FLOAT", "INTEGER"],
  entries: [
    ["Damaged", 45.00, 3],
    ["Late",    12.50, 8],
    ["Changed", 99.90, 2]
  ]
};

const moreOrders = {
  name:    "Orders",
  headers: ["region", "amount", "items"],
  types:   ["VARCHAR", "FLOAT", "INTEGER"],
  entries: [
    ["East", 310.40, 3],
    ["West", 129.95, 1]
  ]
};

const ordersDashboard = {
  config: { type: "dashboard", style },
  data: {
    type: "dash",
    children: [
      {
        type: "dash_stacker_hor",
        children: [
          { type: "dash_chart", datasetId: "Orders", x: "region", chartType: "bar", dataFunction: "count" },
          { type: "dash_chart", datasetId: "Orders", x: "amount", y: "items", chartType: "hexbin", dataFunction: "count" }
        ]
      }
    ]
  }
};

const returnsDashboard = {
  config: { type: "dashboard", style },
  data: {
    type: "dash",
    children: [
      {
        type: "dash_stacker_hor",
        children: [
          { type: "dash_chart", datasetId: "Returns", x: "amount", y: "days", d: "amount", r: "days", chartType: "dot", dataFunction: "average" }
        ]
      }
    ]
  }
};

const App = () => {
  useEffect(() => {
    const timer = setTimeout(() => { sprucely_add(moreOrders); }, 5000);
    return () => clearTimeout(timer);
  }, []);

  return (
    <>
      <Sprucely.Database host="https://www.yourdomain.com" accessToken="YOUR_ACCESS_TOKEN" />
      <Sprucely.Dashboard id="orders_dashboard" dashboard={ordersDashboard} data={orders} />
      <Sprucely.Dashboard id="returns_dashboard" dashboard={returnsDashboard} data={returns} />
    </>
  );
};

createRoot(document.getElementById("root")).render(<App />);

Fornecimento de Chaves de Curta Duração

O token de acesso que você cria acima tem vida longa e deve permanecer um segredo do lado do servidor. Se o seu próprio backend serve as páginas de incorporação - em vez de uma página sem backend próprio - você não precisa colocar esse token de longa duração na página em nenhum momento - seu backend pode trocá-lo, servidor a servidor, por um token de renderização de curta duração (15 minutos) imediatamente antes de servir cada página, e apenas o token de renderização chega ao navegador. Um token de renderização que um visitante extrai da página só é útil por alguns minutos, não indefinidamente.

Instruções:

1) Troque seu token de acesso por um token de renderização - a partir do seu backend, chame POST https://www.sprucely.io/api/auth/render_token usando seu token de acesso como credencial bearer. A resposta traz o novo token, o host ao qual ele está vinculado, e seu tempo de vida em segundos:

// On your server, immediately before serving each embedding page:
const response = await fetch("https://www.sprucely.io/api/auth/render_token", {
  method:  "POST",
  headers: { Authorization: "Bearer " + process.env.SPRUCELY_ACCESS_TOKEN }
});
const { token, expires_in } = await response.json(); // expires_in: 900 (15 minutes)

// Send only the render token to the browser - never the long-lived access
// token itself:
res.send(`
  <script src="https://www.sprucely.io/cross-origin/sprucely-runtime.min.js"></script>
  <script>
    sprucely_db({
      id: "database",
      host: "https://www.yourdomain.com",
      accessToken: "${token}"
    });
  </script>
`);

2) Sirva o token de renderização ao navegador - use-o exatamente como um token de acesso ao chamar sprucely_db ou montar Sprucely.Database. Repita a troca antes de servir cada página (ou em um temporizador, se você mantiver a página renderizada em cache), para que o navegador nunca receba um token válido por mais de 15 minutos.

Referência de funções

  • POST /api/auth/render_token - troca um token de acesso válido, enviado como Authorization: Bearer <token>, por um token de renderização. Retorna { token, host, expires_in } com expires_in fixo em 900 segundos. Um token de renderização não pode ser trocado por outro token de renderização - apenas um token de acesso de longa duração pode solicitá-lo.

Configurações de Segurança

Se o seu site aplica uma Content Security Policy (CSP), as integrações de JavaScript e React independentes acima precisam de algumas origens permitidas antes que os dashboards carreguem - o runtime carrega seu script a partir do Sprucely.io, abre um banco de dados no navegador baseado em WebAssembly, e valida seu token de acesso junto à nossa API, e cada um desses pontos precisa de uma permissão CSP explícita. Se o seu site não usa CSP, você pode pular esta seção.

Adicione as seguintes origens à sua política existente - estas são diretivas para mesclar, não uma política completa para substituir o que você já tem:

script-src   'self' https://www.sprucely.io 'wasm-unsafe-eval';
connect-src  'self' https://www.sprucely.io;
worker-src   'self' blob: https://www.sprucely.io;

Para que serve cada diretiva:

  • script-src - https://www.sprucely.io carrega o script do runtime. 'wasm-unsafe-eval' é necessário para compilar e executar o banco de dados no navegador, que é construído sobre WebAssembly.
  • connect-src - https://www.sprucely.io é contatado para validar seu token de acesso e para carregar os arquivos WebAssembly e worker do banco de dados.
  • worker-src - o banco de dados no navegador executa suas consultas em uma thread em segundo plano, criada a partir de uma URL blob:.

Nenhuma das diretivas acima requer 'unsafe-inline' - o próprio runtime do Sprucely nunca precisa dela. Se você mantiver suas próprias definições de dashboard e dataset em uma tag <script> inline, como no exemplo de JavaScript independente acima, ou se sua própria página usa estilos inline, adicione 'unsafe-inline' a script-src ou style-src, ou considere usar nonces de CSP.