Discorgento is a Brazilian tech community born in the Magento/e-commerce world, now talking about tech in general: PHP, JavaScript, e-commerce and AI. This repository holds the community's home on the web — discorgento.com — where the podcast lives, the episode archive is browsable and the newsletter is announced.
The site's product is in Brazilian Portuguese (with /en and /es editions); everything else here — code, docs, commit messages — is in English.
The site is more than a landing page — every piece below lives in this repo:
- Podcast watch pages — one per episode at
/podcast/<slug>/, rendered from the content catalog: the YouTube player (consent-gated,?t=deep links), a human-written summary, key points and Q&A attributed to who said them, chapters, the full timestamped transcript, and the people involved (hosts fromsrc/lib/team.ts, guests fromsrc/content/guests/) - Episode catalog —
src/content/episodes/<slug>/is the single source of truth per episode:episode.json(YouTube id, duration, localized titles, chapters), notes in three languages (pt-BR.md,en.md,es.md) and a timestampedtranscript.jsonimported from YouTube captions viascripts/import-transcript.mjs - Server islands — the latest YouTube episode, the home episode grid, the
/podcast/list, the latest Substack edition and the live Discord member counts re-render on every request inside the Cloudflare Worker, so new content shows up without a redeploy (each degrades to a committed snapshot if its upstream fails) - AI-friendly on purpose —
robots.txtallows GPTBot, ClaudeBot and friends explicitly, every episode shipsPodcastEpisode/VideoObject/BreadcrumbListJSON-LD, andllms.txt+llms-full.txtare prerendered from the catalog for LLM consumption - Newsletter bridge — a Cloudflare cron Worker (
workers/announcer-cron) checks the Substack feed every 10 minutes and announces new posts in the community's Discord news channel: house-voice message with rotating lines, picked deterministically from the post URL, duplicate-proof through state kept in a Durable Object - Self-hosted media — episode thumbnails are downloaded, resized and re-encoded to AVIF/WebP/JPEG tiers at build time, so the LCP image never leaves our origin
Astro 7 + Tailwind v4, static-first with server islands, deployed as a Cloudflare Worker via GitHub Actions. Three locales: pt-BR (default, no prefix), /en/, /es/ — every route exists in all three, hreflang wired. Strict CSP with hashed inline scripts/styles and opt-in GA4 consent.
See AGENTS.md for the full architecture, commands and gotchas — it is the deep dev doc this README only summarizes.
- CI/CD: every push runs
astro check, Biome lint, unit tests and a production build;maindeploys the build to thediscorgentoWorker anddevelopto thestagingWorker (what passed the gates is exactly what ships) - Substack → Discord: the hourly announcer described above — free on a public repo, zero maintenance, one bot commit per new post
Requires Node >= 22.18.
npm install
npm run dev # foreground dev server on http://localhost:4321| Command | What it does |
|---|---|
npm run dev |
Dev server (foreground; Ctrl+C to stop) |
npm run dev:start / dev:stop |
Dev server in the background (log in .astro/dev.log) |
npm run dev:reset |
Full clean cycle: stop, clear caches, build, start fresh |
npm run build |
Production build to dist/ (safe with the dev server up) |
npm run check |
Type-check the project and templates |
npm run lint / format |
Biome check / check with fixes applied |
npm test |
Unit tests for the pure src/lib code |
src/
content/episodes/<slug>/ # one folder per episode: episode.json + pt-BR/en/es.md + transcript.json
content/guests/ # podcast guests
pages/ # routes per locale (root = pt-BR, en/, es/)
components/ # Home sections, Navbar, Footer, EpisodeArt, CookieConsent, islands
lib/ # feeds (YouTube/Substack/Discord), i18n, episode helpers
layouts/MainLayout.astro # html shell + all SEO
scripts/ # build wrapper, thumbnails, OG image, transcripts, Discord announcer
.github/workflows/ # CI/CD + the Substack → Discord announcer
Issues and pull requests are welcome — the community is the point. For anything beyond a typo, open an issue first so we can talk it through. The gates CI runs are the same ones you should run locally before submitting:
npm run check && npm run lint && npm testPublishing an episode or a page translation follows the catalog conventions in AGENTS.md — start there.