Vous pouvez intégrer des tableaux de bord interactifs Sprucely.io à votre propre site web ou application web de trois façons : en les intégrant avec un élément HTML iframe standard, en les affichant nativement avec le runtime JavaScript autonome, ou en montant les composants React autonomes. L’iframe est la solution la plus rapide à mettre en place ; les runtimes autonomes dessinent les tableaux de bord directement dans votre page et vous permettent d’y injecter de nouvelles données à l’exécution. La structure JSON que lisent les runtimes autonomes - tableaux de bord, graphiques et jeux de données - est documentée dans la référence format de données. Pour l’automatisation des tableaux de bord pilotée par l’IA, consultez la section API MCP.
Intégrer des tableaux de bord dans une page HTML
L’intégration la plus simple utilise l’élément HTML iframe standard et fonctionne sur n’importe quel site web, voire des pages HTML locales. Le tableau de bord doit être partagé, dans le Cloud ou sur site, pour se charger correctement. Notez que les tableaux de bord sur site ne se chargeront que si le client qui y accède se trouve sur le même réseau d’entreprise.
Instructions :
1) Extraire le lien d’intégration du tableau de bord - Sur la page Tableaux de bord, assurez-vous que votre tableau de bord est partagé, puis cliquez sur l’icône de ce tableau de bord. Une bannière contextuelle verte vous informera que le lien a été copié dans le presse-papiers. Vous l’utiliserez pour remplacer le contenu de l’attribut src de l’iframe HTML ci-dessous.
2) Intégrer le tableau de bord avec une taille fixe
<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) Intégrer le tableau de bord avec une largeur dynamique - Redimensionne automatiquement le tableau de bord en fonction de la largeur du document parent
Vous pouvez utiliser le paramètre de style aspect-ratio pour recalculer automatiquement la hauteur en fonction de la largeur.
<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) Autres options d’intégration utiles
Vous pouvez ajouter des modifications de style personnalisées au bloc de style de l’élément iframe, afin de personnaliser l’apparence du cadre. Ces paramètres suivent les consignes HTML/CSS standard. L’exemple ci-dessous ajoute une bordure grise autour du tableau de bord :
<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>Intégrer avec le JavaScript autonome
Le runtime autonome affiche les tableaux de bord directement dans votre page - sans iframe. Vos données sont chargées dans une base de données embarquée dans le navigateur et dessinées sous forme de graphiques entièrement interactifs ; le runtime ne contacte Sprucely.io que pour valider votre jeton d’accès.
Instructions :
1) Créer un jeton d’accès - Dans la section Jetons d’accès de votre profil, créez un jeton d’accès pour l’origine à partir de laquelle vos pages sont servies (par exemple https://www.yourdomain.com). Le runtime vérifie que l’origine de la page d’intégration correspond au jeton avant d’afficher le tableau de bord.
2) Charger le runtime et afficher un tableau de bord - Ajoutez le script du runtime à votre page, connectez la base de données embarquée une seule fois avec sprucely_db, puis affichez chaque tableau de bord avec sprucely_create. La page complète ci-dessous relie également un bouton qui ajoute d’autres lignes :
<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) Ajouter des données à l’exécution - Appelez sprucely_add avec des lignes supplémentaires à tout moment. Chaque tableau de bord qui utilise le jeu de données se rafraîchit automatiquement :
sprucely_add({
name: "Orders",
headers: ["region", "amount", "items"],
types: ["VARCHAR", "FLOAT", "INTEGER"],
entries: [
["East", 310.40, 3],
["West", 129.95, 1]
]
});Référence des fonctions
sprucely_db({ id, host, accessToken })- connecte la base de données embarquée et valide votre jeton d’accès par rapport à l’origine de la page. Affiche une bannière de statut dans l’élément identifié par id. À appeler une seule fois par page, avant de créer des tableaux de bord.sprucely_create({ id, dashboard, data })- affiche un tableau de bord dans l’élément identifié par id. Le paramètre dashboard définit la mise en page et le style ; data fournit le jeu de données avec son nom, ses en-têtes, ses types de colonnes (VARCHAR,INTEGER,FLOATouTIMESTAMP) et ses lignes - voir la référence format de données.sprucely_add(data)- ajoute des lignes au jeu de données dont le nom correspond à un jeu de données déjà chargé, puis rafraîchit tous les tableaux de bord qui l’utilisent.
Intégrer avec React autonome
Si votre site est construit avec React, vous pouvez afficher les tableaux de bord sous forme de composants plutôt que de charger le script manuellement. Les composants utilisent les mêmes jetons d’accès, les mêmes définitions de tableau de bord et le même format de jeu de données que le runtime JavaScript autonome.
Instructions :
1) Créer un jeton d’accès - Comme pour le JavaScript autonome, créez un jeton d’accès pour l’origine de votre site dans la section Jetons d’accès de votre profil.
2) Afficher les composants du tableau de bord - Récupérez le runtime à l’adresse https://www.sprucely.io/cross-origin/sprucely-runtime.min.cjs.js et placez-le dans votre projet. Montez un composant Sprucely.Database par page, et un composant Sprucely.Dashboard par tableau de bord. Les tableaux de bord affichent un indicateur de chargement jusqu’à ce que la base de données ait validé le jeton d’accès, puis s’affichent. L’application complète ci-dessous affiche deux tableaux de bord à partir de jeux de données distincts et ajoute de nouvelles lignes au premier après cinq secondes :
// 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 />);Servir des jetons de courte durée
Le jeton d’accès que vous créez ci-dessus est de longue durée et doit rester un secret côté serveur. Si votre propre backend sert les pages d’intégration - plutôt qu’une page dépourvue de tout backend - vous n’avez pas du tout besoin d’inclure ce jeton de longue durée dans la page - votre backend peut l’échanger, de serveur à serveur, contre un jeton de rendu de courte durée (15 minutes) juste avant de servir chaque page, et seul ce jeton de rendu parvient jamais au navigateur. Un jeton de rendu qu’un visiteur extrait de la page n’est utile que quelques minutes, pas indéfiniment.
Instructions :
1) Échanger votre jeton d’accès contre un jeton de rendu - depuis votre backend, appelez POST https://www.sprucely.io/api/auth/render_token avec votre jeton d’accès comme identifiant Bearer. La réponse contient le nouveau jeton, l’hôte auquel il est lié, ainsi que sa durée de vie en secondes :
// 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) Servir le jeton de rendu au navigateur - utilisez-le exactement comme un jeton d’accès lors de l’appel à sprucely_db ou du montage de Sprucely.Database. Répétez l’échange avant de servir chaque page (ou selon une minuterie si vous mettez en cache la page générée), afin que le navigateur ne reçoive jamais un jeton valide plus de 15 minutes.
Référence des fonctions
POST /api/auth/render_token- échange un jeton d’accès valide, envoyé sous la formeAuthorization: Bearer <token>, contre un jeton de rendu. Retourne{ token, host, expires_in }avecexpires_infixé à 900 secondes. Un jeton de rendu ne peut pas être échangé contre un autre jeton de rendu - seul un jeton d’accès de longue durée peut en demander un.
Paramètres de sécurité
Si votre site applique une Content Security Policy (CSP), les intégrations JavaScript et React autonomes ci-dessus nécessitent d’autoriser quelques sources avant que les tableaux de bord ne se chargent - le runtime charge son script depuis Sprucely.io, ouvre une base de données embarquée reposant sur WebAssembly, et valide votre jeton d’accès auprès de notre API, et chacun de ces éléments nécessite une autorisation CSP explicite. Si votre site n’utilise pas de CSP, vous pouvez ignorer cette section.
Ajoutez les sources suivantes à votre politique existante - il s’agit de directives à fusionner, et non d’une politique complète destinée à remplacer celle que vous avez déjà :
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;Le rôle de chaque directive :
script-src-https://www.sprucely.iocharge le script du runtime.'wasm-unsafe-eval'est nécessaire pour compiler et exécuter la base de données embarquée, qui repose sur WebAssembly.connect-src-https://www.sprucely.ioest contacté pour valider votre jeton d’accès et pour charger les fichiers WebAssembly et worker de la base de données.worker-src- la base de données embarquée exécute ses requêtes sur un thread en arrière-plan, créé à partir d’une URLblob:.
Aucun des éléments ci-dessus ne nécessite 'unsafe-inline' - le runtime Sprucely lui-même n’en a jamais besoin. Si vous conservez vos propres définitions de tableau de bord et de jeu de données dans une balise <script> inline, comme dans l’exemple JavaScript autonome ci-dessus, ou si votre propre page utilise des styles inline, ajoutez 'unsafe-inline' à script-src ou à style-src, ou envisagez d’utiliser des nonces CSP.