Develop a component
Edit your project's components on your computer, see every change in the paywall editor, and publish them as new versions.
A component is a Rust crate built with the voidhash-ui library. voidhash-cli dev keeps a copy
of your project's components on your computer, builds them as you edit, and shows each build in
the paywall editor within seconds. voidhash-cli publish turns your changes into new versions your
paywalls can use. This page walks through that loop.
Before you start
You need stable Rust and its WebAssembly target:
rustup target add wasm32-unknown-unknownRun the commands on this page in your app's root, the directory with the voidhash.config.ts that
voidhash-cli init created. They act for the project it names and
for you: sign in first with npx voidhash-cli auth login. A project's secret key cannot run them.
Start the dev loop
npx voidhash-cli devThe first time, dev creates a .voidhash directory and adds it to your .gitignore (creating
the file when there is none). Then it:
- downloads the source of every component of the project. A component that was uploaded as a
built module has no source to edit;
devlists it as not editable; - builds each component and its editor panel;
- serves the builds to the paywall editor, on your computer only, and rebuilds a component each time you save one of its files.
Keep it running while you work, and press Ctrl-C to stop. It listens on port 4319; pass
--port <port> when that port is taken.
The working copy
.voidhash is a Cargo workspace. Open it in your editor so Rust tooling such as rust-analyzer sees
every component:
| Path | Contents |
|---|---|
Cargo.toml | The workspace. It is yours to change once created. |
components/<slug>/ | One component crate: its Cargo.toml, src/lib.rs and any other modules. |
components/<slug>/src/panel.rs | The component's editor panel, when it has one. |
state.json | What the CLI knows of each component. Do not edit it. |
target/ | Build output. |
A component in .voidhash has the id project/<slug>, after its directory's name. Give the same
id in #[component(id = …)] and #[panel(for = …)], as voidhash-cli new does; dev reports a
build whose id does not match.
Create a component
voidhash-cli new creates a component with its editor panel in the working copy:
npx voidhash-cli new badgeIt writes .voidhash/components/badge/ with a working component in src/lib.rs and its panel in
src/panel.rs. A running dev picks it up and builds it at once. Until you publish it, the new
component exists only on your computer: the paywall editor lists it under Local, and only you
see it.
One crate, two modules
The crate builds twice. The default build, its runtime feature, is the component module that
paywalls run in your app. The panel feature builds the editor panel module, which only the
paywall editor loads. Panel code never reaches your app or its download size.
[features]
default = ["runtime"]
runtime = []
panel = ["voidhash-ui/panel"]Both builds share the crate's types, so the component and its panel agree on its props. A component without an editor panel needs neither feature.
See your builds in the paywall editor
Open any paywall of the project in the editor, signed in as the person who runs dev. There is
nothing to link: the editor finds your dev and uses its builds.
- Every instance of a component you serve draws with your latest build, on the canvas and in the right panel, which shows the build's props, traits and editor panel.
- Local builds, at the top of the layers panel, says how your builds stand. Select it to see each component, whether it changed since its last version, and the error and build log of a build that failed. The editor keeps showing a component's last good build until you fix the error.
- Use published versions, in the same place, shows the versions your instances pin instead,
without stopping
dev. Turn it off to see your builds again. - New components you created with
voidhash-cli neware listed under Local when you add a component. You can place them on the canvas to try them out. - A prop that only your build declares is marked Local build only. You can set it, and the value is saved with the paywall, but the version the instance pins ignores it until you publish a version that declares it.
- When
devstops, the editor says it cannot reach it, and within half a minute returns to the published versions.
Your builds are yours alone. Teammates who open the same paywall see the published versions, and your builds never reach your apps.
Chrome may ask whether the site can reach devices on your local network. Allow it: the editor needs
it to reach dev on your computer. If the editor reports a version of dev it does not support,
update the CLI or reload the editor, whichever is older.
Changes from the Voidhash agent and teammates
The Voidhash agent can edit a component in the editor's Code mode, and a teammate can publish a
new version while you work. dev checks for new versions every few seconds and merges them into
your working copy:
- Changes to parts of a file you did not change merge quietly.
devsays which files it merged. - When you and the new version changed the same lines,
devwrites both, between conflict markers (<<<<<<< local,=======,>>>>>>> v5), and marks the component as conflicted. Keep what you want, remove the markers, and save. Until then, the component cannot be published.
Publish your changes
voidhash-cli publish compares your working copy with the project and lists each new or changed
component with the files that changed:
npx voidhash-cli publishChoose the components to publish. Conflicted components are listed, but you can choose them only once you resolve their conflicts. Each one you choose becomes a new version of the project's component: Voidhash builds it from your source, checks it, and the command waits and reports the result of every build, with its log when one fails.
To publish without the prompt, for example from a script, name the components or take them all:
npx voidhash-cli publish --component badge --yes
npx voidhash-cli publish --all --yesPublishing a paywall that uses your builds
A new component version does not change placed instances: each instance keeps the version it pins. So that a paywall never goes live with something other than what you saw, the editor refuses to build it while:
- an instance of a component exists only on your computer, or shows a build with changes you have
not published: run
voidhash-cli publish; - an instance pins an older version than the one you published or based your work on: choose Update N instances to vX in the dialog. It moves those instances to the new version in one step, which you can undo, keeping the props the new version still declares.
The dialog lists every component that stops the paywall from being built, with the fix for each. Once nothing stops it, build and deploy the paywall as usual.
Test
Unit tests run with cargo test in a component's directory. voidhash_ui::testing mounts a
component, presses its buttons and records what it asks the paywall to do.
voidhash_ui::panel::testing does the same for a panel. See
Test a panel.
voidhash-cli test runs the checks publishing runs, on your machine:
npx voidhash-cli test badgeIt builds the component, checks the panel module, then runs the component conformance suite. The
suite needs the conformance checker on your PATH, or its location in VOIDHASH_CONFORMANCE.
Without it, the command reports that the suite did not run and exits with an error. Pass a crate
directory instead of a component's name to test a crate outside .voidhash; the command writes
its modules to target/voidhash.
Publishing runs the same checks on the server. A version that fails them is kept, so the
Components page and voidhash-cli registry list can show you which checks failed, but it
cannot be inserted into a paywall or released. A self-hosted server without a component build
service skips the conformance suite and marks each version conformance-not-run.
To test modules you built some other way, pass the component module. The panel module is
panel.wasm next to it, or the file you pass with --panel.
A typical loop
npx voidhash-cli dev # keep running while you edit
npx voidhash-cli new countdown # in another terminal, when you need a new component
cargo test --manifest-path .voidhash/Cargo.toml
npx voidhash-cli publishThen update the instances when the editor asks, and build and deploy the paywall. To share a component with every project of your organization, publish one of its versions to your organization. See Publishing.