cherrynet
Free freakin websites at you.chrry.page
everything people send through ur toys lands here first,,, nothing shows on ur site till u publish it
pick a toy or make one
blocked senders can still hit send but nothing reaches u,,, they don't get told. senders are a scrambled id made from their ip, u never see the actual ip
drop a toy on any page
<cherry-toy toy="TOYID"></cherry-toy> <script src="/_cherry/toys.js" defer></script>
it renders right into ur page (no iframe), so ur own css styles it,,, every part has a class
the gallery is its own thing
the form only sends stuff,,, the published stuff lives in a separate cherry-gallery u can put anywhere
<cherry-gallery toy="TOYID" layout="grid" columns="3"></cherry-gallery> layout: grid | masonry | list | strip | polaroid show="text,name,date" limit="12" empty="nothing yet" more="show more" .cg-items .cg-item .cg-img .cg-q .cg-text .cg-a .cg-meta .cg-empty .cg-more --cg-cols --cg-gap --cg-radius --cg-card-bg --cg-card-fg --cg-border --cg-pad
toys are see-through and use ur page's colors,,, the builder makes new ones white,,, change it with --ct-bg and --ct-fg
cherry-toy the whole thing, has kind="doodle|ask|custom" .ct-form the sending part .ct-palette .ct-swatch .ct-picker .ct-tools .ct-tool[data-tool=brush|eraser|fill|line|rect|spray] .ct-action[data-action=undo|clear] .ct-sizes .ct-size .ct-dot .ct-canvas .ct-input .ct-question .ct-caption .ct-name .ct-send .ct-status .ct-list published stuff .ct-item .ct-img .ct-text .ct-field .ct-answer .ct-label .ct-meta .ct-empty [aria-pressed=true] the picked color / tool / size
quick parameters, set them on cherry-toy or anywhere above it
cherry-toy {
--ct-accent: hotpink; /* send button + picked stuff */
--ct-accent-fg: white;
--ct-border: #0003;
--ct-radius: 12px;
--ct-gap: 10px;
--ct-input-bg: white;
--ct-card-bg: #fff8;
}
the default look sits in @layer cherry-toy, so any css u write wins without !important
headless,,, build ur own
add headless and it only shows the published list, or skip the element and talk to the api urself,,, any toy kind takes these, custom toys take anything in fields
<script src="/_cherry/toys.js"></script>
<script>
await cherry.toys.send('TOYID', {
text: 'hi', // up to 2000 chars
name: 'bob', // optional
img: canvas.toDataURL('image/png'), // optional, png, 600KB max
fields: { mood: 'good', score: 9 } // optional, flat, 8KB max
})
const { toy, items } = await cherry.toys.get('TOYID') // only published stuff
</script>
or plain http from the same site
GET /_cherry/toy/TOYID → { toy: { id, kind, name, config }, items: [...] }
POST /_cherry/toy/TOYID ← json like above → { ok: true }
GET /_cherry/toy/TOYID/img/ITEMID.png
the element also fires cherry-sent after a send,,, el.addEventListener('cherry-sent', e => e.detail)
limits: 6 sends per toy per 10 min from one person, 30 across all toys
addresses on shared domains
People can share their own domains with everyone. Grab a name on one and point it at any of your sites.
your own domain
Put one of your sites on a domain you ownnn, like example.com,, Uses CNAME records.
YOU NEED TO OWN THIS DOMAIN FIRST!!! we're not making it for free. Sorry! Though you should register w/ Cloudflare
share a domain with everyone
Give us ur ENTIRE domain so everyone can claim a site at name.yourdomain.com...
tokens
for git, sftp, webdav and the api
copy it now
password is a token from account, username can be anything
git clone https://chrry.page/git/SITE.git cd SITE git add -A && git commit -m "stuff" git push
git remote add cherry https://chrry.page/git/SITE.git
git push cherry main --force
maingoes live on push- has a
buildscript? it gets built first (vite, astro, react...) - output folder:
"cherry": { "out": "dist" }in package.json, or it guesses - git push wins if a file changed in both places
github mirror
on: { push: { branches: [main] } }
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 0 }
- run: git push --force "https://x:${{ secrets.CHERRY_TOKEN }}@chrry.page/git/SITE.git" HEAD:main
easiest: backend button next to ur site in sites
backend/ package.json ← "start" script server.js ← listens on process.env.PORT
require('http').createServer((req, res) => {
res.end(JSON.stringify({ hi: req.url }))
}).listen(process.env.PORT)
- gets
/api/*,,, change it with"cherry": { "prefix": "/x" } /datasticks around- saves go live in a second
backend/stays private- websockets work:
new WebSocket(`wss://${location.host}/api/chat`) - 512MB, 30s per request
cd backend npm install express backend env API_KEY=abc123 backend restart logs
| host | sftp.chrry.page |
| port | 2222 |
sftp -P 2222 you@sftp.chrry.page
ssh
ssh -p 2222 SITE@sftp.chrry.page ssh -p 2222 SITE@sftp.chrry.page "ls -l"
https://chrry.page/dav/
- mac: Finder → Go → Connect to Server
- windows: This PC → Map network drive → connect to a web site
- linux:
davs://chrry.page/dav/
curl -u x:TOKEN -T index.html https://chrry.page/dav/SITE/index.html
GET /api/me GET /api/files?site=SITE GET /api/raw?site=SITE&path=/a.png PUT /api/file?site=SITE&path=/a.html DELETE /api/file?site=SITE&path=/old POST /api/move?site=SITE {"from":"/a","to":"/b"}
curl -H "Authorization: Bearer TOKEN" -T index.html "https://chrry.page/api/file?site=SITE&path=/index.html"