This repo also serves static marketing pages in-repo (e.g. submit-your-artwork/ — artwork submission form).
physicaladdons.com is the main Netlify project that proxies content from
multiple sub-projects. The visitor and Google always see physicaladdons.com
— the sub-project domains are never exposed.
physicaladdons.com (web-landing repo)
├── /psa/* → proxied from web-psa.netlify.app (Twig/gulp)
├── /pow/* → proxied from web-pow.netlify.app (Twig/gulp)
├── /pco/* → proxied from web-pco.netlify.app (Twig/gulp)
└── /blog/* → proxied from pa-blog.netlify.app (Hugo)
Documentation (MkDocs, lives inside each product repo at root, gulp in src/):
├── /psa/documentation/ → physical-starlight-and-atmosphere-docs (hosted on web-psa.netlify.app)
├── /pow/documentation/ → web-pow
└── /pco/documentation/ → web-pco
All proxy rules are defined in netlify.toml in this repo using status = 200
(reverse proxy, not redirect — the sub-project URL never appears in the browser).
| Repo | Purpose | Stack |
|---|---|---|
web-landing |
Main physicaladdons.com — netlify.toml proxy rules, sitemap, robots.txt only | TOML |
physical-starlight-and-atmosphere-docs |
Physical Atmosphere product page + docs (hosted on web-psa.netlify.app) | Twig/gulp/MkDocs |
web-pow |
Physical Open Waters product page + docs | Twig/gulp/MkDocs |
web-pco |
Physical Celestial Objects product page + docs | Twig/gulp/MkDocs |
pa-blog |
Development blog | Hugo ("paper" theme) |
The root site also includes in-repo static pages (e.g.
submit-your-artwork/) in addition to netlify.toml, sitemap, and this README.
Node dependencies and Gulp config live under src/ (src/package.json, src/gulpfile.js). There is no package.json at the repo root.
One-time (any machine you use to run Gulp from the command line): npm install -g gulp-cli. That installs the gulp command globally; it still uses this repo’s local gulp from node_modules when you are inside src/.
cd src
npm install
gulp # http://localhost:3000 — opens /submit-your-artwork/; reloads on HTML/CSS changes
# same: npm run devThe Netlify artwork form POSTs to /submit-your-artwork/success/; netlify.com handles that in production. gulp/BrowserSync is static-only, so src/gulpfile.js adds a tiny dev-only middleware: POST → 302 redirect to the same path as GET, so the thank-you page loads locally after submit. (Submissions are still only stored on Netlify after deploy.)
If ENOENT: uv_cwd: the shell’s current directory no longer exists (e.g. the folder was deleted). Open a new terminal, cd into the repo, then cd src again.
npm install
cd src
gulp # generates /documentation section + watchesMkDocs config is at repo root (not inside src/).
mkdocs serve # preview docs locally at localhost:8000hugo server # preview at localhost:1313Self-hosted Plausible (stats.upitis.com) is proxied through Netlify to avoid adblockers and cookie banners:
# In netlify.toml
[[redirects]]
from = "/js/script.js"
to = "https://stats.upitis.com/js/script.js"
status = 200
force = true
[[redirects]]
from = "/api/event"
to = "https://stats.upitis.com/api/event"
status = 200
force = trueThe tracking script in each page head:
<script defer data-domain="physicaladdons.com" src="/js/script.js"></script>Hugo blog (pa-blog) has baseURL = "https://physicaladdons.com/blog/" in
config.toml. This causes Hugo to generate canonical tags pointing to
physicaladdons.com on every page, not pa-blog.netlify.app.
Canonical tag is added manually in layouts/head.html:
<link rel="canonical" href="{{ .Permalink }}" />Each sub-project netlify app (pa-blog, web-psa, web-pow, web-pco) should have
a static/robots.txt blocking direct crawling:
# This project is proxied through physicaladdons.com
# Block direct crawling to avoid duplicate content.
# Canonical tags on all pages point to physicaladdons.com
User-agent: *
Disallow: /
TODO: verify web-psa, web-pow, web-pco also have this robots.txt.
Submitted to Google Search Console:
https://www.physicaladdons.com/sitemap.xml— main landing pageshttps://www.physicaladdons.com/blog/sitemap.xml— auto-generated by Hugo