DEV Community

Pound Eater
Pound Eater

Posted on

One Governance Recap, Three Formats: Building the Redbelly DAO Monthly Digest published: true tags: web3, dao, react, frontend

Every DAO writes its governance recap once and then rewrites it three times. Once for Discord, once for X, once for a PDF that goes into an archive nobody opens. Redbelly DAO Task Board's TASK-24 asked for a page that ends that pattern: one source, three formats, one page.

Live site: https://redbellydaotask24-one.vercel.app/
Source: https://github.com/poundeater/task24

The brief

The July 2026 governance cycle closed 6 Snapshot votes, reset a High Council election midmonth, and passed a Leadership Structure Amendment that replaces generic roles with 5 appointed positions. That is a lot to recap, and every channel wants it shaped differently. Discord wants full paragraphs. X wants short numbered posts, or for accounts with the long post feature, one flowing piece. Anyone doing due diligence wants a PDF they can cite and a DOCX they can read.

So the page has 4 sections that all describe the same 6 votes:

  • a long-form block with an inline PDF preview and a read-only DOCX link
  • a Discord-ready paragraph block
  • an 8-post X thread, numbered 1/8 through 8/8
  • a single long-form X premium post

Every card has a Copy button and a Download txt button, so whoever is posting the update never has to retype a number.

The design system

The page runs on Redbelly DAO Task Board's Kinetic Consensus tokens. Dark theme, one accent color, no pill buttons, and depth done tonally instead of with drop shadows, a card is a lighter slate than the page with a 1px border a shade lighter than its own fill. Be Vietnam Pro carries every heading and all body copy. JetBrains Mono is reserved for machine-generated values only, vote percentages, proposal identifiers, post-count labels like 1/8, never for prose.

The house copy rule that mattered most while writing this: plain hyphens only, never an em or en dash, and say the number. "6 votes," not "a few votes." It reads oddly plain at first and then it reads exact, which is the point for a governance record.

Two links, two jobs, one 403

The PDF and DOCX come from the same GitHub repo but they cannot use the same CDN, and that took one failed deploy to learn.

jsdelivr (cdn.jsdelivr.net/gh/...) is built for anything meant to render inline, so it powers the Read PDF button and the embedded viewer. It has returned a 403 on a .docx file specifically, so it never touches the DOCX link.

raw.githubusercontent.com serves files with a Content-Disposition header that forces a download, which is exactly wrong for a document someone just wants to skim. So the DOCX button opens read-only in a new tab through Google Docs Viewer, pointed at the raw GitHub URL:

https://docs.google.com/viewer?url=<url-encoded raw.githubusercontent.com link>&embedded=false
Enter fullscreen mode Exit fullscreen mode

No download prompt, no Google account required, and it renders .docx the same way it renders .pdf, .xlsx, and half a dozen other formats, straight from a URL.

Copy and download, no backend

Every text block has a Copy button and a Download txt button, and neither one touches a server.

Copy uses the Clipboard API first, with a hidden textarea plus execCommand('copy') as a fallback for browsers that do not support it, then flips the button label to "Copied" with a checkmark for about 2 seconds before reverting.

Download txt is a Blob and a temporary anchor element:

function downloadTxt(filename, text) {
  const blob = new Blob([text], { type: "text/plain" });
  const url = URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  a.download = filename;
  a.click();
  URL.revokeObjectURL(url);
}
Enter fullscreen mode Exit fullscreen mode

For the X thread, the 8 posts combine into one file, each one preceded by its 1/8 through 8/8 label, so a download gives you the whole thread in the order it should be posted, not 8 separate files to reassemble.

Stack

React, TypeScript, and Vite, fully responsive down to a 16px mobile margin, single column throughout, no navigation, no second page. The DOCX, PDF, and every logo and favicon asset ship straight from the repo's public/ folder.

Where it lives

Top comments (0)