Skip to content

Copy the component source into your repo

Two ways to use the components. Import them from @sparkletree/react and we own the markup. Or copy the source into your project and you own it.

Terminal window
npx @sparkletree/cli add hero cta

Pick one or the other. Doing both leaves you with two components called Hero and a confusing diff.

Files are written under components/sparkletree/ by default, and dependencies are resolved for you: asking for hero also writes provider if you do not have it.

ComponentWhat it is
providerThe SparkletreeProvider wrapper, reading your environment variables.
heroStreaming hero: greeting, headline, body, artwork.
ctaStreaming call-to-action with a stable hit area.
copy-cardA card for copy you already have.
product-cardA product card with image, name, description and price.

The default class names assume Tailwind CSS. Swap them for anything; the files are yours.

sparkletree add <component...> [options]
sparkletree upgrade [options]
sparkletree list
sparkletree help
Option
--dir <path>Where files are written. Default components.
--cwd <path>Project root. Default: the current directory.
--forceOverwrite files that already exist.
--dry-runPrint what would happen and write nothing.

Existing files are never overwritten without --force; they are listed as skipped and the command still exits 0, so re-running it in CI is safe. The tool prints the packages to install and does not run your package manager.

Node 18 or later, ESM only. --version and --help work from any position.

Port copies to the current template wiring

Section titled “Port copies to the current template wiring”

Copies drift as the templates improve, and they are your files — nothing can patch them at runtime. One command ports what your copies are missing:

Terminal window
npx @sparkletree/cli upgrade

The upgrade is version-aware, one generation at a time, and decides what a copy is missing by its content — never by guessing which release wrote it:

  • 0.4.0 changed the hold from blanking to reserving: a holding field is invisible but still occupies its exact space. A 0.3.0 copy without this wiring collapses during the hold and shifts the page when copy lands.
  • 0.6.1 moved URL vetting to the one safeActionUrl in @sparkletree/core. A copy carrying the old inline helper still works, but it is frozen: a future fix to the vetting rules would never reach it. The upgrade deletes the local copy and imports the shared one.

A 0.3.0 copy gets both, in order; a 0.4.0 or 0.5.0 copy gets only the second. It takes no component names; it upgrades every copied hero and cta it finds under --dir, with the same --cwd, --dir and --dry-run as add.

How it stays safe in your repository:

  • Exact matches, all-or-nothing per file. Every hunk of every needed generation must match exactly. One miss means you edited the file where the upgrade has to land, so nothing is written and the command names which parts did not match, for you to port by hand.
  • Your styling survives. The hunks avoid the Tailwind class names the templates invite you to change.
  • Idempotent. A generation whose wiring is already in the file is skipped; a copy missing none is reported up to date and never touched.
  • It checks your install first. The rewritten source must compile against your installed @sparkletree/react and @sparkletree/core. Against an older install the run names the version it needs, reports what it would write, and writes nothing. Update the packages, then re-run.

Diverged files are a report, not a failure: the command exits 0 either way, so it is safe in CI.

The copied components contain layout and nothing else: no endpoints, no event names, no version numbers, no timing values. Everything that talks to SparkleTree stays in @sparkletree/core and @sparkletree/react, which the copies import from.

So a change to how SparkleTree delivers copy is a version bump for you, not a migration.

What the copies do own is layout, which is why the one thing 0.4.0 asked of them was a layout change, and why it ships as a codemod rather than a guide.

Edit the copied files freely. Two things to preserve:

  • Attach the ref that useIsland returns to the element that has to be visible, or the block reports no impressions.
  • Pass fields to StreamText, not field.text, or adapted copy renders without its provenance stamp and paced entrance.