2025-09-11

Web Stamp: Internet Collectibles

Today I want to share with the class a silly little thing I made:

|Web Stamp!|

The system is already integrated on this blog website and my 2 other websites! Go try them out!
The other 2 websites:

What even is this?

The idea of |Web Stamp| is essentially stamp collecting for the web, |like going to a carnival where you have to go to different booths to collect stamp for your stamp card for a reward.| There isn't a reward though. The rewards are the friends we make along the way.

To start off, get a stamp card from one of the websites that has Web Stamp. This [site's main page](/) would be a good place to start (shameless self promotion, you're here already anyway). Note that these sites are not connected in anyway. They simply all use this same library. If this ever blows up (which I hope would), it would quite fun to go around niche websites to see if you can get a stamp from them.

That is kind of the reason behind this library though. It's to add some interactive elements for free!

How do I use this?

If you are an ordinary user who are just visiting a website, the video at the top of this blog is a pretty good demo. You can either upload your own stamp card or get a new one using the button. Drag the stamp card and the stamp around to position them as you like. Then click on the stamp to put the image on the card.

If you're a web developer who wants to add this to your website, |*first of all I have to express how happy I would be if you are doing that*.| |When you're done, shoot me a DM so I can go get my stamp :>|

Ahem, anyway, you can follow the README in the [repository](https://codeberg.org/NorthWestWind/web-stamp) (it's on Codeberg!) But for accessibility's sake I'll give some simple instructions here.

Minified JS + CSS

You can add this library directly to your HTML file, like-a-so:

            <html>
                <head>
                    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/web-stamp/dist/style.min.css" />
                </head>
                <body>
                    <button onclick="openUI()">Open Stamp UI</button>
                    <div web-stamp ws-src="link.to/stamp/image" ws-disabled></div>
                    <script src="https://cdn.jsdelivr.net/npm/web-stamp/dist/web-stamp.min.js"></script>
                    <script>
                        function openUI() {
                            document.querySelector("\*[web-stamp]").removeAttribute("ws-disabled");
                        }
                    </script>
                </body>
            </html>
        

You need to put the `ws-disabled` attribute on the `div` to avoid it from opening and blocking everything. Then have a button that removes the attribute to show the stamp UI.

React

If you want to bundle this directly with your React app, you can also do that:

            import { useState } from "react";
            import WebStamp from "web-stamp";
            // Do this if you have css import set up
            // Otherwise, link the stylesheet in the HTML file
            import "web-stamp/dist/style.min.css";

            export default function App() {
                const [opened, setOpened] = useState(false);

                return <>
                    <button onClick={() => setOpened(true)}>Open Stamp UI</button>
                    {opened && <WebStamp src="link.to/stamp/image" onClose={() => setOpened(false)} />}
                </>;

                return 
            }
        

Here's some note for devs who use Preact SSR (which I am one of them). If you are using `preact-render-to-string`\'s `renderToString` function on the server-side, make sure the `WebStamp` component DOES NOT get rendered. For some reason, the React library does not get de-duplicated, and errors happen when 2 React instances exists (well in this case, it's React and Preact).

Technical Details

This part is for those who cares about the implementation.

Fully Client-Side

Flies are not uploaded to any servers. All the composition of the stamp card and the stamp happens right here inside your browser. It's simply a canvas the draws the images on top of each other.

(Hopefully) Small Bundle

React is BIG. I've talked about this in [another post before.](/p/2024/11/04/made-a-brella-counter-learnt) That's why the JS bundle is created using Preact. It has once again brought the size of the file down by 5 times.

That's all!

Happy stamp-collecting!