Apologies if it's a bit rough -- paper cut on my index finger, but I wanted to share this anyway. Sign the MyGB guestbook here.

[MyGB](https://github.com/verfasor/MyGB) is a beefed-up version of the guestbook script originally mentioned in "[brewing a guestbook using cloudflare workers](https://mgx.bearblog.dev/brewing-a-guestbook-using-cloudflare-workers/)". This worker.js lets you host your own guestbook for free using Cloudflare's global network. It's designed to be lightweight and easy to embed anywhere. There is no middle man, no multi tenancy -- you own the code and you own the database.
## How it works
* **The Engine (Cloudflare Workers):** The code runs on Cloudflare's edge servers. This makes your guestbook load instantly for visitors, no matter where they are.
* **The Memory (Cloudflare D1):** Your data (messages, settings) is stored in D1, a SQL database that lives on the edge.
* **The Look (HTML/CSS):** The user interface is generated directly by the worker. No complex build steps or frontend frameworks like React or Vue are needed..just fast, raw HTML and CSS.
The entire application lives in a single file [worker.js](https://github.com/verfasor/MyGB/blob/main/worker.js), making it incredibly easy to manage and deploy.
## Philosophy
**AI-Ready**: The code is extensively commented and structured to be easily understood. You can drop `worker.js` into your favorite AI agent or coding assistant to add new features, change the design, or customize it to your liking.
**Open Source (AGPL v3)**: The source code is licensed under **GNU AGPL v3**. Please ensure that any "good" derivatives or improvements you make remain open source so others can benefit from them.
## Your project, your rules
Consider MyGB as a primer or a starting foundation. You are encouraged to optimize the code, improve the database schema, or rewrite entire sections to fit your specific needs. The goal is to give you a solid, working guestbook that you can truly make your own.
## Deployment guide (no coding required)
You can deploy this guestbook directly from the Cloudflare Dashboard without touching a command line. If you are a developer, you may refer to [getting-started.md](https://github.com/verfasor/MyGB/blob/main/getting-started.md) on GitHub repo.
### Prerequisites
- A Cloudflare account (Free tier is fine)
### Step 1: create a D1 database

1. Log in to your Cloudflare Dashboard.
2. Go to **Storage & databases** > **D1 SQL database**.
3. Click **Create database**.
4. Name it `guestbook-db` (or anything you like).
5. Click **Create**.
### Step 2: create the Worker
1. Go to **Compute & AI** > **Workers & Pages** > **Overview**.
2. Click **Create application**.

3. Choose **"Start with Hello World!"**
4. Name your worker (e.g., `my-guestbook`).

6. Click **Deploy** (this creates a default Hello World worker and redirects you to the Worker overview page).
7. Click **Edit code**.
### Step 3: add the code
1. In the online code editor, you'll see a `worker.js` file.
2. Delete all the existing code in that file.
3. Copy the entire content of [worker.js](https://github.com/verfasor/MyGB/blob/main/worker.js) from the repository and paste it into the editor.
4. Deploy it.

> Ignore the `{"success":false,"error":"Cannot read properties of undefined (reading 'prepare')"}` error -- we will bind Database in the next step.
### Step 4: bind the database

1. Go back to your Worker's overview page (click the back arrow or navigate via dashboard).
2. Click the **Bindings** tab.
3. Click **Add binding**.
4. Choose **D1 Database**.
5. Variable name: `DB` (Must be exactly `DB`).
6. Database: Select the database you created in Step 1.
7. Cloudflare will automatically redeploy.
### Step 5: configure environment variables

1. In **Settings** tab of Worker, look for the **Variables and Secrets** section.
2. Click **Add**.
3. Add the following variables:
| Variable Name | Value | Type | Note |
ADMIN_PASSWORD | your-secure-password | Secret | Password for the admin panel |
SESSION_SECRET | long-random-string | Secret | Used to sign cookies (generate a random string) |
API_URL | https://your-worker.workers.dev | Text | (Optional) Required if you use a custom domain or embed on another site |
4. Click **Deploy** to apply changes.
### Step 6: initialize the database
The application will automatically create the necessary database tables (`entries` and `settings`) when you first access it. **No manual SQL execution is required!**
If you prefer to manually initialize the database, you can run the following SQL in the D1 Console:
```sql
CREATE TABLE IF NOT EXISTS entries (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
message TEXT NOT NULL,
site TEXT,
email TEXT,
created_at TEXT NOT NULL DEFAULT (datetime('now')),
approved INTEGER NOT NULL DEFAULT 0
);
CREATE INDEX IF NOT EXISTS idx_approved ON entries(approved);
CREATE INDEX IF NOT EXISTS idx_created_at ON entries(created_at);
CREATE TABLE IF NOT EXISTS settings (
key TEXT PRIMARY KEY,
value TEXT
);
```
### Step 7: custom domain (optional)

Instead of the default `my-guestbook.your-subdomain.workers.dev`, you can use your own domain (e.g., `guestbook.example.com`).
1. Go to your Worker's **Settings** > **Domains & Routes**.
2. Click **Add Custom Domain**.
3. Enter the domain you want to use (it must be a domain active in your Cloudflare account).
**Important for Turnstile:**
If you use a custom domain, you must update your Turnstile widget settings:
* Add your custom domain (e.g., `guestbook.example.com`) to the allowed domains list in the Turnstile dashboard.
* If you plan to **embed** the guestbook on another site (e.g., `myblog.com`), add that domain to the Turnstile allowed list as well.
> See Turnstile configuration in [security settings](#security).
**Recommendation for API_URL:**
If you are using a custom domain, it is highly recommended to add the `API_URL` variable in your Worker settings (e.g., `https://guestbook.example.com`). This ensures that if you visit the worker directly or use the embed code, the client-side scripts will always point to the correct custom domain API.
### Step 8: done!
Visit your Worker's URL (e.g., `https://my-guestbook.your-subdomain.workers.dev`).
- **Guestbook:** The home page is your guestbook.
- **Admin Panel:** Go to `/login` to access the admin dashboard using the password you set.
- **Embed:** Go to `/admin/embed` to get the code snippet for your website.
## Features & configuration
Once logged into the Admin Panel, you can configure the guestbook via the **Settings** tab. These settings are stored in your D1 database.
### General settings
- **Site Name:** The title of your guestbook page and HTML `
` tag.
- **Site Intro:** A welcome message displayed above the form. Supports basic HTML.
- **Site Description:** Used for SEO and social media meta description tags.
- **Site Icon & Cover Image:** Customize the look of your guestbook when shared on social media.
- **Canonical URL:** Important for SEO if you embed the guestbook on another site.
- **Search Engine Indexing:** Control whether search engines should index your guestbook.
### Navigation

You can add custom links to the header (e.g., "Back to Home", "Portfolio") using the Navigation builder in settings.
### Moderation
- **Require Approval:** If enabled, new entries will not appear publicly until you approve them in the Admin Panel. The Worker enables check-mark by default.
- **Admin Actions:** You can Approve or Delete entries from the dashboard.
### Security
MyGB supports **Cloudflare Turnstile** integration out of the box to prevent spam. The Worker enables it by default.
Here is how to set it up:
1. **Get the Keys:**
* Log in to your Cloudflare Dashboard.
* Go to **Turnstile** (available in the Application security sidebar).
* Click **Add Site**.
* **Site Name:** e.g., `My Guestbook`.
* **Domain:** Enter your worker's domain (e.g., `my-guestbook.your-subdomain.workers.dev`). If you use a custom domain, add it as well. Also include the Bear blog or website where the guestbook will be embedded.
* **Widget Mode:** Select **Managed**.
* Click **Create**.
* Copy the **Site Key** and **Secret Key**.
2. **Enable in Guestbook:**
* Log in to your Guestbook Admin Panel.
* Go to **Settings**.
* Scroll to **Security (Cloudflare Turnstile)**.
* Check "Enable Turnstile CAPTCHA".
* Paste your **Site Key** and **Secret Key**.
* Click **Save Settings**.

### Appearance (custom CSS)
You can add custom CSS to style the guestbook to match your vibe.
- Example: Change the background color.
```css
body { background-color: #f0f0f0; }
.card { border-radius: 0px; }
```
### Data export
You can download all your approved entries as **JSON** or **CSV** directly from the Settings page.
## How client-side JavaScript works

The guestbook uses lightweight, vanilla JavaScript to handle interactivity:
1. **Date Formatting:** Timestamps are converted to the visitor's local timezone in their browser.
2. **AJAX Form Submission:** New entries are submitted without reloading the page.
3. **"Load More" Pagination:** Older entries are fetched by clicking "Load More".
4. **Embed Widget:** The embed code loads a small script (`/client.js`) that renders the guestbook inside a container on your external site. You can get the copy-paste ready embed code from your Admin Panel at `/admin/embed`.
### The process (example)

Add MyGB widget to the blog

Add a sample entry and submit

Approve or delete entry in /admin/.

Render the entry in front-end.