nicailab.com is NicAI Lab, the share space for what NicAI builds. The homepage says it in 1 line: "Where NicAI & I put the things we build, so I can share them with a link."
NicAI produces a lot of HTML: demo pages, one-pagers, dashboards, small tools. A file on my disk helps nobody else. nicailab.com turns any of them into a link in 1 command.
| What | A static site for pages, demos and files that NicAI builds and I want to share |
| Started | 23rd September 2026 |
| Default | Unlisted: a page only opens for people who have its link |
| Public | A page can also get a card on the homepage, by choice |
| Tool | 1 Python script, publish_nicai.py, in the shared tools (see NicAI shared tools ) |
Why it exists
Some of what NicAI builds is for work, some is me playing. Both need a place to live that isn't a file attachment and isn't a public index.
- A link beats an attachment. A page with a video, a live demo or a small app doesn't survive email. A link does, and I can update what's behind it.
- Most things aren't for everyone. A prototype for 1 person, a page in progress, an experiment. I want to share it without publishing it.
- The link must stay stable. If I fix a typo after sending the link, the same link should show the fix.
How it works
For business people
Every project gets an address made of 2 parts: a readable name, and a short random code after it. The name tells you what it is. The code is what makes the link work. Without the right code, the site sends you back to the homepage, so nobody can guess their way to a page, or even confirm that it exists.
When I update a project, the code stays the same, so the link I sent last week shows this week's version. If a link travels further than I wanted, I change the code: the old link stops working, and I send the new one to the people who should have it.
Project pages tell search engines not to index them. Only the homepage is meant to be found.
For technical people
The URL shape is /p/<slug>/<key>/:
<slug>is the project name, lowercase letters, digits and hyphens.<key>is 8 characters drawn from a 31-character alphabet with the look-alike characters removed. That gives about 850 billion combinations.
The script keeps a local JSON registry: 1 entry per project with its key, URL, source path, dates and public flag. It reuses the key on every republish.
The server side is 2 .htaccess files, nothing else:
- In
/p/, any path with 2 segments or more is served. Anything shallower redirects to the homepage. Directory listings are off. - The same file sends
X-Robots-Tag: noindex, nofollowon every project page. - The root file forces HTTPS on the bare domain and serves a custom 404 page for both 404 and 403.
The commands:
| Command | What it does |
|---|---|
publish <file or dir> |
Publishes a page, a folder or any single file. Reuses the key if the project exists |
publish ... --public |
Also adds a card on the homepage, with an optional title and 1-line blurb |
show / hide |
Puts a project's card on the homepage or takes it off. The link keeps working |
home |
Rebuilds the homepage from the registry and pushes it. Never touches projects |
list |
Shows every project with its date and public or unlisted state |
rotate |
Gives a project a new key. The old link dies |
unpublish |
Removes the project from the server and the registry |
Every publish also has a --dry-run.
What publish does to a page
An HTML page on my disk often points at images and styles elsewhere on the disk. A copied page would break. So the script bundles it first:
- It copies every file the page references by absolute path into an
assets/folder and rewrites the references. - It copies relative references next to the page as they are, and skips anything that climbs out of the folder with
... - It warns about referenced files it can't find.
- It adds the NicAI Lab tab icon unless the page names its own.
A folder is copied as is, minus .git, .env, caches and macOS clutter. A folder without an index.html gets a warning, because its bare link would show the 404 page.
Honest limits
- The key is a gate, not a lock. The script's own docstring says it: "not authentication, just an unguessable segment". Anyone who has the link can open it and forward it. So nothing sensitive belongs on nicailab.com.
rotateis the only remedy once a link leaks. - Static only. No server code, no database, no login. A page that needs a backend calls someone else's.
- It's new. On the day I write this, 1 project is on the site, unlisted, and the homepage has no public cards yet.
nicailab.com and my work site
For work, I already had the same idea on a Kaltura-branded domain: publish_kc.py publishes decks, avatar demos and one-pagers there, in 3 sections, with the same slug-and-key URLs and the same reuse, rotate and unpublish commands. It also keeps an index page of my live avatar demos.
nicailab.com is the general version. It borrows the transport and slug rules from the work script, but it takes any page, folder or file, and it adds the public homepage cards. The rough split:
- Kaltura-branded decks, demos and one-pagers go to the work domain.
- Anything else NicAI builds, for work or for fun, can go to nicailab.com, under my name.
What's next
- Put the first public projects on the homepage, with a title and a 1-line blurb each.
- Link public projects from the notes in this section, so a note about a tool can show the tool.
Related notes
- What NicAI is: What is NicAI
- The shared tools, including both publish scripts: NicAI shared tools
- How this notebook is built and published: The notes pipeline