Astro + Tailwind source for the Abstract Machines website and blog.
- Astro (v5)
- Tailwind CSS
src/pages/: Routes (Astro pages).src/components/: Shared UI components.src/layouts/: Page layouts.src/styles/: Global CSS (design tokens + utilities).src/content/blogs/: Blog posts (Markdown).src/content.config.ts: Blog frontmatter schema.public/: Static assets (images, favicons, etc).
npm install
npm run devAstro runs on http://localhost:4321 by default.
npm run build
npm run previewUse the package scripts for Pages Functions workflows:
npm run cf:dev
npm run cf:deploycf:dev: Builds the site and starts local Pages dev server fromdist/usingwrangler.jsonc.cf:deploy: Builds and deploysdist/to theabsmachCloudflare Pages project usingwrangler.jsonc.
Note: wrangler pages deploy does not accept compatibility flags as CLI arguments. Keep them in wrangler.jsonc and in Cloudflare Pages project settings.
wrangler.jsonc (project config):
name: Cloudflare Pages project name (the*.pages.devsubdomain).pages_build_output_dir: deploy output directory (./dist).compatibility_dateandcompatibility_flags(for examplenodejs_compat) for Functions runtime.vars: non-secret defaults for Functions (for contact form, useTEAM_CONTACT_EMAILandMAIL_FROM_EMAIL).
Wrangler automatically reads wrangler.jsonc when commands are run from the project root.
The contact page submits to POST /api/contact via functions/api/contact.js.
The endpoint uses nodemailer over SMTP (Google SMTP supported).
Each successful submission sends:
- one email to your team inbox (
TEAM_CONTACT_EMAIL) - one confirmation copy to the user who submitted the form email
Request payload fields:
nameemailmessage
Required environment variables:
SMTP_HOST: SMTP server host (for Google:smtp.gmail.com).SMTP_PORT: SMTP server port (465for SSL,587for STARTTLS).SMTP_SECURE:truewhen using SSL port (usually465), otherwisefalse.SMTP_USER: SMTP username (for Google: full Gmail/Workspace email).SMTP_PASS: SMTP password (for Google: app password).MAIL_FROM_EMAIL: From address used when sending both emails.TEAM_CONTACT_EMAIL: Team inbox that receives contact requests.
For local smtp4dev testing (Docker -p 2525:25), use:
SMTP_HOST=127.0.0.1
SMTP_PORT=2525
SMTP_SECURE=false
SMTP_USER=
SMTP_PASS=
MAIL_FROM_EMAIL=info@absmach.eu
TEAM_CONTACT_EMAIL=info@absmach.euSMTP_USER and SMTP_PASS are optional for local test servers.
For Cloudflare Pages production:
- Non-secret values are already in
wrangler.jsoncundervars:SMTP_HOST,SMTP_PORT,SMTP_SECURE,MAIL_FROM_EMAIL,TEAM_CONTACT_EMAIL. - Set only SMTP credentials as secrets on the project:
wrangler pages secret put SMTP_USER
wrangler pages secret put SMTP_PASSBackward compatibility: NO_REPLY_EMAIL, CONTACT_FROM_EMAIL, and CONTACT_TO_EMAIL are still accepted, but new projects should use MAIL_FROM_EMAIL and TEAM_CONTACT_EMAIL.
Production does not use .dev.vars.
.dev.varsis local-only forwrangler pages dev.- For production, configure values in Cloudflare Pages: Dashboard -> Pages -> your project -> Settings -> Variables and Secrets -> Production.
- No separate production env file is required in the repo.
For local Cloudflare Pages function testing, copy .dev.vars.example to .dev.vars and fill the values.
nodemailer requires Node compatibility in Cloudflare Workers. Enable nodejs_compat:
- In Cloudflare Pages project settings: Workers runtime compatibility flags.
- Or in local dev:
wrangler pages dev dist --compatibility-flag=nodejs_compat.
See WRITING.md for frontmatter and writing guidelines.
@astrojs/sitemapgeneratesdist/sitemap-index.xml(and chunk files likedist/sitemap-0.xml) duringnpm run build.src/pages/robots.txt.tsis prerendered as/robots.txtand points to/sitemap-index.xml.
src/pages/rss.xml.tsis prerendered as/rss.xml(blog feed).