# humanAI — landing page React + Vite static site, served by nginx in the `humanai-landing` Docker container, behind Nginx Proxy Manager on the `nginxproxymanager_default` network. ## Development ```bash npm install npm run dev ``` ## Deploy ```bash ./deploy.sh ``` The script builds images locally, pushes them to piha.local via the `piha` Docker context, and runs smoke tests against the mailer endpoint. ## Mailer The `mailer/` directory contains a standalone Express microservice that handles the contact form. It runs as `humanai-mailer` on the same Docker network as NPM so it can be proxied without exposing any port to the host. ### Manual steps required before first deploy **(a) Create a Fastmail app-password and write credentials to `mailer.env` on the deploy machine:** ``` # mailer.env (never commit this file) SMTP_USER=youruser@fastmail.com SMTP_PASS=your-app-password ``` **(b) In Nginx Proxy Manager → Proxy Host for `gethumanai.pl` → Custom Locations:** | Field | Value | |---|---| | location | `/api` | | scheme | `http` | | forward hostname | `humanai-mailer` | | port | `3000` | ## Known issues **Open Graph metadata is Polish on `/en` routes.** `index.html` is a single static document served for every path (`try_files … /index.html`), so `og:title`, `og:description` and `og:url` are baked in Polish. `App.tsx` rewrites `document.title` and `meta[name="description"]` at runtime, which browsers and JS-executing crawlers honour — but Open Graph scrapers (Facebook, LinkedIn, Slack) read the raw HTML and will show Polish copy when an `/en` link is shared. **`hreflang` alternates are the same on every page.** All routes advertise the same `pl` / `en` / `x-default` triple pointing at the two homepages, so `/privacy` claims the homepage as its alternate. Both have one root cause and one fix: prerender a per-language `index.html` instead of serving one document for every route.