Signature counter for a European Citizens' Initiative
What is a European Citizens' Initiative?
A European Citizens' Initiative (ECI) is an official EU petition. It is the only element of direct democracy at the European level. Citizens can ask the European Commission to propose a new law. If one million citizens across the EU (as well as a certain minimum in at least 7 member states) sign the initiative, the European Commission must consider taking action on the issue.
Why build your own landing page?
The European Commission provides a so-called Central Online Collection System to collect online signatures for European Citizens' Initiatives.
However, the Central Online Collection System's landing page for an ECI doesn't exactly follow best practices for campaigning landing pages, which is one reason it is unappealing to many campaigning organisations.
Among the various confusing things about the official ECI pages is that there are 2 separate pages for every ECI during signature collection:
Central Online Collection System | European Commission's register page |
---|---|
Counts online signatures only | Counts online and offline signatures |
updates instantly | updates once per day |
URL uses initiative ID | URL uses registration number |
That's why campaigners might want to build their own landing page on a website they control:
- Use a clear messaging hierarchy appropriate for the target audience
- Make it easy to subscribe to updates about the campaign and/or your organization
- Display strong social proof
Build a signature counter using the European Commission's API
For social proof, you usually want to prominently show a signature counter on your landing page. Thankfully, the European Commision has a public (though not publicly documented) API that allows you to get the number of online signatures. Here's how I built a signature counter. I originally built it for the Tax the Rich ECI, but I'm using the excellent My Voice, My Choice (which you should sign if you haven't already) as an example here:
More than 900.000 people have signed. Help us reach 1 million!
HTML
Set up a text and a progress bar. Provide a fallback in case Javascript is disabled or something doesn't load properly. You can update this manually from time to time.
<span class="signature-number">More than 900.000</span> people have signed. Help us reach 1 million!
<progress class="signature-progress" value="900000" max="1000000"></progress>
CSS
Some styles, you can tweak this according to your tastes or brand.
:root {
--progress-color: #090;
--progress-bg-color: #eee;
}
.signature-progress[value] {
width: 100%;
height: 40px;
appearance: none;
border: 3px solid var(--progress-color);
border-radius: 5px;
color: var(--progress-color);
background-color: var(--progress-bg-color);
}
.signature-progress[value]::-webkit-progress-bar {
background-color: var(--progress-bg-color);
border-radius: 5px;
}
.signature-progress[value]::-webkit-progress-value {
background-color: var(--progress-color);
border-radius: 0px;
}
.signature-progress[value]::-moz-progress-bar {
background-color: var(--progress-color);
border-radius: 0px;
}
Javascript
We load the live signature count from the API, add offline signatures and update the counter and progress bar with the total number.
async function eciProgress() {
const offlineSignatureCount = 28261; // number of offline signatures
const locale = "de-DE"; // the locale according to which you want your numbers formatted
const eciID = "044"; // ID of your ECI. It's the number in the URL of the Central Online Collection System page such as https://eci.ec.europa.eu/044/public/
const signatureProgress = document.querySelector(".signature-progress");
const url = "https://eci.ec.europa.eu/" + eciID + "/public/api/report/progression"
const response = await fetch(url);
const progress = await response.json();
const signatureCount = progress.signatureCount + offlineSignatureCount;
if (typeof signatureCount === "number" && signatureCount > 0) {
signatureProgress.setAttribute("value", signatureCount);
let localizedSignatureCount = new Intl.NumberFormat(locale).format(signatureCount);
document.querySelectorAll(".signature-number").forEach((el) => {
el.textContent = localizedSignatureCount;
});
}
}
eciProgress();
Caveats and limitations
- If you want to count offline signatures, you have to add them manually. The current number of submitted offline signatures is not officially published anywhere and cannot be automatically retrieved, so you have to update it manually in the script. Officially registered organizers of the ECI can see the number of paper signatures they have reported in their account. Otherwise you can only estimate the number by closely monitoring the daily total numbers at the European Commission's register page and comparing them with the online numbers of the Central Online Collection System.
- The Commission's API can presumably handle a lot of hits, but be considerate – you don't really need to refresh the counter every second while the user is reading the page. Checking the API once on page load as in the example should be sufficient. We don't want the Central Online Collection System to go down or the API to get restricted.