Files
softvowels-webpage/AGENTS.md
T
2026-06-17 22:37:47 +05:30

4.0 KiB

SoftVowels — project conventions

A monorepo with two apps:

apps/web   Astro 5  (static site, Tailwind v4)
apps/cms   Payload 3 (admin UI + REST/GraphQL)

Package manager

pnpm 9. From the repo root:

pnpm install                  # install both
pnpm dev                      # dev:web
pnpm dev:web                  # Astro only
pnpm dev:cms                  # Payload only
pnpm build                    # build:web
pnpm build:cms                # build Payload
pnpm typecheck                # Astro check
pnpm format                   # prettier
pnpm format:check             # prettier --check

Source paths

  • apps/web/src/components/{layout,home,article,category,search,newsletter,ui}/ — components
  • apps/web/src/layouts/ — page layouts
  • apps/web/src/lib/ — Payload client, types, SEO, formatting
  • apps/web/src/styles/global.css (Tailwind v4 @theme tokens) and prose.css
  • apps/web/public/fonts/ — drop Geist-Variable.woff2 + GeistMono-Variable.woff2 here
  • apps/cms/src/collections/ — Payload collections
  • apps/cms/src/hooks/ — Payload hooks (e.g. revalidateAstro)

Code style

  • All component files are .astro single-file components. Frontmatter (between ---) is TypeScript.
  • No comments in code unless explicitly requested.
  • Tailwind v4 tokens live in CSS (@theme in global.css). Do not create a tailwind.config.* file.
  • Use icon (astro-icon) with names like material-symbols:memory. Self-host icon font woff2 under public/icons/material-symbols-outlined.woff2 and wire it via @font-face in global.css (already declared; add the binary file when ready).
  • Prefer border border-border-subtle rounded-md over arbitrary values to stay on the 4px baseline.
  • For code blocks in MDX / Lexical output, the article body uses prose-article (see prose.css).

Lint / typecheck

pnpm typecheck    # astro check
pnpm format:check

There is no separate ESLint run; the project's quality bar is enforced by astro check and Prettier.

Build outputs

  • apps/web/dist/ is bind-mounted into the web nginx container (./apps/web/dist:/usr/share/nginx/html:ro). The host-side webhook rewrites this folder on demand; the nginx container does not need to be rebuilt.
  • apps/cms/dist/ is built by Payload (Next.js) and runs as the CMS Node process.

Deploy (homeserver)

  1. Copy the repo to /opt/softvowels on the server.
  2. cp .env.example .env and fill in the secrets.
  3. docker compose up -d --build.
  4. In Nginx Proxy Manager add two proxied hosts:
    • softvowels.exampleweb:80 (force SSL, HSTS)
    • cms.softvowels.examplecms:3000 (force SSL, HSTS)
  5. On the host, install the rebuild webhook:
    sudo cp scripts/softvowels-webhook.service /etc/systemd/system/
    sudo systemctl daemon-reload
    sudo systemctl enable --now softvowels-webhook
    
    Make sure REBUILD_TOKEN in /etc/systemd/system/softvowels-webhook.service matches REVALIDATE_TOKEN in .env.

Revalidate flow

  1. Editor publishes in /admin.
  2. Payload afterChange hook POSTs to http://host.docker.internal:4321/__revalidate?secret=…&collection=…&op=….
  3. The host-side Node webhook spawns scripts/rebuild.sh, which git pulls and runs pnpm --filter web build.
  4. nginx container now serves the new apps/web/dist/.

Self-hosting fonts

Drop these two files into apps/web/public/fonts/:

The @font-face rules are already declared in global.css.

Environment

Root .env (used by docker compose):

POSTGRES_PASSWORD=
PAYLOAD_SECRET=
REVALIDATE_TOKEN=
WEB_HOSTNAME=
CMS_HOSTNAME=

apps/web/.env:

PUBLIC_SITE_URL=
PUBLIC_PAYLOAD_API=
PAYLOAD_API_INTERNAL=
REVALIDATE_TOKEN=

apps/cms/.env:

PAYLOAD_SECRET=
DATABASE_URI=
PAYLOAD_PUBLIC_SERVER_URL=
SERVER_URL=
CORS_ORIGINS=
ASTRO_REVALIDATE_URL=
ASTRO_REVALIDATE_TOKEN=