Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/syhily/yufan.me/llms.txt

Use this file to discover all available pages before exploring further.

yufan.me includes a built-in comment system backed by Postgres. Commenters don’t need accounts — they submit a name, email address, and message directly on a post page. Comments appear on post and page detail views and are moderated from the admin console at /admin/comments.

Comment flow for visitors

When a visitor loads a post page, a comment token is issued for that page. The token is stored in Redis with a configurable TTL (default 30 minutes) and is required to submit a comment. This prevents replay and cross-site comment injection. The full submission flow:
  1. Visitor fills in name, email (not displayed publicly), and message in the comment form.
  2. The form submits to /rpc/comments.* (CSRF-protected via the publicProc base procedure).
  3. Rate limiting is enforced per IP and per email address before the comment is written.
  4. If the commenter has no previously approved comments, the new comment is placed in the pending queue for moderation. Subsequent comments from the same email skip the queue once at least one has been approved.
A honeypot field (subtitle) is included in the form markup. Any submission with a non-empty honeypot value is rejected silently — legitimate users never see or fill it. Duplicate detection: within a 7-day window, submitting the same markdown content as a previous comment from the same user is rejected as a duplicate, even if the earlier comment is still pending.

Moderation at /admin/comments

The comments admin page lists all comments with commenter info, the associated post title, submission timestamp, and approval status. Available actions:
  • Approve — marks a pending comment as approved and makes it visible on the public page. An approval notification email is sent to the commenter if outbound mail is configured.
  • Reject / delete — removes the comment permanently.
  • Edit — admins can edit any comment body directly. Own-comment edits within the 30-minute grace period do not require re-approval; edits after the grace period re-queue the comment as pending.
Filters available in the toolbar:
FilterDescription
Statusall, pending, or approved
Post / pageFilter to a specific page by its title (autocomplete search)
AuthorFilter to a specific commenter by name (autocomplete search)

Rate limits

Rate limits are enforced by Redis and apply to comment submissions and post likes. Defaults:
LimitDefault
Comments per IP per hour12
Comments per email per hour8
Likes per IP per hour30
Adjust these in Admin → Settings → Rate Limits.

Post likes

Visitors can like posts without leaving a comment. Like counts are stored alongside the post metrics and displayed on post pages. The per-IP like rate limit (default 30/hour) is configurable in Admin → Settings → Rate Limits.

Comment settings

Open Admin → Settings → Comments to configure the comment system:
SettingDefaultDescription
Comments per page10Number of root-level comments shown per paginated page
Gravatar mirror URLhttps://www.gravatar.com/avatarBase URL used to fetch commenter avatars
Avatar size80Requested avatar size in pixels
Comment token TTL1800How long (in seconds) an issued comment token remains valid
If you’re seeing spam, lower the rate limit caps in Admin → Settings → Rate Limits. The per-email cap is particularly effective against automated spammers because most bots cycle IPs but reuse a small set of addresses.
Gravatar avatars are fetched using an MD5 hash of the commenter’s email address. If you want to use a regional mirror — for example, gravatar.loli.net — update the Gravatar mirror URL field in Admin → Settings → Comments. The avatar renderer in src/server/render/avatar/ caches fetched avatars in Redis to avoid redundant outbound requests.

Build docs developers (and LLMs) love