appreciation buttons for your blog, digital garden, portfolio… no account required. no user tracking
<script src="https://cdn.jsdelivr.net/gh/welpo/iine@main/iine.mini.js"></script><button class="iine-button" aria-hidden="true"></button>that's it! your button will automatically display a heart icon and show the current count
Tip
if you use a content security policy (CSP), you'll need to allow scripts from cdn.jsdelivr.net and connections to *.supabase.co
- no ips, timestamps, or tracking data processed/stored
- pure vanilla javascript, ~3KB minified
- built-in icons (heart, thumbs_up, upvote) + custom emoji
- accessible: semantic html, aria attributes, keyboard navigation
- free (at least until i reach over 100,000 websites; then i may need to ask for donations)
- rate limiting and input validation
- customisable
- self-hostable
- agpl licensed
see the built in svgs @ iine.to or use any emoji:
<!-- default is 'heart' -->
<button class="iine-button" data-icon="heart" aria-hidden="true"></button>
<!-- other options: thumbs_up & upvote -->
<!-- any emoji -->
<button class="iine-button" data-icon="💯" aria-hidden="true"></button>to add multiple buttons on the same page:
<!-- use custom slug -->
<button class="iine-button" data-slug="/custom-page" aria-hidden="true"></button>buttons without styling can look ugly. iine does not inject any css, so you'll have to add your own
here's a good starting point:
.iine-button {
display: inline-flex;
align-items: center;
gap: 5px;
margin: 0;
padding: 0;
font-size: inherit;
line-height: inherit;
cursor: pointer;
border: none;
background: transparent;
color: inherit;
.icon {
display: inline-flex;
align-items: center;
}
&:focus {
outline: 2px solid currentColor;
outline-offset: 2px;
}
}available css classes:
.iine-button— main button element.iine-button.clicked— added after user clicks. use it to style clicked state or to add animations.icon— icon container (svg or emoji).counter— number display
iine buttons are built to be accessible, including keyboard navigation, screen reader support, and focus management.
for screen readers, iine automatically generates aria-labels based on the icon and button state. you can set custom labels using the aria-label attribute:
<button class="iine-button" aria-label="Love this post"></button>you can run iine on your own Supabase instance/PostgreSQL setup. see the self-hosting guide
- client clicks button → javascript sends request to Supabase
- server validates → checks rate limits, domain, and input
- counter increments → simple integer increment
- display updates → new count shows immediately (optimistic update; reverts if server fails)
no user identification, no behavioural tracking, no analytics. just counters that go up
something not working? have an idea? let me know!
- questions or ideas → start a discussion
- found a bug? → report it here
- feature request? → let me know
iine is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the license, or (at your option) any later version