Garlic

Protect your website's text from being scraped by no-JS bots.

View source →

Playground

Type something, pick a cipher, and see exactly what ships to a bot vs. what a human reads.

🧛 What a scraper sees (the shipped HTML)

        
🙂 What a human sees (after garlic decodes)

        

A real protected article

Everything below was shipped to you as base64.

VGhlIHRleHQgb24gdGhpcyBwYWdlIHdhcyBwcm90ZWN0ZWQgYnkgR2FybGljX3l1bW15X2dhcmxpY18yMDI2

RXZlcnkgc2VudGVuY2UgaW4gdGhpcyBhcnRpY2xlIHdhcyBzaGlwcGVkIHRvIHlvdXIgYnJvd3NlciBhcyBiYXNlNjQgZ2liYmVyaXNoLiBZb3UgY2FuIHJlYWQgaXQgYmVjYXVzZSB5b3VyIGJyb3dzZXIgcmFuIGEgdGlueSBzY3JpcHQgdGhhdCBkZWNvZGVkIGl0IG9uIGxvYWQuX3l1bW15X2dhcmxpY18yMDI2

QSBzY3JhcGVyIHRoYXQgb25seSByZWFkcyB0aGUgcmF3IEhUTUwgcmVzcG9uc2Ug4oCUIHdnZXQsIGN1cmwsIG1vc3QgY3Jhd2xlcnMsIGFuZCBhIGxvdCBvZiBuby1KUyBkYXRhLWNvbGxlY3Rpb24gYm90cyDigJQgbmV2ZXIgc2VlcyB0aGVzZSB3b3Jkcy4gVGhleSBzZWUgZW5jb2RlZCBibG9icyBpbnN0ZWFkLl95dW1teV9nYXJsaWNfMjAyNg==

VHJ5IGl0IHlvdXJzZWxmX3l1bW15X2dhcmxpY18yMDI2

UnVuICB3Z2V0IGh0dHBzOi8vYW5kcmVhaXNhYmVsbW9udGFuYS5naXRodWIuaW8vZ2FybGljLyAgYW5kIG9wZW4gdGhlIGRvd25sb2FkZWQgaW5kZXguaHRtbC4gVGhlIGFydGljbGUgdGV4dCBpcyB1bnJlYWRhYmxlLiBOb3cgbG9vayBhdCBpdCBoZXJlLCBpbiBhIGJyb3dzZXIsIGFuZCBpdCByZWFkcyBwZXJmZWN0bHkuX3l1bW15X2dhcmxpY18yMDI2

QUkgbmVlZHMgZGF0YSwgYW5kIHlvdXIgd2Vic2l0ZSBtaWdodCBlbmQgdXAgaW4gYSB0cmFpbmluZyBzZXQuIEdhcmxpYyByYWlzZXMgdGhlIGNvc3Qgb2Ygc2NyYXBpbmcgeW91IHdpdGhvdXQgYnJlYWtpbmcgdGhlIGV4cGVyaWVuY2UgZm9yIHJlYWwgcmVhZGVycy5feXVtbXlfZ2FybGljXzIwMjY=

Use it

<!-- 1. encode your text at build time (Node) -->
const Garlic = require("garlic");
const token = Garlic.encode("Hello readers", { cipher: "b64", salt: "pepper" });
// ship: <span data-garlic="b64">${token}</span>

<!-- 2. decode in the browser -->
<script src="garlic.js"></script>
<script>Garlic.peal({ salt: "pepper" });</script>

Or protect a live DOM subtree directly: Garlic.protect(document.querySelector("article")), then Garlic.reveal() on the client.