Manta Developers
GitHub
Menu

Snapshot views

Draw a Horn snapshot on the server and hydrate it in the browser with @manta-eu/horns-kit.

What it is

@manta-eu/horns-kit draws a HornSnapshot, the rows a Horn’s views returned, laid out on the Horn’s grid. It fetches nothing itself: whatever built the snapshot already ran the queries as the viewer. There are two ways to use it:

  • In a React tree. Render HornSnapshotView with a snapshot. HornDrawn does this for you, and fetches the snapshot too.
  • As HTML from a server. renderHornEmbed turns a snapshot into markup plus the snapshot as inline JSON, and hydrateHornEmbeds makes it live in the browser without a second request.

Written views and catalog cards need the host’s components, so the server draws a placeholder for them. The browser fills the placeholder in when you pass writtenView and catalogCard to hydrateHornEmbeds, and keeps it otherwise.

Import

import { HornSnapshotView } from "@manta-eu/horns-kit";
import { renderHornEmbed } from "@manta-eu/horns-kit/server";
import { hydrateHornEmbeds } from "@manta-eu/horns-kit/client";

The kit needs react and react-dom 18 or newer.

Example

On the server, with a snapshot in hand:

const html = renderHornEmbed({ snapshot, mode: "embed", embedId: "open-tasks" });

In the browser, once the page has loaded:

hydrateHornEmbeds({
  onRecoverableError: (error, embedId) => console.warn(`Horn ${embedId} re-rendered`, error),
});

hydrateHornEmbeds adopts every embed on the page and is safe to call again after you add more. An embed id is lowercase letters, digits and hyphens, at most 64 characters.

Request

The kit sends no request. The Horns server can draw a whole page for you: post the Horn to /d/<datastore>/horns/render.

POST /d/your-datastore/horns/render?mode=embed
Content-Type: application/json

{ "horn": { "…": "the Horn" }, "variables": { "status": "open" }, "viewIds": ["open-tasks"] }

variables and viewIds are optional. viewIds draws only those views, from 1 to 24 of them. The server fills the /horn.html page among your static assets, which must hold a <!--horn-title--> and a <!--horn-embed--> placeholder.

Response

renderHornEmbed, and the render route inside its page, produce one embed per Horn:

<div data-horn-embed="open-tasks" data-horn-mode="embed" data-horn-theme="light">…the drawn views…</div>
<script type="application/json" data-horn-snapshot="open-tasks">
  { "snapshotVersion": 1, "…": "…" }
</script>

The snapshot carries the Horn’s identity and grid, a views entry per view, the labels and links for every IRI in the rows, the plans behind each view, the current variables, and generatedAt. Each view holds at most 1,000 rows.

After hydration the embed gets data-horn-ready="true". If React had to throw the server’s markup away and draw again, it also gets data-horn-hydration="recovered", which is worth logging.