Mighil

MyStatus: brew your own status site using Cloudflare Workers

MyStatus landing page screenshot

Demo (main site): mystatus.mighil.com
Demo (embed): mystatus-demo

I haven't been on my website/blog for a while. I am back in Kerala and taking it real slow, mostly dealing with some commissioned work. We also released a few animations (I did the music), and it has been a fun journey.

This project is based on the MyGB Cloudflare Worker flow. Use the original setup guide here. A recent email exchange with Sylvia inspired this release. Sylvia made the initial draft for her own needs, and I cleaned up the code, added more features, and decided to share MyStatus with whoever is reading my blog.

What this worker.js does

Features

What to do

  1. Follow the MyGB guide step by step (create D1, create Worker, bind DB, set secrets/vars, deploy).
  2. When the guide asks for the Worker code, replace the script with this repo's worker.js.
  3. Deploy and open your Worker URL.
  4. Go to /login and sign in with your configured admin password.

Important note about database setup

Ignore the manual DB initialization section from the previous tutorial for this version. Just create the D1 database and bind it as DB. This Worker initializes the required tables automatically on first load.

Embedded stream (/client.js): pagination

The widget loads the first page with GET /api/entries (up to 10 entries, newest first). If the API returns nextCursor, a Load more button appears; each click fetches GET /api/entries?cursor=<id> and appends rows until there are no more pages (same contract as the home page Load More).

Styling the embedded stream (/client.js)

The embed injects markup under your [data-gb] container. Add CSS on the site that embeds the widget.

Class Role
.gb-widget Root of the widget (default: font-family / color inherit)
.gb-entries Wraps the list
.gb-entries-list List container (entries are appended here)
.gb-entry One status block (<article>)
.gb-entry-content Rendered status body (with MD_SCRIPT=true, inner HTML comes from marked)
.gb-entry-meta Footer row for each entry
.gb-entry-date Timestamp
.gb-loading Shown while fetching
.gb-no-entries Shown when there are no posts
.gb-error Shown when the API request fails
.gb-load-more-wrap Wrapper for the Load more control (hidden when there is no next page)
.gb-load-more-btn Load more button

Example CSS snippet:

<style>
.gb-entry {
  border: 1px solid color-mix(in srgb,var(--text-color)10%,transparent);
  padding: 0 20px 20px;
  border-radius: 10px;
  margin-bottom: 20px;
}
.gb-entry-meta {
  font-family: var(--font-secondary);
  font-size: .9em;
  color: color-mix(in srgb,var(--text-color) 80%,transparent);
  font-style: normal;
}
</style>

Experimental: R2 media (optional)

  1. Create an R2 bucket and bind it to the Worker with binding name MEDIA.
  2. In the admin nav, open Media (/admin/media): upload files, copy the public URL, or delete objects from the bucket.
  3. Files are served at /media/<filename> (one URL path segment; names are normalized to letters, digits, ., _, and -).
  4. In statuses, use same-origin paths such as ![](/media/photo.png) or [label](/media/doc.pdf). The built-in renderer allows these /media/... paths alongside http(s): URLs. With MD_SCRIPT=true, you can also use full https:// URLs to your site.

Upload limits (experimental): up to 15 MB per file; types allowed include common raster images (not SVG), video/mp4, video/webm, audio/mpeg / mp3 / wav / webm, and application/pdf.

Credits

This direction was Sylvia's idea, and she cleaned it up for her use case (kudos to her). I reviewed it and am now releasing a version with extended features. Sylvia also added markdown support for statuses, meaning you can write status posts directly in Markdown.

New variables in this version

  1. ALLOWED_ORIGINS

Set it as a comma-separated list of full origins allowed for cross-origin access to public endpoints.

Example:

ALLOWED_ORIGINS=https://myblog.com,https://www.myblog.com,http://localhost:3000

  1. MD_SCRIPT

MD_SCRIPT controls the markdown rendering engine.

Configure MyStatus however you like. Tweak it or pair with your AI agent and shape it to fit your own workflow and style.

Tagged in cloudflare, tech