vocdoni-app
September 16, 2026 · View on GitHub
Our main aim is a trustless voting system where anyone can speak their voice and where everything is auditable.
We are engineering building blocks for a permissionless, private and censorship resistant democracy.
Explore the developer portal »
More About Us
Vocdoni Website | Web Application | Blockchain Explorer | MIT Law Publication | Contact UsKey Repositories
Vocdoni App | Vocdoni Node | Vocdoni Integrator SDKvocdoni-app
Vocdoni App is a React application that uses the Vocdoni Integrator SDK (including its react-components and react-providers packages) to provide a user interface for the Vocdoni voting protocol. It is built with Vite and Vike, and is deployed at https://app.vocdoni.io/.
Table of Contents
Getting Started
Rendering Architecture
The app now uses a mixed rendering model:
- Vike handles SSR for the public pages:
/organization/:address/processes/:id
- The rest of the application remains client-rendered and is served through the SPA catch-all page:
/- auth and login routes
- dashboard and backoffice routes
- all other existing SPA routes
This keeps the migration incremental:
- public organization and process pages get server-rendered HTML and SEO metadata
- the existing React Router application remains the source of truth for the rest of the app
- Vike sits on top of the current Vite app instead of replacing the SPA router entirely
Relevant entry points:
src/pages/organization/@address/for the SSR organization pagesrc/pages/processes/@id/for the SSR process pagesrc/pages/home-process/for the SSR single-process homepage (only whenHOME_PROCESS_IDis set)src/pages/@catchAll/for the SPA catch-all pagesrc/router/for the client-side React Router application
Environment variables
You can create a .env.local file to set your custom environment variables
there, here's a list of variables you can use:
VOCDONI_ENVIRONMENT: the vocdoni environment to be used, eitherdevorprod(defaults todev).BASE_URLis used to specify the public base page during build.BUILD_PATHSpecifies the destination of built files.CUSTOM_ORGANIZATION_DOMAINSA JSON.stringified object of custom domains mapped to organization ids, to replace the homepage with their profile page.HOME_PROCESS_IDa single process id that turns the app root into that process' voting page — the same view served at/<lang>/processes/<id>, server-rendered by Vike. Both/and every localized root (/en,/es, …) render it, and its<title>, description, canonical URL,hreflangalternates and structured data all describe that process, with the roots as its canonical URLs. Unset, the root keeps behaving exactly as before. It is read at runtime, so a single build/image can be pointed at a process withdocker run -e HOME_PROCESS_ID=....PRIMARY_COLORthe accent color of the app as a#rgbor#rrggbbhex value (e.g.#1a73e8). A full palette (tints, shades, text and focus-ring colors) is generated from it and applied to buttons, form controls, tabs and highlights in both color modes. Filled surfaces use the exact color wherever it reads at 3:1 against the page background and the closest readable shade otherwise (a very dark color in dark mode, a very pale one in light mode). Unset, the app keeps its stock black accent. It is read at runtime, so a single build/image can be recolored withdocker run -e PRIMARY_COLOR=....SHOW_ORG_LOGOset it totrueto brand the header of process pages with the logo of the organization that created the process, instead of the Vocdoni logo. It applies to the public voting page (/<lang>/processes/<id>), its summary (/<lang>/processes/<id>/summary) and theHOME_PROCESS_IDroot, which render that logo server-side — there is no client-side swap. Pages with no process behind them (the dashboard, auth, pricing…) keep the Vocdoni logo, and so does an organization that has no logo set or whose logo URL fails to load. Only the header is affected: the footer logo is always Vocdoni. It is read at runtime, so a single build/image can be branded withdocker run -e SHOW_ORG_LOGO=true.
You can also start the app by prefixing these vars instead of defining your
custom .env file:
VOCDONI_ENVIRONMENT=dev pnpm start
# or an example using many of them...
BUILD_PATH=build/dev BASE_URL=/vocdoni-app/dev VOCDONI_ENVIRONMENT=dev pnpm build
Custom domain names
The custom domain names environment variable allows to map custom domains to organization ids, so that the homepage rendered will be the mapped organization profile.
CUSTOM_ORGANIZATION_DOMAINS='{"deadcorp.com":"0x000000000000000000000000000000000000dead"}' pnpm build
With the example above, accessing the app via the deadcorp.com domain would render the profile of the organization
with id 0x000000000000000000000000000000000000dead as the homepage of the app.
SharedCensus configuration
The SharedCensus page uses the following env vars to drive its UI:
PROCESS_IDS: comma-separated election IDs to display.SHARED_CENSUS_ALWAYS_VISIBLE_TEXT: JSON object mapping language codes to markdown (e.g.{"en":"...", "es":"..."}) rendered via the read-only Editor. Must include the default language (first entry fromLANGUAGES, defaulten), otherwise the build fails. Always shown at the top of the SharedCensus page.SHARED_CENSUS_DISCONNECTED_TEXT: JSON object mapping language codes to markdown, shown only when the user is not connected/admin. Must include the default language if set, or the build fails.SHARED_CENSUS_CONNECTED_TEXT: JSON object mapping language codes to markdown, shown only when the user is connected or an admin. Must include the default language if set, or the build fails.STREAM_URL: singlehttp(s)URL for an embeddable stream (e.g. YouTube). Validated at build time. When the session starts (connected or admin), it renders in a 16:9 player floated right so text flows around it. If only the stream is provided, it renders alone.
When neither pretext nor stream is configured, no top content is shown. When only pretext exists, it remains single-column. After sign-in, the stream (if set) appears as the second column, displacing the pretext to the left.
Available Scripts
In the project directory, you can run:
pnpm start
Runs the app in development mode with Vike + Vite.
Open
http://localhost:5173 to view it in the browser (note
the port may change if already used).
pnpm build
Builds the app for production to the dist folder.
The output now includes both the client bundle and the Vike SSR server bundle:
dist/clientfor browser assetsdist/serverfor the SSR entry and page server bundles
pnpm translations
Extracts all i18n strings from the code and puts them in the i18n/locales json
files. The best way to work with translations is:
Branching and deploys
Three branches are linked to deploys:
linked to SaaS api-dev and vochain dev.
linked to SaaS api-stg and vochain LTS.
linked to SaaS api-lts and vochain LTS.
Pushes and pull requests to develop and stage are validated by the GitHub
Actions test workflow, which runs lint, test, and env-specific production
builds.
The common flow to follow when deploying to main is passing through all the
other stages:
branch from develop => merge to develop => merge to stage => merge to main
The only exception should be when fixing specific versions to a deployment, in such case, a hotfix should be created from the desired branch to be updated:
branch from stage (i.e. h/sdk-0.4.1) => PR to stage
branch from main (i.e. h/sdk-0.5.0) => PR to main
Contributing
While we welcome contributions from the community, we do not track all of our issues on Github and we may not have the resources to onboard developers and review complex pull requests. That being said, there are multiple ways you can get involved with the project.
Please review our development guidelines.
Contributions and pull requests
To avoid unnecessary review overhead, pull requests that only fix typos, whitespace, punctuation, or other minor changes without functional impact or clear added value will not be accepted. If you want to correct such issues, please open an issue first. If the change is considered necessary, it may be accepted as a dedicated pull request that groups those corrections together. Accepted contributions must provide a clear benefit, whether through functional improvements, meaningful documentation updates, or the implementation of a feature or bug fix. Minor changes should be made with consideration and strong justification to avoid unnecessary distractions for reviewers.
License 
This repository is licensed under the Business Source License 1.1.
Copyright © 2025 Vocdoni.